代码之家  ›  专栏  ›  技术社区  ›  Andromeda

位置权限未使用设备打开

  •  0
  • Andromeda  · 技术社区  · 6 年前

    我已经使用FusedLocationProviderClient实现了location。我的应用程序中的问题是,权限对话框没有打开“设置”中的位置。在开始更新之前,我必须手动打开它。

    我已检查并申请使用许可 ContextCompat and ActivityCompat 但是在我手动按下按钮之前什么都不会发生。这是一个错误吗 FusedLocationProviderClient 还是糟糕的编程?我曾与 location manager and Fused Location Provider

    这是我的代码:

    public class HomeFragment extends BaseFragment implements OnMapReadyCallback {
    
    private static final String TAG = HomeFragment.class.getSimpleName();
    
    private Toolbar toolbar;
    private TextView driverStatusTV;
    
    public static MaterialAnimatedSwitch statusSwitch;
    
    private FusedLocationProviderClient providerClient;
    public static Location mLastLocation;
    public static LocationRequest locationRequest;
    public GoogleMap mGmap;
    
    public static Marker currentMarker;
    public static double latitude = 0f, longitude = 0f;
    private static boolean isLocationGranted = false;
    
    public static final int UPDATE_INTERVAL = 15000;
    public static final int FASTEST_INTERVAL = 8000;
    public static final int DISPLACEMENT = 10;
    
    public static final int PLAY_SERVICES_REQ_CODE = 9009;
    public static final int PLAY_SERVICES_RESOLUTION_REQ_CODE = 9090;
    
    private SupportMapFragment mapFragment;
    
    public HomeFragment() {
        // Required empty public constructor
    }
    
    private void initViews(View view) {
        toolbar = view.findViewById(R.id.toolbar);
        driverStatusTV = view.findViewById(R.id.driverStatusTV);
        statusSwitch = view.findViewById(R.id.statusSwitch);
    }
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_home, container, false);
        initViews(view);
        ((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
    
        checkPerms();
        providerClient = LocationServices.getFusedLocationProviderClient(getActivity());
        mapFragment = (SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.mapFragment);
        mapFragment.getMapAsync(this);
    
        driverStatusTV.setText("OFFLINE");
        statusSwitch.setOnCheckedChangeListener(new MaterialAnimatedSwitch.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(boolean b) {
                if (b) {
                    Snackbar.make(getActivity().findViewById(android.R.id.content), "You are Now Online", Snackbar.LENGTH_LONG).show();
                    if (checkPerms()) {
                        startLocationListener();
                        driverStatusTV.setText("ONLINE");
                    }
                } else {
                    Snackbar.make(getActivity().findViewById(android.R.id.content), "You are Now Offline", Snackbar.LENGTH_LONG).show();
                    mGmap.setIndoorEnabled(false);
                    if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                        return;
                    }
                    mGmap.setMyLocationEnabled(false);
                    stopLocationListener();
                    driverStatusTV.setText("OFFLINE");
                    if (currentMarker != null){
                        currentMarker.remove();
                    }
                }
            }
        });
    
        return view;
    }
    
    private void stopLocationListener() {
        if (providerClient != null){
            providerClient.removeLocationUpdates(locationCallback);
        }
    }
    
    @Override
    public void onPause() {
        super.onPause();
        stopLocationListener();
    }
    
    private void startLocationListener() {
        locationRequest = LocationRequest.create();
        locationRequest.setSmallestDisplacement(DISPLACEMENT);
        locationRequest.setFastestInterval(FASTEST_INTERVAL);
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(UPDATE_INTERVAL);
    
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
        builder.addLocationRequest(locationRequest);
    
        LocationSettingsRequest settingsRequest = builder.build();
    
        SettingsClient client = LocationServices.getSettingsClient(getActivity());
        client.checkLocationSettings(settingsRequest);
    
        displayLocation();
    
    }
    
    private boolean checkPerms() {
        if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            reqPerms();
            isLocationGranted = false;
            Log.d(TAG, "Permission Value:\t" + isLocationGranted);
        } else {
            isLocationGranted = true;
            Log.d(TAG, "Permission Value:\t" + isLocationGranted);
        }
        return isLocationGranted;
    }
    
    private void reqPerms() {
        ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, AppConstants.LOC_PERM_CODE);
    }
    
    private void displayLocation() {
        if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            reqPerms();
        } else {
            if (statusSwitch.isChecked()) {
                providerClient.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper());
                mGmap.setIndoorEnabled(true);
                mGmap.setMyLocationEnabled(true);
            } else {
                mGmap.setIndoorEnabled(false);
                mGmap.setMyLocationEnabled(false);
            }
        }
    }
    
    private LocationCallback locationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {
    
            Location location = locationResult.getLastLocation();
            mLastLocation = location;
            if (currentMarker != null) {
                currentMarker.remove();
            }
            latitude = mLastLocation.getLatitude();
            Log.d(TAG, "Lat:\t" + latitude);
            longitude = mLastLocation.getLongitude();
            Log.d(TAG, "Long:\t" + longitude);
    
            MarkerOptions options = new MarkerOptions();
            options.position(new LatLng(latitude, longitude));
            options.title("Driver");
            //options.icon(BitmapDescriptorFactory.fromResource(R.drawable.car)); // throws error
    
            currentMarker = mGmap.addMarker(options);
            rotateMarker(currentMarker, 360, mGmap);
            mGmap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude,longitude), 18.0f));
    
        }
    };
    
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case AppConstants.LOC_PERM_CODE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    isLocationGranted = true;
                    if (checkPlayServices() && statusSwitch.isChecked()) {
                        startLocationListener();
                    } else {
                        Snackbar.make(getActivity().findViewById(android.R.id.content), "Google Play Services Not Supported on Your Device", Snackbar.LENGTH_LONG).show();
                    }
                }
                break;
        }
    }
    
    public boolean checkPlayServices() {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity());
        if (resultCode != ConnectionResult.SUCCESS) {
            if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(), AppConstants.PLAY_SERVICES_RESOLUTION_REQUEST).show();
            } else {
                Snackbar.make(getActivity().findViewById(android.R.id.content), "Play Services NOT Supported on Your Device", Snackbar.LENGTH_LONG).show();
                getActivity().finish();
                getActivity().moveTaskToBack(true);
            }
            return false;
        }
        return true;
    }
    
    private void rotateMarker(final Marker currentMarker, final float i, GoogleMap mGmap) {
        final Handler handler = new Handler();
        final long start = SystemClock.uptimeMillis();
        final float startRotation = currentMarker.getRotation();
        final int duration = 1500;
    
        final Interpolator interpolator = new LinearInterpolator();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                long elapsed = SystemClock.elapsedRealtime() - start;
                float t = interpolator.getInterpolation(elapsed / duration);
                float rot = t * i + (1 - t) * startRotation;
                currentMarker.setRotation(-rot > 180 ? rot / 2 : rot);
    
                if (t < 1.0) {
                    handler.postDelayed(this, 16);
                }
    
            }
        }, duration);
    }
    
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGmap = googleMap;
    
        startLocationListener();
    
    }
    

    }

    Alos,标记器上的set图标会抛出此错误 com.google.maps.api.android.lib6.common.apiexception.b: Failed to decode image. The provided image must be a Bitmap.

    有人能帮我解决这两个问题吗?非常感谢。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Suhaib Roomy    6 年前

    您的onRequestPermissionsResult将永远不会被调用,您正在从您的活动请求权限,并且您的活动的onRequestPermissionsResult将被调用。如果你想在你的片段中调用权限,当你请求权限时只需删除活动即可

    private void reqPerms() {
       requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, AppConstants.LOC_PERM_CODE);
    }
    

    如果要访问此方法,您的片段必须是supportFragment

    推荐文章