Search code examples
javaandroidgpslocation

onRequestPermissionsResult is deprecated in Android Fragment


This is my current (deprecated) method:

int LOCATION_REQUEST_CODE = 10001;     
@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        if (requestCode == LOCATION_REQUEST_CODE) {
            //Permission granted
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                checkSettingsAndStartLocationUpdates();
            } else {
                //DO SOMETHING - Permission not granted
            }
        }
    }

According to the android documentation https://developer.android.com/training/basics/intents/result I should use registerForActivityResult():

// GetContent creates an ActivityResultLauncher<String> to allow you to pass
// in the mime type you'd like to allow the user to select
ActivityResultLauncher<String> mGetContent = registerForActivityResult(new GetContent(),
    new ActivityResultCallback<Uri>() {
        @Override
        public void onActivityResult(Uri uri) {
            // Handle the returned Uri
        }
});

However I am struggling with replacing my method. Where do I insert my requestcode and my int array in the new method "registerForActivityResult()" ? Why do I need a "Uri" ?


Solution

  • Where do I insert my requestcode and my int array in the new method "registerForActivityResult()" ?

    You do not have any requestCode. In this design, you can think one single callback for each of the requestCode you have used previously. For handling single permission, you can use the built-in ActivityResultContracts.RequestPermission:

    // Register the permissions callback, which handles the user's response to the
    // system permissions dialog. Save the return value, an instance of
    // ActivityResultLauncher, as an instance variable.
    private ActivityResultLauncher<String> requestPermissionLauncher = registerForActivityResult(new RequestPermission(), isGranted -> {
        if (isGranted) {
            // Permission is granted. Continue the action or workflow in your
            // app.
        } else {
            // Explain to the user that the feature is unavailable because the
            // features requires a permission that the user has denied. At the
            // same time, respect the user's decision. Don't link to system
            // settings in an effort to convince the user to change their
            // decision.
        }
    });
    

    Why do I need a "Uri" ?

    You may get it wrong. In this way, you need an ActivityResultContract<Input, Output> which connects the two Activities. Previously you can only pass Intent to the starting Activity. Now you can pass any type of object using this contract. Input is the type of object you want to pass, Output is the type of result object back from the new Activity. There are some built-in contracts to handle regular scenerio, one of which is GetContent(). If you want a startActivityForResult(intent) like thing, just use ActivityResultContracts.StartActivityForResult, and registering it will return an ActivityResultLauncher, within that intent, you can pass your array with that intent.

    // Similar to how you pass your array with intnt before
    Intent i = new Intent(MainActivity.this, NewActivity.class);
    i.putExtra ("key_arr", arr); // arr is your int array
    resultLauncher.launch(i);