javaandroidruntime-permissions

Android RequestMultiplePermissions(): one of the permission's status is never true, even after allowing it


I want to ask for the SEND_SMS and READ_SMS runtime permissions, if they are not given. This is my code:

private ActivityResultLauncher<String[]> mRequestPermissionsLauncher;
String[] PERMISSIONS = {
    Manifest.permission.SEND_SMS,
    Manifest.permission.READ_SMS
};
@Override
protected void onCreate(Bundle savedInstanceState) {

    mRequestPermissionsLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), result -> {
         Log.d("DEBUG",result.toString());
    });

    if (!hasPermissions(this, PERMISSIONS)) {
         if(shouldShowRequestPermissionRationale(Manifest.permission.SEND_SMS) || shouldShowRequestPermissionRationale(Manifest.permission.READ_SMS)){
              new AlertDialog.Builder(this)
                   .setTitle("Permission Needed")
                   .setMessage("Please press OK to allow the permissions")
                   .setCancelable(false)
                   .setPositiveButton("OK", (dialog, which) -> mRequestPermissionsLauncher.launch(PERMISSIONS)).create().show();
         }
         else{
             mRequestPermissionsLauncher.launch(PERMISSIONS);
         }
    }
}
public static boolean hasPermissions(Context context, String... permissions) {
    if (context != null && permissions != null) {
        for (String permission : permissions) {
            if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
         }
    }
    return true;
}

After I allow the permissions and debug the result, it keeps showing:

{android.permission.SEND_SMS=true, android.permission.READ_SMS=false}

Why is my READ_SMS permission false?

EDIT: Never mind, the issue is resolved. I forgot to declare the READ_SMS permission in the manifest file. Silly me :p


Solution

  • You can't and that's by design - to prevent abuse.

    You're better of following the official guidelines.

    The only way to request permissions again, is to navigate the user to app info, where the user has to manually allow it:

    fun launchPermissionSettings(context: Context) {
        Intent().apply {
            action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
            data = Uri.fromParts("package", context.packageName, null)
    
            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
            addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
    
            context.startActivity(this)
        }
    }
    
    static void launchPermissionSettings(Context context) {
        Intent intent = new Intent();
        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.fromParts("package", context.getPackageName(), null));
    
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
    
        context.startActivity(intent);
    }
    

    You're also using a deprecated way of requesting permissions. Consider using ActivityResultContracts.RequestMultiplePermissions():

    class MyFragment: Fragment() {
        private lateinit var mRequestPermissionsLauncher: ActivityResultLauncher<Array<String>>
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            mRequestPermissionsLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result: Map<String, Boolean> ->
                //Handle result here
            }
    
            //Request permissions like this:
            mRequestPermissionsLauncher.launch(arrayOf(
                Manifest.permission.SEND_SMS,
                Manifest.permission.READ_SMS,
            ))
        }
    }
    
    class MyFragment extends Fragment {
        private ActivityResultLauncher<String[]> mRequestPermissionsLauncher;
    
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            mRequestPermissionsLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), result -> {
                //Handle activity result here
            });
    
            //Request permissions like this:
            String[] PERMISSIONS = {
                Manifest.permission.SEND_SMS,
                Manifest.permission.READ_SMS,
            };
            mRequestPermissionsLauncher.launch(PERMISSIONS);
        }
    }