Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android permission granted but still permission denied

I have 3 different activitys on my project. First activity contains all permissions request. App has all permissions granted and still cannot write file on sdcard. If I close app and starting that again then I can write file on sdcard. Is there anyway update permissions for multiple activity.

public class PermissionActivity extends AppCompatActivity {
public static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1;
private static int TIME_OUT = 2000;
private String TAG = "tag";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_permission);

    Locale locale = new Locale("en");
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    config.locale = locale;
    this.getResources().updateConfiguration(config, null);

    if(checkAndRequestPermissions()) {
        // carry on the normal flow, as the case of  permissions  granted.
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                // This method will be executed once the timer is over
                // Start your app main activity

                Intent i = new Intent(PermissionActivity.this, MainActivity.class);
                startActivity(i);

                // close this activity
                finish();
            }
        }, TIME_OUT);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    Log.d(TAG, "Permission callback called-------");
    switch (requestCode) {
        case REQUEST_ID_MULTIPLE_PERMISSIONS: {

            Map<String, Integer> perms = new HashMap<>();
            // Initialize the map with both permissions
            perms.put(android.Manifest.permission.WRITE_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
            perms.put(android.Manifest.permission.WRITE_CALENDAR, PackageManager.PERMISSION_GRANTED);
            perms.put(android.Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
            perms.put(android.Manifest.permission.ACCESS_COARSE_LOCATION, PackageManager.PERMISSION_GRANTED);
            // Fill with actual results from user
            if (grantResults.length > 0) {
                for (int i = 0; i < permissions.length; i++)
                    perms.put(permissions[i], grantResults[i]);
                // Check for both permissions
                if (perms.get(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
                        && perms.get(android.Manifest.permission.WRITE_CALENDAR) == PackageManager.PERMISSION_GRANTED
                        && perms.get(android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                        && perms.get(android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                    Log.d(TAG, "all permission granted");

                    // process the normal flow
                    Intent i = new Intent(PermissionActivity.this, MainActivity.class);
                    startActivity(i);
                    finish();
                    //else any one or both the permissions are not granted
                } else {
                    Log.d(G.mLogTag, "Some permissions are not granted ask again ");
                    if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                            || ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.WRITE_CALENDAR)
                            || ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
                            || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION)) {
                        showDialogOK("Service Permissions are required for this app",
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        switch (which) {
                                            case DialogInterface.BUTTON_POSITIVE:
                                                checkAndRequestPermissions();
                                                break;
                                            case DialogInterface.BUTTON_NEGATIVE:
                                                // proceed with logic by disabling the related features or quit the app.
                                                finish();
                                                break;
                                        }
                                    }
                                });
                    }
                    else {
                        explain("You need to give some mandatory permissions to continue. Do you want to go to app settings?");
                    }
                }
            }
        }
    }
}

private boolean checkAndRequestPermissions(){
    int writeStoragePermission = ContextCompat.checkSelfPermission(PermissionActivity.this,
            android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
    int writeCalenderPermission = ContextCompat.checkSelfPermission(this,
            android.Manifest.permission.WRITE_CALENDAR);
    int fineLocationPermission = ContextCompat.checkSelfPermission(this,
            android.Manifest.permission.ACCESS_FINE_LOCATION);
    int coarseLocationPermission = ContextCompat.checkSelfPermission(this,
            android.Manifest.permission.ACCESS_COARSE_LOCATION);

    List<String> listPermissionsNeeded = new ArrayList<>();
    if (writeStoragePermission != PackageManager.PERMISSION_GRANTED)
        listPermissionsNeeded.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
    if (writeCalenderPermission != PackageManager.PERMISSION_GRANTED)
        listPermissionsNeeded.add(android.Manifest.permission.WRITE_CALENDAR);
    if (fineLocationPermission != PackageManager.PERMISSION_GRANTED)
        listPermissionsNeeded.add(android.Manifest.permission.ACCESS_FINE_LOCATION);
    if (coarseLocationPermission != PackageManager.PERMISSION_GRANTED)
        listPermissionsNeeded.add(android.Manifest.permission.ACCESS_COARSE_LOCATION);
    if (!listPermissionsNeeded.isEmpty()){
        ActivityCompat.requestPermissions(this, listPermissionsNeeded
                        .toArray(new String[listPermissionsNeeded.size()]),
                REQUEST_ID_MULTIPLE_PERMISSIONS);
        return false;
    }
    return true;
}

private void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
    new AlertDialog.Builder(this)
            .setMessage(message)
            .setPositiveButton("OK", okListener)
            .setNegativeButton("Cancel", okListener)
            .create()
            .show();
}
private void explain(String msg){
    final android.support.v7.app.AlertDialog.Builder dialog = new android.support.v7.app.AlertDialog.Builder(this);
    dialog.setMessage(msg)
            .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                    //  permissionsclass.requestPermission(type,code);
                    startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                            Uri.parse("package:fi.maxitors.mydiscgolfapp")));
                }
            })
            .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                    finish();
                }
            });
    dialog.show();
}

}

Above is my permission asking activity. I'm sorry for the bad English.

like image 653
Maxitors Avatar asked Mar 11 '23 05:03

Maxitors


2 Answers

Apps targeting Android 10 (API level 29) and higher are given scoped access into an external storage device, or scoped storage, by default. Such apps can see only their app-specific directory

  1. Temp Fix-

    <manifest ... > <application android:requestLegacyExternalStorage="true" ... > ...

  2. permanent Fix- openFileDescriptor

like image 78
Mohd Danish Avatar answered Mar 16 '23 21:03

Mohd Danish


You need to also add READ_EXTERNAL_STORAGE permission to read data from the device.

I think this has to do with the fact that Android gives automatically read permission when write ones are granted, but probably for his own bug doesn't do it in certain circumstances. In fact from documentation,

Note: If your app uses the WRITE_EXTERNAL_STORAGE permission, then it implicitly has permission to read the external storage as well.

at page https://developer.android.com/training/data-storage/files.html

I had a situation where for testing after having installed the apk on the device, i granted permission with the command

adb shell pm grant com.blippar.ar.android.debug android.permission.WRITE_EXTERNAL_STORAGE

that triggered the behaviour you observed. Instead giving both the previous and the

adb shell pm grant com.blippar.ar.android.debug android.permission.READ_EXTERNAL_STORAGE

solved the issue.

like image 21
AndrewBloom Avatar answered Mar 16 '23 21:03

AndrewBloom