I'm working on an android project that requires location permission. i followed the documentations and everything works fine for the permission itself. But my app heavily depend on that permission so nothing will work if not granted. anyway my problem is that i have a function that requests the permission as follows (knowing that the function hasPermission()
just checks if permission granted before or not):
public void requestPermission() {
if(!hasPermission()){
ActivityCompat.requestPermissions(MainActivity.this, new String[] {ACCESS_FINE_LOCATION}, REQUEST_CODE);
Toast.makeText(this, "Here", Toast.LENGTH_SHORT).show();
}
}
I handled my onRequestPermissionsResult
as follows :
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Location Permission Granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Location Permission Denied", Toast.LENGTH_SHORT).show();
}
}
}
and my onCreate()
is :
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestPermission();
Toast.makeText(this, "In main", Toast.LENGTH_SHORT).show();
}
How can I make the Toast in my onCreate()
method wait until the user finishes from choosing from the permission dialog box, because if I directly try to use my hasPermission()
function it will check even before the user chooses?
------------------------Edit----------------------------------
the onRequestPermissionsResult
is deprecated so i used this :
private ActivityResultLauncher<String> permission = registerForActivityResult(new ActivityResultContracts.RequestPermission(), result -> {
if(result){
Toast.makeText(this, "Granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Denied", Toast.LENGTH_SHORT).show();
}
});
and my onCreate()
:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
permission.launch(Manifest.permission.ACCESS_FINE_LOCATION);
Toast.makeText(this, "In main", Toast.LENGTH_SHORT).show();
}
and still the toast after permission.launch()
ran before completing the permission dialog box.
CodePudding user response:
how can i make the Toast in my onCreate() method wait until the user finish from choosing from the permission dialog box
This is normal because requesting the permission takes some time to check if the system already granted this permission to my app or not. And this is done asynchronously; so the onCreate()
will go ahead and continue executing by showing the Toast and returning.
Generally speaking, you shouldn't seize the main thread in Android to avoid Application Not Responding (ANR); so, pausing the onCreate()
until it checks there is a granted permission or not will cause ANR.
until the user finish from choosing
How could we know that the user will immediately choose an option or waits one hour later on?
So, the right way to do this is in the ActivityResultLauncher
callback which waits for the user reaction asynchronously:
private ActivityResultLauncher<String> permission = registerForActivityResult(new ActivityResultContracts.RequestPermission(), result -> {
if(result){
Toast.makeText(this, "Granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Denied", Toast.LENGTH_SHORT).show();
}
// The permission dialog gone; show the Toast
Toast.makeText(this, "In main", Toast.LENGTH_SHORT).show();
});
Or probably you can fire another listener callback or update a LiveData
object. But all this will also go in the ActivityResultLauncher
callback.