簡體   English   中英

FusedLocationProvider 總是返回 null 位置 object

[英]FusedLocationProvider always returns null Location object

我已經嘗試過無數次 FusedLocationProviderClient 的實現,我在互聯網上找到並使用文檔,但每次我都無法獲得位置和 null object。 這是我在主要活動中使用 FusedLocationProviderClient 獲取位置的最終代碼。 然后我在另一個片段中使用 Location object 來顯示用戶的坐標。

這是活動代碼

    ActivityMainBinding activityMainBinding;
    NavHostFragment navHostFragment;
    NavController navController;
    LocationRequest mLocationRequest;
    Location mLocation;
    FusedLocationProviderClient mFusedLocationClient;

    @SuppressLint("NewApi")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        startLocation();

        activityMainBinding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(activityMainBinding.getRoot());
        navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragmentContainerMain);
        navController = navHostFragment.getNavController();

        activityMainBinding.bottomNavigation.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                switch(item.getItemId()) {
                    case R.id.menuItemHome:
                        navController.navigate(R.id.homeFragment);
                        break;
                    case R.id.menuItemSearch:
                        navController.navigate(R.id.searchFragment);
                        break;
                    case R.id.menuItemProfile:
                        navController.navigate(R.id.profileFragment);
                        break;
                    case R.id.menuItemSettings:
                        navController.navigate(R.id.settingsFragment);
                        break;
                }
                return true;
            }
        });
    }

    @Override
    public void onBackPressed() {
        navController.navigate(R.id.homeFragment);
        activityMainBinding.bottomNavigation.setSelectedItemId(R.id.menuItemHome);
    }

    public void startLocation() {

        mLocationRequest = LocationRequest.create();
        mLocationRequest.setInterval(10000);
        mLocationRequest.setFastestInterval(1000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        if (    (ContextCompat.checkSelfPermission( this,
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED )
                || ( ContextCompat.checkSelfPermission( this,
                Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) ) {
            //Location Permission granted
            mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
            LocationServices.getFusedLocationProviderClient(this).getLastLocation().addOnSuccessListener(new OnSuccessListener<Location>() {
                @Override
                public void onSuccess(@NonNull Location location) {
                    mLocation = location;
                }
            });
        } else {
            //Request Location Permission
            checkLocationPermission();
        }
    }

    public void stopLocationUpdates() {
        if( mFusedLocationClient != null )
            mFusedLocationClient.removeLocationUpdates(mLocationCallback);
    }

    public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
    private void checkLocationPermission() {
        if (    (ContextCompat.checkSelfPermission( this,
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED )
                || ( ContextCompat.checkSelfPermission( this,
                Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) ) {

            if (    ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION)
                    || ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION) ) {

                //Request location message for user
                new AlertDialog.Builder(this)
                        .setTitle("Location Permission Needed")
                        .setMessage("This app needs the Location permission, please accept to use location functionality")
                        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                //Prompt the user once explanation has been shown
                                ActivityCompat.requestPermissions(MainActivity.this,
                                        new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                                        MY_PERMISSIONS_REQUEST_LOCATION );
                            }
                        })
                        .create()
                        .show();
            } else {
                //request the permission.
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                        MY_PERMISSIONS_REQUEST_LOCATION );
            }
        }
    }

    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == MY_PERMISSIONS_REQUEST_LOCATION) {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted
                if (ContextCompat.checkSelfPermission(this,
                        Manifest.permission.ACCESS_COARSE_LOCATION)
                        == PackageManager.PERMISSION_GRANTED) {
                    mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
                }
            }
        }
    }

    LocationCallback mLocationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {
            if (locationResult == null) {
                return;
            }
            for (Location location : locationResult.getLocations()) {
                if (location != null) {
                    mLocation = location;
                    return;
                }
            }
        }
    };
}

這是片段 class 中的代碼,我想在其中顯示坐標

public class HomeFragment extends Fragment {
    private HomeFragmentBinding homeFragmentBinding;
    private NavController navController;
    private MainViewModel mainViewModel;
    private Location userLocation;
    private MainActivity mainActivity;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mainViewModel = new ViewModelProvider(getActivity()).get(MainViewModel.class);
        mainActivity = (MainActivity) getActivity();
        userLocation = mainActivity.mLocation;

        homeFragmentBinding.textDist1.setText("Lat: " + userLocation.getLatitude() + " Long: " + userLocation.getLongitude());
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        homeFragmentBinding = HomeFragmentBinding.inflate(inflater, container, false);
        return homeFragmentBinding.getRoot();
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        navController = Navigation.findNavController(view);

        homeFragmentBinding.textDist1.setText("Lat: " + userLocation.getLatitude() + " Long: " + userLocation.getLongitude());

    }

我還在清單中添加了 ACCESS_FINE_LOCATION 和 ACCESS_COARSE_LOCATION 的權限,

在 gradle 構建中implementation 'com.google.android.gms:play-services-location:19.0.0'

每次運行應用程序時,我都會收到 null 位置 object 的 null 指針異常。 用戶也沒有獲得提供位置訪問權限的彈出窗口。 我從我的 android 虛擬設備的設置中手動打開了位置訪問,但沒有任何改變。 在 android 文檔和舊的 StackOverflow 頁面上數小時后,我找不到問題。 謝謝你的幫助。

首先,創建一個 Fused Location Provider Client 的實例。

mFusedLocationClient= LocationServices.getFusedLocationProviderClient(this)

然后進行位置請求。

mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());

我想官方文檔很清楚。 參考 - https://developer.android.com/training/location/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM