获取纬度和经度?

3

我正在尝试在RecyclerView中的按钮点击时获取位置。

但是当我点击按钮时,应用程序会崩溃并给出以下错误:

Logcat:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.location.Location android.location.LocationManager.getLastKnownLocation(java.lang.String)' on a null object reference

RecyclerView适配器代码:

public class RecieverAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
Context context;
List<BloodData> data = Collections.emptyList();
List<BloodData> searchData;
LayoutInflater inflater;
RecieverAdapter RAdapter;
LocationManager locationManager;
public RecieverAdapter(RecieveBlood recieveBlood, List<BloodData> data) {
    this.context = recieveBlood;
    inflater = LayoutInflater.from( context );
    this.data = data;
    this.RAdapter = this;
    searchData = new ArrayList<>( data );
}

@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
    View view = inflater.inflate( R.layout.blood_list, viewGroup, false );
    MyHolder holder = new MyHolder(view);
    return holder;
}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
    MyHolder myHolder = (MyHolder) viewHolder;
    BloodData current = data.get( i );
    myHolder.Sr_Num.setText( " "+i );
    myHolder.Donar_Name.setText( "Name : "+current.getD_Name() );
    myHolder.Donar_Blood_Group.setText( "Blood Group : " +current.getD_blood_group());
    myHolder.Donar_Mobile.setText( "Mobile : "+current.getD_Number());
    myHolder.Donar_Gender.setText( "Gender : "+current.getD_Gender());

    myHolder.location1.setOnClickListener( new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            getLocation();
        }
    } );

}

void getLocation() {
    if (ContextCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

        ActivityCompat.requestPermissions( (Activity) context, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}, 101);

    }else{
        Location location = locationManager.getLastKnownLocation( LocationManager.NETWORK_PROVIDER );

        if(location != null){
            double lati = location.getLatitude();
            double longi = location.getLongitude();

            Log.e(TAG,"Location :" +lati+ " ,"+longi );
        }
    }
}



@Override
public int getItemCount() {
    return data.size();
}
 private class MyHolder extends  RecyclerView.ViewHolder{
    TextView Sr_Num,Donar_Name,Donar_Blood_Group,Donar_Mobile,Donar_Gender;
    Button location1, location2;
    public MyHolder(@NonNull View itemView) {
        super( itemView );

        Sr_Num = (TextView) itemView.findViewById( R.id.sr_number );
        Donar_Name = (TextView) itemView.findViewById( R.id.Donar_Name );
        Donar_Blood_Group  =(TextView) itemView.findViewById( R.id.Donar_blood_Group);
        Donar_Mobile = (TextView) itemView.findViewById( R.id.Donar_Number );
        Donar_Gender = (TextView) itemView.findViewById( R.id.Donar_Gender );
        location1 = (Button) itemView.findViewById( R.id.Location1 );
        location2 = (Button) itemView.findViewById( R.id.location2 );


    }
}
}

我设置了所有位置所需的权限。

Android MainFest文件:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="nikhil.bloodbank.bloodsupplies">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

所以每当我点击按钮时,应用程序就会崩溃并显示该错误。我还手动检查了是否已授予权限。

它可以帮助:https://dev59.com/I-k6XIcBkEYKwwoYEf8H - Ali Khaki
1个回答

2
您尚未初始化位置管理器实例。请将适配器的构造函数更改如下:
public RecieverAdapter(RecieveBlood recieveBlood, List<BloodData> data) {
    this.context = recieveBlood;
    inflater = LayoutInflater.from( context );
    this.data = data;
    this.RAdapter = this;
    searchData = new ArrayList<>( data );

    //Initialize Location manager
    locationManager = (LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE);
}

请注意,使用getLastKnownLocation()可能会返回旧的和过时的位置,如Android文档所述:
返回一个位置,指示从给定提供程序获得的上次已知位置修复数据。
这可以在不启动提供程序的情况下完成。请注意,此位置可能已过时,例如,如果设备关闭并移动到另一个位置。
如果提供程序当前已禁用,则返回null。
在下面的链接中有关于获取位置的多种方法的详细说明:https://developer.android.com/guide/topics/location/strategies 更新:
我已添加了以下locationListener逻辑,但最佳实践是将您的位置获取代码放置在活动或片段中,记住在关闭活动或片段时应该删除locationListener。使用locationManager.removeUpdates(locationListener)以删除locationListener。
void getLocation() {
    if (ContextCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions( (Activity) context, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}, 101);
    }else{
        Location location = locationManager.getLastKnownLocation( LocationManager.NETWORK_PROVIDER );
        if(location != null){
            double lati = location.getLatitude();
            double longi = location.getLongitude();
            Log.e(TAG,"Location :" +lati+ " ,"+longi );
        } else {
            boolean isNetworkAvailable = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
            if(isNetworkAvailable) fetchCurrentLocation()
            else //Redirect user to device settings in order to turn on location service
        }
    }
}

您应该按照以下方式实现locationListener:
fetchCurrentLocation() {
        try {
                LocationListener locationListener = new LocationListener() {
                    @Override
                    public void onLocationChanged(final Location location) {
                        if (location != null) {
                            locationManager.removeUpdates(this);
                            double lati = location.getLatitude();
                            double longi = location.getLongitude();
                            Log.e(TAG,"Location :" +lati+ " ,"+longi );
                        }
                    }

                    @Override
                    public void onProviderDisabled(String s) {
                        locationManager.removeUpdates(this);
                    }

                    @Override
                    public void onStatusChanged(String s, int i, Bundle bundle) {
                    }

                    @Override
                    public void onProviderEnabled(String s) {
                    }
                };

    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 500L,30f, locationListener);
            } catch (SecurityException e) {
                e.printStackTrace();
            }
}

我已经初始化了它,但仍然无法工作。应用程序没有崩溃,但我无法获取经度和纬度。 - nikhil lohar
正如我所提到的,getLastKnownLocation() 可能不会返回任何位置,这是因为之前没有获取过位置。您可以设置一个位置监听器,在 getLastKnownLocation() 返回无位置时获取当前实时位置,按照此链接中所述进行操作:https://dev59.com/-Oo6XIcBkEYKwwoYNBZQ#17591377 - Mostafa Arian Nejad
你能根据那个做出修改吗?因为我还是不太明白。这将会是非常有帮助的。 - nikhil lohar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接