通过构造函数传递数组适配器 |列表显示

Posted

技术标签:

【中文标题】通过构造函数传递数组适配器 |列表显示【英文标题】:Passing Array Adapter via Constructor | ListView 【发布时间】:2020-12-03 05:30:20 【问题描述】:

我正在尝试使用从我的LocationsFragment.class 到我的DeviceAdmin.class 的适配器来添加两个字符串,比如mylatitudemylongitude 到我的ListView。 我正在通过构造方法。 但它似乎返回 null,每当我在我的 DeviceAdmin.class 中调用 adapter.add(mylatitude + " " + mylongitude);

  java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ArrayAdapter.add(java.lang.Object)' on a null object reference
        at com.ayush.trixter.ui.captures.DeviceAdmin$1.onLocationChanged(DeviceAdmin.java:103)

第 103 行是:adapter.add("Latitude: " + mylat + "Longitude: " + mylon);

DeviceAdmin.class


import android.Manifest;
import android.annotation.SuppressLint;
import android.app.admin.DeviceAdminReceiver;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Paint;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Looper;
import android.os.UserHandle;
import android.util.Log;
import android.util.SparseIntArray;
import android.view.ContextThemeWrapper;
import android.view.Surface;
import android.view.View;
import android.widget.Adapter;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.content.PermissionChecker;

import com.ayush.trixter.R;
import com.ayush.trixter.ui.locations.LocationFragment;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.material.snackbar.Snackbar;
import com.google.firebase.database.FirebaseDatabase;

import java.util.ArrayList;

public class DeviceAdmin extends DeviceAdminReceiver

    private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
    public CameraManager cam;
    LocationManager locationManager;
    final String TAG = "[Trixter]";
    DevicePolicyManager mgr;
    FirebaseDatabase db;
    public boolean mTracking = false;
    public ArrayList<String> listItems=new ArrayList<>();
    LocationFragment lf = new LocationFragment();
    ArrayAdapter<String> adapter = lf.adapter;



    @Override
    public void onPasswordFailed(@NonNull Context ctx, @NonNull Intent intent, @NonNull UserHandle user) 
        super.onPasswordFailed(ctx, intent, user);
        cam = (CameraManager) ctx.getSystemService(Context.CAMERA_SERVICE);
        mgr = (DevicePolicyManager) ctx.getSystemService(Context.DEVICE_POLICY_SERVICE);

        Log.d(TAG,"PasswordFailed");
        int pwdfailcount = mgr.getCurrentFailedPasswordAttempts();

        if(pwdfailcount==3)
        
            takeSnapShots();
            getloc(ctx);

        
    

    public void getloc(Context ctx)
    
        locationManager = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);
        Criteria criteria = new Criteria();
        String provider =  locationManager.getBestProvider(criteria,true);
        boolean gps_enabled = false;
        boolean network_enabled = false;

        try
         gps_enabled =   locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); 
        catch (Exception e) 
        try  network_enabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); catch (Exception e) 

        if(PermissionChecker.checkSelfPermission(ctx, Manifest.permission.ACCESS_COARSE_LOCATION) == PermissionChecker.PERMISSION_GRANTED && PermissionChecker.checkSelfPermission(ctx,Manifest.permission.ACCESS_FINE_LOCATION) == PermissionChecker.PERMISSION_GRANTED) 
            if(gps_enabled == true && network_enabled ==true) 
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, new LocationListener() 
                    @Override
                    public void onLocationChanged(@NonNull Location loc) 
                        double mylat = loc.getLatitude();
                        double mylon = loc.getLongitude();
                        double myacc = loc.getAccuracy();
                        double time = loc.getTime();
                        double myalt = loc.getAltitude();
                        Log.d("[TrixterLocation]", "The Latitude:- " + mylat + "\nThe Longitude:- " + mylon + "\nThe Altitude:- " + myalt + "\n The Accuracy" + myacc + "\nThe Time:- " + time);
                        adapter.add("Latitude: " + mylat + "Longitude: " + mylon);
                    
                );
            
            else
            
                Toast.makeText(ctx, "Location is not enabled", Toast.LENGTH_SHORT).show();
                Log.d("[Trixter] ","Error: Location or Internet Not Enabled");
            
        

    



    private void takeSnapShots()
    

    






LocationsFragment.class

package com.ayush.trixter.ui.locations;

import android.content.Context;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.ListFragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;

import com.ayush.trixter.R;
import com.ayush.trixter.ui.captures.DeviceAdmin;

import java.util.ArrayList;

public class LocationFragment extends ListFragment 

    ListView loclst;
    LocationManager locationManager;
    public ArrayList<String> listItems=new ArrayList<>();
    public ArrayAdapter<String> adapter = (ArrayAdapter<String>) getListAdapter();

    public LocationFragment()
    

    
    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) 
        View root = inflater.inflate(R.layout.fragment_locations, container, false);
            loclst = root.findViewById(android.R.id.list);
            Context context = getActivity();
            locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
            adapter = new ArrayAdapter<String>(getActivity(),   android.R.layout.simple_list_item_2 , listItems);
            loclst.setAdapter(adapter);

          return root;
    


据我所知:- 它将返回 null,因为 ArrayAdapter 未初始化,仅在 Fragment 打开时才被初始化,即 onCreateView()

但我无法找到使其工作的解决方案。 另外,如果有人有更好的想法更容易地做到这一点,请告诉。

【问题讨论】:

【参考方案1】:

它不起作用,因为您正在 DeviceAdmin 类上创建一个新的 LocationFramgent。

您需要做的是访问实际的 LocationFragment。

要正确回答你,我需要知道:

片段是从哪里创建的?

你在哪里调用 getLoc 方法?

【讨论】:

片段是从哪里创建的?答案:- from home.class 不是主要活动。这是代码home.class 你在哪里调用 getLoc 方法?答:如果密码失败计数等于 3,则在 DeviceAdmin 类的 onPasswordFailed 上调用。 [点我获取代码方法] (hastebin.com/rihebomijo.java) 我看到您正在使用导航控制器。为了解决这个问题,无论您在哪里创建 DeviceAdmin 实例,还要将引用传递给 navcontroller,这样您就可以获取实际位置片段并在实际位置片段的适配器中调用 add 函数。 感谢您的回答。我要求您提供一个例子,请更具体一些。我对应用程序开发很陌生。

以上是关于通过构造函数传递数组适配器 |列表显示的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 列表适配器构造函数错误

无法从构造函数中将数组值传递给向量

笔记十:复制构造函数深拷贝浅拷贝

通过构造函数请求数组初始化子类

如何从通过按钮单击呈现的部分视图将recordId传递给模型构造函数

虚函数总结