Android – onRequestPermissionsResult() ist veraltet. Gibt es Alternativen?

Lesezeit: 8 Minuten

Benutzer-Avatar
Asche

Ich habe versucht, Anforderungsberechtigungen zum Schreiben und Lesen aus dem Speicher zu implementieren. Alles hat gut funktioniert, aber heute hat mir Android gezeigt, dass die Methode onRequestPermissionsResult(…) veraltet ist. Es gibt so viele Fragen zu diesem Thema in StackOverflow, aber leider sind sie veraltet.

Ich habe die folgenden Methoden in einem Fragment aufgerufen.

Es wurde vorgeschlagen, einfach anzurufen:

requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
StorageKeys.STORAGE_PERMISSION_CODE)

Statt meiner Vorgehensweise:

ActivityCompat.requestPermissions(getActivity(),
new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
StorageKeys.STORAGE_PERMISSION_CODE))

Aber beide zeigen, dass onRequestPermissionsResult(…) veraltet ist.

Hier ist meine onRequestPermissionsResult(…)-Methode:

  @Override
  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                         @NonNull int[] grantResults) {

    if (requestCode == StorageKeys.STORAGE_PERMISSION_CODE) {

      if (grantResults.length > 0
          && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

        exportBibTex.createBibFile();
        exportBibTex.writeBibFile(exportBibTex
            .getBibDataLibrary(libraryModel, bookDao, noteDao));

        Toast.makeText(getContext(),
            getString(R.string.exported_file_stored_in) + '\n'
                + File.separator + StorageKeys.DOWNLOAD_FOLDER + File.separator + fileName
                + StorageKeys.BIB_FILE_TYPE, Toast.LENGTH_LONG).show();

      } else {
        Toast.makeText(getContext(), R.string.storage_permission_denied,
            Toast.LENGTH_SHORT).show();
      }
    }
  }

Hier ist ein einfacher Warndialog, in dem ich das onRequestPermissionsResult(…) aufrufe:

  private void showRequestPermissionDialog() {
    AlertDialog.Builder reqAlertDialog = new AlertDialog.Builder(getContext());
    reqAlertDialog.setTitle(R.string.storage_permission_needed);
    reqAlertDialog.setMessage(R.string.storage_permission_alert_msg);

    reqAlertDialog.setPositiveButton(R.string.ok,
        (dialog, which) -> ActivityCompat.requestPermissions(getActivity(),
            new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
            StorageKeys.STORAGE_PERMISSION_CODE));
    reqAlertDialog.setNegativeButton(R.string.cancel,
        (dialog, which) -> dialog.dismiss());

    reqAlertDialog.create().show();
  }

Gibt es eine Alternative für onRequestPermissionsResult(…), die ich verwenden kann?

  • onRequestPermissionsResult() ist nicht veraltet androidx.appcompat.app.AppCompatActivity. hast du welche Aktivitätsklasse verwendet?

    – Daniel.Wang

    9. März 2021 um 17:35 Uhr

  • Ich benutze es in einem Fragment. Die Erklärung von Android Studio lautet: „Überschreibt die veraltete Methode in ‚androidx.fragment.app.Fragment‘“

    – Asche

    9. März 2021 um 17:43 Uhr


  • Ich habe die Antwort gepostet und Ihre Frage beworben. damit Sie meine Antwort überprüfen können.

    – Daniel.Wang

    9. März 2021 um 18:25 Uhr


  • Sie sollten sich diesen offiziellen Leitfaden ansehen: youtu.be/oP-zXjkT0C0. onActivityResult() und onRequestPermissionResult() sind jetzt alle veraltet.

    – Sam Chen

    28. Mai 2021 um 16:59 Uhr

  • Die requestPermissions-Methode ist veraltet.

    – Abhinav Saxena

    28. Juli 2021 um 9:40 Uhr

Benutzer-Avatar
Daniel.Wang

Das onRequestPermissionsResult() Methode ist veraltet androidx.fragment.app.Fragment.

Sie dürfen also verwenden registerForActivityResult() Methode statt onRequestPermissionsResult().

Darauf können Sie verweisen URL.

Es folgt Kotlin-Code, aber Sie können darauf verweisen:

val requestPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission()
) { isGranted ->
    if (isGranted) {
        // PERMISSION GRANTED
    } else {
        // PERMISSION NOT GRANTED
    }
}

// Ex. Launching ACCESS_FINE_LOCATION permission.
private fun startLocationPermissionRequest() {
    requestPermissionLauncher(Manifest.permission.ACCESS_FINE_LOCATION)
}

Ich habe Java-Code von folgender URL hinzugefügt.
Wie erhalte ich eine Berechtigungsanfrage in der neuen ActivityResult-API (1.3.0-alpha05)?

private ActivityResultLauncher<String> requestPermissionLauncher = registerForActivityResult(
    new ActivityResultContracts.RequestPermission(),
    new ActivityResultCallback<Boolean>() {
        @Override
        public void onActivityResult(Boolean result) {
            if (result) {
                // PERMISSION GRANTED
            } else {
                // PERMISSION NOT GRANTED
            }
        }
    }
);

// Ex. Launch the permission window -- this is in onCreateView()
floatingActionButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        requestPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION);    
    }
});

Sie können auch mehrere Berechtigungen anfordern:

val requestMultiplePermissions = registerForActivityResult(
    ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
    permissions.entries.forEach {
        Log.d("DEBUG", "${it.key} = ${it.value}")
    }
}

requestMultiplePermissions.launch(
    arrayOf(
        Manifest.permission.READ_CONTACTS,
        Manifest.permission.ACCESS_FINE_LOCATION
    )
)

  • Danke, kann ich den ActivityResultLauncher(..) für mehrere Berechtigungen verwenden? Zum Beispiel requestPermissionLauncher.launch( Manifest.permission.WRITE_EXTERNAL_STORAGE); requestPermissionLauncher.launch (Manifest.permission.READ_EXTERNAL_STORAGE);

    – Asche

    9. März 2021 um 18:35 Uhr

  • ja, du kannst es verwenden. aber Sie müssen einen Teil meines Codes ändern. ich habe meinen Beitrag aktualisiert.

    – Daniel.Wang

    9. März 2021 um 18:43 Uhr

  • Sie müssen also verwenden ActivityResultContracts.RequestMultiplePermissions() beim Anruf registerForActivityResult() Methode.

    – Daniel.Wang

    9. März 2021 um 18:47 Uhr

  • Dies wird auch ausdrücklich in erwähnt die Dokumentation.

    – ianhanniballake

    9. März 2021 um 21:01 Uhr

Ein einfacher Weg hinein Kotlin

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityCompat
import androidx.fragment.app.Fragment

class MyFragment : Fragment() {

companion object {
    val TAG: String = MyFragment::class.java.simpleName
    var PERMISSIONS = arrayOf(
        Manifest.permission.CAMERA,
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
    )
}

private val permReqLauncher =
    registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
        val granted = permissions.entries.all {
            it.value == true
        }
        if (granted) {
            displayCameraFragment()
        }
    }

private fun takePhoto() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        displayCameraFragment()
    }
    activity?.let {
        if (hasPermissions(activity as Context, PERMISSIONS)) {
            displayCameraFragment()
        } else {
            permReqLauncher.launch(
                PERMISSIONS
            )
        }
    }
}

// util method
private fun hasPermissions(context: Context, permissions: Array<String>): Boolean = permissions.all {
    ActivityCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
}

private fun displayCameraFragment() {
    // open camera fragment
}
}

Alternatives registerForActivityResult

Beispielanwendung:

 private fun permissionSetup() {
    val permission = ContextCompat.checkSelfPermission(
        requireContext(), Manifest.permission.READ_CONTACTS)

    if (permission != PackageManager.PERMISSION_GRANTED) {
        permissionsResultCallback.launch(Manifest.permission.READ_CONTACTS)
    } else {
        println("Permission isGranted")
    }
}

private val permissionsResultCallback = registerForActivityResult(
    ActivityResultContracts.RequestPermission()){
    when (it) {
        true -> { println("Permission has been granted by user") }
        false -> {
            Toast.makeText(requireContext(), "Permission denied", Toast.LENGTH_SHORT).show()
            dialog.dismiss()
        }
    }
}

Registrieren Sie den Berechtigungsrückruf in Ihrer Aktivität oder Ihrem Fragment. die die Benutzerberechtigung behandeln Beispiel-Speicherberechtigung

 private final ActivityResultLauncher<String> requestPermissionLauncher = registerForActivityResult(
        new ActivityResultContracts.RequestPermission(),
        result -> {
            if (result) {
                  //Permission granted
 
            } else {
               //permission denied
                if (ActivityCompat.shouldShowRequestPermissionRationale(activity, WRITE_EXTERNAL_STORAGE)) {
                    //show permission snackbar
                } else {
                   //display error dialog
                }
            }

        });

Fragen Sie nach der Erlaubnis. Der registrierte ActivityResultCallback erhält das Ergebnis dieser Anfrage.

if (checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PermissionChecker.PERMISSION_GRANTED) {
                    requestPermissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE);
                } else {
                    //Permission already granted 
                }

Benutzer-Avatar
Andy Cass

Das funktioniert bei mir – (kotlin):

private fun checkPermissions() {
    if (mContext?.let {
        ContextCompat.checkSelfPermission(
            it,
            READ_EXTERNAL_STORAGE
        )
    } != PackageManager.PERMISSION_GRANTED) {
    Log.d(TAG, "Request Permissions")
    requestMultiplePermissions.launch(
        arrayOf(READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE))
 } else {
        Log.d(TAG, "Permission Already Granted")
    }
}

private val requestMultiplePermissions =
    registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
        permissions.entries.forEach {
            Log.d(TAG, "${it.key} = ${it.value}")
        }
        if (permissions[READ_EXTERNAL_STORAGE] == true && permissions[WRITE_EXTERNAL_STORAGE] == true) {
            Log.d(TAG, "Permission granted")
        } else {
            Log.d(TAG, "Permission not granted")
        }
    }

Benutzer-Avatar
CoolMind

Die meisten Antworten beziehen sich auf die OP-Anforderung. Aber ich habe einige Dinge gefunden, die fehlen, also dachte ich, ein vollständiges Beispiel zu geben (in Koltin).

class ProfileFragment : Fragment(){

private lateinit var permissionRequest : ActivityResultLauncher<Array<String>>

companion object {
      
    val LOCATION_PERMISSIONS = arrayOf(
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
        )
    }

    private fun getGpsLocation() {
        if(activity != null){
            permissionRequest.launch(LOCATION_PERMISSIONS)
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding.locBtn.setOnClickListener { getGpsLocation() }
    }


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        registerPermissionRequest()
    }
        
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {

        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_profile, container, false)
       
        return binding.root
    }
    
    private fun registerPermissionRequest(){
            var permissionCount = 0
            permissionRequest = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
                permissions.entries.forEach {
                    if(it.value){
                        permissionCount++
                    }
    
                }
    
                if(permissionCount == 2){
                    getMyLocation()
                }
            }
        }
    }

Die Dinge, die fehlen, sind

A) Fragmente müssen registerForActivityResult() aufrufen, bevor sie erstellt werden (dh Initialisierung, onAttach() oder onCreate()). Andernfalls funktioniert es nicht und die App würde abstürzen.

Fehler:

java.lang.IllegalStateException: Fragment ProfileFragment{bf12414} (210ad5a1-3286-4586-a48f-deac1d8e3eef id=0x7f09008b) versucht, sich nach der Erstellung zu registrierenForActivityResult. Fragmente müssen registerForActivityResult() aufrufen, bevor sie erstellt werden (dh Initialisierung, onAttach() oder onCreate()).

B) Es wird empfohlen, die Erlaubnis zu beantragen, wenn sie wirklich benötigt wird. In meinem Beispiel, wenn der Benutzer auf klickt Button mit Ausweis locBtnwird der Berechtigungsdialog angezeigt, anstatt angezeigt zu werden, wenn Aktivität/Fragment erstellt wird.

Benutzer-Avatar
Benutzer17175784

Bitte beachten Sie die offizielle Dokumentation: https://developer.android.com/training/permissions/requesting

Überprüfen Sie Folgendes, das in der Dokumentation zu finden ist.

// Register the permissions callback, which handles the user's response to the
// system permissions dialog. Save the return value, an instance of
// ActivityResultLauncher. You can use either a val, as shown in this snippet,
// or a lateinit var in your onAttach() or onCreate() method.
val requestPermissionLauncher =
    registerForActivityResult(RequestPermission()
    ) { isGranted: Boolean ->
        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.
        }
    }

Starten Sie danach die Anfrage

when {
    ContextCompat.checkSelfPermission(
            CONTEXT,
            Manifest.permission.REQUESTED_PERMISSION
            ) == PackageManager.PERMISSION_GRANTED -> {
        // You can use the API that requires the permission.
    }
    //Is not needed for it to work, but is a good practice as it plays a role
    //in letting user know why the permission is needed.
    shouldShowRequestPermissionRationale(...) -> {
        // In an educational UI, explain to the user why your app requires this
        // permission for a specific feature to behave as expected. In this UI,
        // include a "cancel" or "no thanks" button that allows the user to
        // continue using your app without granting the permission.
        showInContextUI(...)
    }
    else -> {
        // You can directly ask for the permission.
        // The registered ActivityResultCallback gets the result of this request.
        requestPermissionLauncher.launch(
                Manifest.permission.REQUESTED_PERMISSION)
    }
}

1142990cookie-checkAndroid – onRequestPermissionsResult() ist veraltet. Gibt es Alternativen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy