The description of androidx.activity.result.contract.ActivityResultContract$SynchronousResult said: "An optional method you can implement that can be used to potentially provide a result in lieu of starting an activity.
"
Let's assume that I want to request for permissions.Generally I have to declare an ActivityResultLauncher by registerForActivityResult(contract, callback), write working logic inside the callback, and launch it in the correct time.
And to the best of my knowledge, with SynchronousResult(), I don't have to register the ActivityResultLauncher. I just need to declare an ActivityResultContract, and calling contract.SynchronousResult() will block untill the result return, i.e., user has made a desicion on the granting of permissions. So I write my code like this:
private boolean requestSDCardPermission(){
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityResultContracts.RequestMultiplePermissions contract = new ActivityResultContracts.RequestMultiplePermissions();
Map<String, Boolean> synchronousResult=contract.getSynchronousResult(LBL_CloudDisk_MainActivity.this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}).getValue();
return synchronousResult.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) && synchronousResult.get(Manifest.permission.READ_EXTERNAL_STORAGE);
}
return true;
}
But when this code executes, a NullPointerException occurs because getValue() point to a null object, which in my opinion means SynchronousResult() didn't block and wait for the result. So how should I properly use this method?
As per that exact set of documentation:
Returns:
SynchronousResult<O>
: the result wrapped in aActivityResultContract.SynchronousResult
ornull
if the call should proceed to start an activity.
So it is expected that getSynchronousResult()
will return null
if you need to call launch()
in order to get a valid result back. When it comes to RequestMultiplePermissions
, the source code indicates that synchronous results are only returned if all permissions are already granted.
In general, none of the ActivityResultContract
APIs are meant to be called directly by your app - they are all called as part of the ActivityResultRegistry
and the regular launch
that you should be interfacing with. Those automatically do the right thing and will internally call APIs like getSynchronousResult()
in order to avoid launching an activity if that isn't needed. You should still be handling the results as part of the callback.