Android: проверка проблем с разрешениями во время выполнения - PullRequest
0 голосов
/ 24 апреля 2020

Я хочу проверить разрешения ACCESS_FINE_LOCATION и ACCESS_BACKGROUND_LOCATION в начале метода onCreate () действия. После этой проверки я инициализирую некоторые кнопки, MapView и некоторые TextView.

if(checkMapServices()){    
            if(mLocationPermissionGranted){
                Toast.makeText(RunningActivity.this,"Check on Start", Toast.LENGTH_LONG).show();
            } else {
                getLocationPermission();
            }
        } 

checkMapServices () определяется следующим образом:

private boolean checkMapServices(){
        if(isServicesOK()){
            if(isGPSEnabled()){
                return true;
            }
        }
        return false;
    }

isServicesOK () просто проверьте, установлены ли на телефоне службы Google Play. isGPSEnabled () проверяет состояние GPS, но оно не включено, возвращает false и вызывает buildAlertMessageNoGps () , чтобы дать пользователю возможность включить Местоположение:

private void buildAlertMessageNoGps() {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("This application requires GPS to work properly, do you want to enable it?")
                .setCancelable(false)
                .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
                        Intent enableGpsIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        startActivityForResult(enableGpsIntent, PERMISSIONS_REQUEST_ENABLE_GPS);                                
                    }
                })
                .setNegativeButton("No", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent = new Intent(RunningActivity.this,DashboardActivity.class);
                        startActivity(intent);
                        finish();
                    }
                });
        final AlertDialog alert = builder.create();
        alert.show();
    }

И в следующем фрагменте я просто проверяю оба разрешения.

private void getLocationPermission() {
        if (ContextCompat.checkSelfPermission(this.getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED |
                ContextCompat.checkSelfPermission(this.getApplicationContext(), android.Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            Log.i(TAG, "getLocationPermission: Permission granted");
            mLocationPermissionGranted = true;
            Toast.makeText(RunningActivity.this, "The LocationPermission is granted", Toast.LENGTH_LONG).show();
            if (mMap != null) {
                mMap.setMyLocationEnabled(true);
            }
        } else {
            Log.i(TAG, "getLocationPermission: Permission is not granted");
            if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {        // After the first "Deny", Show a Snackbar
                Log.i(TAG, "getLocationPermission: Showing Rationale");
                Snackbar.make(findViewById(android.R.id.content), "Need permission for loading data", Snackbar.LENGTH_INDEFINITE).setAction("Enable",
                        new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        ActivityCompat.requestPermissions(RunningActivity.this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_BACKGROUND_LOCATION}, PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
                    }
                }).show();
            } else {
                Log.i(TAG, "getLocationPermission: Permission is not granted, no Rationale showing");
                ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_BACKGROUND_LOCATION}, PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
        mLocationPermissionGranted = false;
        switch (requestCode) {
            case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    //Additional if-check for the Background Permission
                    if(ContextCompat.checkSelfPermission(RunningActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION)==PackageManager.PERMISSION_GRANTED){
                        if(ContextCompat.checkSelfPermission(RunningActivity.this, android.Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED){
                            mLocationPermissionGranted = true;
                        }
                    }
                } else { // Permission is not granted
                    //Now further we check if used denied permanently or not
                    if (ActivityCompat.shouldShowRequestPermissionRationale(RunningActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION)) {
                        // User has denied permission but not permanently
                        getLocationPermission();
                    } else {
                        // Permission denied permanently.
                        // You can open Permission setting's page from here now.
                        redirectToSettingsForLocation();
                    }
                }
            }
            break;
        }
    }

    //Checking the GPS Alert Box and the response from it
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.d(TAG, "onActivityResult: called.");
        switch (requestCode) {
            case PERMISSIONS_REQUEST_ENABLE_GPS:
                if(isGPSEnabled()){
                    if(mLocationPermissionGranted){
                        //We can show the content
                    }
                    else{
                        getLocationPermission();
                    }
                }
                break;
            case PERMISSION_AFTER_PERMAMENT_DENY:
                    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED |
                            ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                        mLocationPermissionGranted = true;
                    } else {
                        Toast.makeText(RunningActivity.this, "Sorry, but you haven't enabled the permission", Toast.LENGTH_LONG).show();
                        redirectToSettingsForLocation();
                    }
                break;
        }
    }

Программа возвращает следующую ошибку:

V/FA: onActivityCreated
V/FA: Activity paused, time: 2809594
I/zzbz: Making Creator dynamically
I/DynamiteModule: Considering local module com.google.android.gms.maps_dynamite:0 and remote module com.google.android.gms.maps_dynamite:221
    Selected remote version of com.google.android.gms.maps_dynamite, version >= 221
V/DynamiteModule: Dynamite loader version >= 2, using loadModule2NoCrashUtils
W/System: ClassLoader referenced unknown path: /data/data/com.google.android.gms/app_chimera/m/00000006/n/x86
I/Google Maps Android API: Google Play services client version: 12451000
I/Google Maps Android API: Google Play services package version: 16089022
E/AndroidRuntime: FATAL EXCEPTION: androidmapsapi-ZoomTableManager
    Process: com.pantherrun.pantherrunapp, PID: 4051
    java.lang.ArrayIndexOutOfBoundsException: length=1; index=12
        at com.google.maps.api.android.lib6.gmm6.vector.dg.<init>(:com.google.android.gms.dynamite_mapsdynamite@16089052@16.0.89 (040700-239467275):21)
        at com.google.maps.api.android.lib6.gmm6.vector.dh.a(:com.google.android.gms.dynamite_mapsdynamite@16089052@16.0.89 (040700-239467275):11)
        at com.google.maps.api.android.lib6.gmm6.util.n.run(:com.google.android.gms.dynamite_mapsdynamite@16089052@16.0.89 (040700-239467275):27)
        at java.lang.Thread.run(Thread.java:818)
D/RunningActivity: isServicesOK: checking google services version
D/RunningActivity: isServicesOK: Google Play Services is working

Это говорит о ArrayIndexOutOfBoundException, но единственный массив, который я использую, это тот, который запрашивает разрешения. Я думаю, что это правильный способ, как называются разрешения, но в чем может быть проблема?

...