web-dev-qa-db-fra.com

Autorisation de demande Android Marshmallow?

Je travaille actuellement sur une application qui nécessite plusieurs autorisations "dangereuses". J'ai donc essayé d'ajouter "demander la permission" comme requis dans Android Marshmallow (API niveau 23), mais je n'ai pas trouvé comment le faire. 

Comment puis-je demander une autorisation en utilisant un nouveau modèle d'autorisation dans mon application?

127
Nilabja

Ouvrez une boîte de dialogue en utilisant le code ci-dessous:

 ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                    1);

Obtenez le résultat de l'activité comme ci-dessous: 

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 1: {

          // If request is cancelled, the result arrays are empty.
          if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.          
            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
                Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

Plus d'infos: https://developer.Android.com/training/permissions/requesting.html

189
Dixit Panchal

J'utilise cette structure pour vérifier si mon application a l'autorisation et que demande si elle n'a pas l'autorisation. Donc, dans mon code principal d'où je veux vérifier l'écriture suivante: 

int MyVersion = Build.VERSION.SDK_INT;
if (MyVersion > Build.VERSION_CODES.Lollipop_MR1) {
                if (!checkIfAlreadyhavePermission()) {
                    requestForSpecificPermission();
                }
}

Le module checkIfAlreadyhavePermission () est implémenté en tant que: 

private boolean checkIfAlreadyhavePermission() {
    int result = ContextCompat.checkSelfPermission(this, Manifest.permission.GET_ACCOUNTS);
    if (result == PackageManager.PERMISSION_GRANTED) {
        return true;
    } else {
        return false;
    }
}

Le module requestForSpecificPermission () est implémenté en tant que: 

private void requestForSpecificPermission() {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.GET_ACCOUNTS, Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_SMS, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 101);
}

et déroger à l'activité: 

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case 101:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //granted
            } else {
                //not granted
            }
            break;
        default:
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

Référez-vous à ce lien pour plus de détails: http://revisitingandroid.blogspot.fr 2017/01/how-teck-and-request-for-run-time.html

49
Tarun

J'ai utilisé ce wrapper (recommandé) écrit par les développeurs de Google. C'est super facile à utiliser.

https://github.com/googlesamples/easypermissions

Fonction traitant de la vérification et demande la permission si nécessaire

public void locationAndContactsTask() {
    String[] perms = { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_CONTACTS };
    if (EasyPermissions.hasPermissions(this, perms)) {
        // Have permissions, do the thing!
        Toast.makeText(this, "TODO: Location and Contacts things", Toast.LENGTH_LONG).show();
    } else {
        // Ask for both permissions
        EasyPermissions.requestPermissions(this, getString(R.string.rationale_location_contacts),
                RC_LOCATION_CONTACTS_PERM, perms);
    }
}

Bonne codage :)

15
Farhan

À partir d'Android Marshmallow, nous devons demander à l'utilisateur des autorisations spécifiques. Nous pouvons également vérifier par le code si l'autorisation est déjà donnée. Voici une liste des autorisations généralement nécessaires:

  • Android.permission-group.CALENDAR

    • Android.permission.READ_CALENDAR 
    • Android.permission.WRITE_CALENDAR
  • Android.permission-group.CAMERA

    • Android.permission.CAMERA
  • Android.permission-group.CONTACTS

    • Android.permission.READ_CONTACTS
    • Android.permission.WRITE_CONTACTS
    • Android.permission.GET_ACCOUNTS
  • Android.permission-group.LOCATION

    • Android.permission.ACCESS_FINE_LOCATION
    • Android.permission.ACCESS_COARSE_LOCATION
  • Android.permission-group.MICROPHONE

    • Android.permission.RECORD_AUDIO
  • Android.permission-group.PHONE

    • Android.permission.READ_PHONE_STATE
    • Android.permission.CALL_PHONE
    • Android.permission.READ_CALL_LOG
    • Android.permission.WRITE_CALL_LOG
    • Android.permission.ADD_VOICEMAIL
    • Android.permission.USE_SIP
    • Android.permission.PROCESS_OUTGOING_CALLS
  • Android.permission-group.SENSORS

    • Android.permission.BODY_SENSORS
  • Android.permission-group.SMS

    • Android.permission.SEND_SMS
    • Android.permission.RECEIVE_SMS
    • Android.permission.READ_SMS
    • Android.permission.RECEIVE_WAP_Push
    • Android.permission.RECEIVE_MMS
    • Android.permission.READ_CELL_BROADCASTS
  • Android.permission-group.STORAGE

    • Android.permission.READ_EXTERNAL_STORAGE
    • Android.permission.WRITE_EXTERNAL_STORAGE

Voici un exemple de code pour vérifier les autorisations:

if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
    if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.WRITE_CALENDAR)) {
        AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
        alertBuilder.setCancelable(true);
        alertBuilder.setMessage("Write calendar permission is necessary to write event!!!");
        alertBuilder.setPositiveButton(Android.R.string.yes, new DialogInterface.OnClickListener() {
            @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
            public void onClick(DialogInterface dialog, int which) {
                ActivityCompat.requestPermissions((Activity)context, new String[]{Manifest.permission.WRITE_CALENDAR}, MY_PERMISSIONS_REQUEST_WRITE_CALENDAR);
            }
        });
    } else {
        ActivityCompat.requestPermissions((Activity)context, new String[]{Manifest.permission.WRITE_CALENDAR}, MY_PERMISSIONS_REQUEST_WRITE_CALENDAR);
    }
}
13
Jeff D

Ma classe pour les autorisations d'exécution des demandes dans Activity ou Fragment

Il vous aide également à montrer justification ou à ouvrir Paramètre pour activer l'autorisation après que l'utilisateur a refusé l'autorisation (avec/sans Never ask again

class RequestPermissionHandler(private val activity: Activity? = null,
                               private val fragment: Fragment? = null,
                               private val permissions: Set<String> = hashSetOf(),
                               private val listener: Listener? = null
) {
    private var hadShowRationale: Boolean = false

    fun requestPermission() {
        hadShowRationale = showRationaleIfNeed()
        if (!hadShowRationale) {
            doRequestPermission(permissions)
        }
    }

    fun retryRequestDeniedPermission() {
        doRequestPermission(permissions)
    }

    private fun showRationaleIfNeed(): Boolean {
        val unGrantedPermissions = getPermission(permissions, Status.UN_GRANTED)
        val permanentDeniedPermissions = getPermission(unGrantedPermissions, Status.PERMANENT_DENIED)
        if (permanentDeniedPermissions.isNotEmpty()) {
            val consume = listener?.onShowSettingRationale(unGrantedPermissions)
            if (consume != null && consume) {
                return true
            }
        }

        val temporaryDeniedPermissions = getPermission(unGrantedPermissions, Status.TEMPORARY_DENIED)
        if (temporaryDeniedPermissions.isNotEmpty()) {
            val consume = listener?.onShowPermissionRationale(temporaryDeniedPermissions)
            if (consume != null && consume) {
                return true
            }
        }
        return false
    }

    fun requestPermissionInSetting() {
        val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
        val packageName = activity?.packageName ?: run {
            fragment?.requireActivity()?.packageName
        }
        val uri = Uri.fromParts("package", packageName, null)
        intent.data = uri
        activity?.apply {
            startActivityForResult(intent, REQUEST_CODE)
        } ?: run {
            fragment?.startActivityForResult(intent, REQUEST_CODE)
        }
    }

    fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
                                   grantResults: IntArray) {
        if (requestCode == REQUEST_CODE) {
            for (i in grantResults.indices) {
                if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                    markNeverAskAgainPermission(permissions[i], false)
                } else if (!shouldShowRequestPermissionRationale(permissions[i])) {
                    markNeverAskAgainPermission(permissions[i], true)
                }
            }
            var hasShowRationale = false
            if (!hadShowRationale) {
                hasShowRationale = showRationaleIfNeed()
            }
            if (hadShowRationale || !hasShowRationale) {
                notifyComplete()
            }
        }
    }

    fun onActivityResult(requestCode: Int) {
        if (requestCode == REQUEST_CODE) {
            getPermission(permissions, Status.GRANTED).forEach {
                markNeverAskAgainPermission(it, false)
            }
            notifyComplete()
        }
    }

    fun cancel() {
        notifyComplete()
    }

    private fun doRequestPermission(permissions: Set<String>) {
        activity?.let {
            ActivityCompat.requestPermissions(it, permissions.toTypedArray(), REQUEST_CODE)
        } ?: run {
            fragment?.requestPermissions(permissions.toTypedArray(), REQUEST_CODE)
        }
    }

    private fun getPermission(permissions: Set<String>, status: Status): Set<String> {
        val targetPermissions = HashSet<String>()
        for (p in permissions) {
            when (status) {
                Status.GRANTED -> {
                    if (isPermissionGranted(p)) {
                        targetPermissions.add(p)
                    }
                }
                Status.TEMPORARY_DENIED -> {
                    if (shouldShowRequestPermissionRationale(p)) {
                        targetPermissions.add(p)
                    }
                }
                Status.PERMANENT_DENIED -> {
                    if (isNeverAskAgainPermission(p)) {
                        targetPermissions.add(p)
                    }
                }
                Status.UN_GRANTED -> {
                    if (!isPermissionGranted(p)) {
                        targetPermissions.add(p)
                    }
                }
            }
        }
        return targetPermissions
    }

    private fun isPermissionGranted(permission: String): Boolean {
        return activity?.let {
            ActivityCompat.checkSelfPermission(it, permission) == PackageManager.PERMISSION_GRANTED
        } ?: run {
            ActivityCompat.checkSelfPermission(fragment!!.requireActivity(), permission) == PackageManager.PERMISSION_GRANTED
        }
    }

    private fun shouldShowRequestPermissionRationale(permission: String): Boolean {
        return activity?.let {
            ActivityCompat.shouldShowRequestPermissionRationale(it, permission)
        } ?: run {
            ActivityCompat.shouldShowRequestPermissionRationale(fragment!!.requireActivity(), permission)
        }
    }

    private fun notifyComplete() {
        listener?.onComplete(getPermission(permissions, Status.GRANTED), getPermission(permissions, Status.UN_GRANTED))
    }

    private fun getPrefs(context: Context): SharedPreferences {
        return context.getSharedPreferences("SHARED_PREFS_RUNTIME_PERMISSION", Context.MODE_PRIVATE)
    }

    private fun isNeverAskAgainPermission(permission: String): Boolean {
        return getPrefs(requireContext()).getBoolean(permission, false)
    }

    private fun markNeverAskAgainPermission(permission: String, value: Boolean) {
        getPrefs(requireContext()).edit().putBoolean(permission, value).apply()
    }

    private fun requireContext(): Context {
        return fragment?.requireContext() ?: run {
            activity!!
        }
    }

    enum class Status {
        GRANTED, UN_GRANTED, TEMPORARY_DENIED, PERMANENT_DENIED
    }

    interface Listener {
        fun onComplete(grantedPermissions: Set<String>, deniedPermissions: Set<String>)
        fun onShowPermissionRationale(permissions: Set<String>): Boolean
        fun onShowSettingRationale(permissions: Set<String>): Boolean
    }

    companion object {
        const val REQUEST_CODE = 200
    }
}

Utiliser dans Activity comme

class MainActivity : AppCompatActivity() {
    private lateinit var smsAndStoragePermissionHandler: RequestPermissionHandler

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        smsAndStoragePermissionHandler = RequestPermissionHandler(this@MainActivity,
                permissions = setOf(Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_EXTERNAL_STORAGE),
                listener = object : RequestPermissionHandler.Listener {
                    override fun onComplete(grantedPermissions: Set<String>, deniedPermissions: Set<String>) {
                        Toast.makeText(this@MainActivity, "complete", Toast.LENGTH_SHORT).show()
                        text_granted.text = "Granted: " + grantedPermissions.toString()
                        text_denied.text = "Denied: " + deniedPermissions.toString()
                    }

                    override fun onShowPermissionRationale(permissions: Set<String>): Boolean {
                        AlertDialog.Builder(this@MainActivity).setMessage("To able to Send Photo, we need SMS and" + " Storage permission")
                                .setPositiveButton("OK") { _, _ ->
                                    smsAndStoragePermissionHandler.retryRequestDeniedPermission()
                                }
                                .setNegativeButton("Cancel") { dialog, _ ->
                                    smsAndStoragePermissionHandler.cancel()
                                    dialog.dismiss()
                                }
                                .show()
                        return true // don't want to show any rationale, just return false here
                    }

                    override fun onShowSettingRationale(permissions: Set<String>): Boolean {
                        AlertDialog.Builder(this@MainActivity).setMessage("Go Settings -> Permission. " + "Make SMS on and Storage on")
                                .setPositiveButton("Settings") { _, _ ->
                                    smsAndStoragePermissionHandler.requestPermissionInSetting()
                                }
                                .setNegativeButton("Cancel") { dialog, _ ->
                                    smsAndStoragePermissionHandler.cancel()
                                    dialog.cancel()
                                }
                                .show()
                        return true
                    }
                })

        button_request.setOnClickListener { handleRequestPermission() }
    }

    private fun handleRequestPermission() {
        smsAndStoragePermissionHandler.requestPermission()
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
                                            grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        smsAndStoragePermissionHandler.onRequestPermissionsResult(requestCode, permissions,
                grantResults)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        smsAndStoragePermissionHandler.onActivityResult(requestCode)
    }
}

Code sur Github

Démo

11
Linh

Android-M, c'est-à-dire l'API 23 introduite Autorisations d'exécution pour réduire les failles de sécurité des appareils Android, où les utilisateurs peuvent désormais gérer directement les autorisations des applications sur runtime.so si l'utilisateur refuse une autorisation particulière de votre application, vous devez l'obtenir par demandant le dialogue de permission que vous avez mentionné dans votre requête. 

Vérifiez donc avant action, c’est-à-dire, si vous avez la permission d’accéder à la ressource link et si votre application n’a pas cette permission particulière, vous pouvez demander la permission link et gérer la réponse à la demande de permission comme ci-dessous.

@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.

               } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

Pour finir, il est recommandé de procéder à aux changements de comportement si vous prévoyez de travailler avec de nouvelles versions pour éviter la fermeture forcée :)

Meilleures pratiques pour les autorisations.

Vous pouvez passer par l'exemple d'application officiel ici

9
Anoop M

À partir d'Android Marshmallow (API 23) et supérieur, toutes les autorisations dangereuses (conformément au document officiel document officiel ) sont désactivées par défaut. Après l'installation lorsque l'application est ouverte pour la première fois, vous devez accorder une autorisation au moment de l'exécution.

J'ai réalisé cette manière suivante:

public class MarshMallowPermission {

    public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_GALLERY = 0;
    public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_CAMERA = 1;
    public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_LOAD_PROFILE = 2;
    public static final int CAMERA_PERMISSION_REQUEST_CODE = 3;
    public static final int LOCATION_PERMISSION_REQUEST_CODE = 4;
    Activity activity;
    Context mContext;

    public MarshMallowPermission(Activity activity) {
        this.activity = activity;
        this.mContext = activity;
    }

    public boolean checkPermissionForExternalStorage(){
        int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (result == PackageManager.PERMISSION_GRANTED){
            return true;
        } else {
            return false;
        }
    }

    public boolean checkPermissionForCamera(){
        int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA);
        if (result == PackageManager.PERMISSION_GRANTED){
            return true;
        } else {
            return false;
        }
    }

    public boolean checkLocationPermission(){

        int result = ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION);
        if (result == PackageManager.PERMISSION_GRANTED){
            return true;
        } else {
            return false;
        }
    }

    public void requestPermissionForExternalStorage(int requestCode){
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)){
            Toast.makeText(mContext.getApplicationContext(), "External Storage permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
        } else {
            ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},requestCode);
        }
    }

    public void requestPermissionForCamera(){
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA)){
            Toast.makeText(mContext.getApplicationContext(), "Camera permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
        } else {
            ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.CAMERA},CAMERA_PERMISSION_REQUEST_CODE);
        }
    }
    public void requestPermissionForLocation(){
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_FINE_LOCATION) && ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_COARSE_LOCATION)){
            Toast.makeText(mContext.getApplicationContext(), "Location permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
        } else {
            ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE);
        }
    }
}

DANS votre classe d'activité:

 public class MainActivity extends AppCompatActivity{

   private MarshMallowPermission marshMallowPermission;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d("NavHome", "Oncreate_nav");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        marshMallowPermission = new MarshMallowPermission(MainActivity.this);



        if (!marshMallowPermission.checkPermissionForExternalStorage()) {
            marshMallowPermission.requestPermissionForExternalStorage(MarshMallowPermission.EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_LOAD_PROFILE);
        }
    }

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

        switch (requestCode) {
            case MarshMallowPermission.EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_LOAD_PROFILE:
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    //permission granted successfully

                } else {

                 //permission denied

                }
                break;
    }
    }

}
6
Vikas Tiwari

J'utilise ceci comme classe de fragment de base. Je ne demande que les permissions d'un fragment, mais vous pouvez le refactoriser et créer une version Activity similaire.

public class BaseFragment extends Fragment {

    private static final int PERMISSION_REQUEST_BLOCK_INTERNAL = 555;
    private static final String PERMISSION_SHARED_PREFERENCES = "permissions";

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == PERMISSION_REQUEST_BLOCK_INTERNAL) {
            boolean allPermissionsGranted = true;

            for (int iGranting : grantResults) {
                if (iGranting != PermissionChecker.PERMISSION_GRANTED) {
                    allPermissionsGranted = false;
                    break;
                }
            }

            if (allPermissionsGranted && permissionBlock != null) {
                permissionBlock.run();
            }

            permissionBlock = null;
        }
    }

    public void runNowOrAskForPermissionsFirst(String permission, Runnable block) {
        if (hasPermission(permission)) {
            block.run();
        } else if (!hasPermissionOrWillAsk(permission)) {
            permissionBlock = block;
            askForPermission(permission, PERMISSION_REQUEST_BLOCK_INTERNAL);
        }
    }

    public boolean hasPermissionOrWillAsk(String permission) {
        boolean hasPermission = hasPermission(permission);
        boolean hasAsked = hasPreviouslyAskedForPermission(permission);
        boolean shouldExplain = shouldShowRequestPermissionRationale(permission);

        return hasPermission || (hasAsked && !shouldExplain);
    }

    private boolean hasPermission(String permission) {
        return (ContextCompat.checkSelfPermission(getContext(), permission) == PackageManager.PERMISSION_GRANTED);
    }

    private boolean hasPreviouslyAskedForPermission(String permission) {
        SharedPreferences prefs = getContext().getSharedPreferences(PERMISSION_SHARED_PREFERENCES, Context.MODE_PRIVATE);
        return prefs.getBoolean(permission, false);
    }

    private void askForPermission(String permission, int requestCode) {
        SharedPreferences.Editor editor = getContext().getSharedPreferences(PERMISSION_SHARED_PREFERENCES, Context.MODE_PRIVATE).edit();

        editor.putBoolean(permission, true);
        editor.apply();

        requestPermissions(new String[] { permission }, requestCode);
    }
}

Vous devez utiliser deux méthodes clés:

  • hasPermissionOrWillAsk - Utilisez ceci pour voir si une autorisation a été demandée et refusée par un utilisateur qui ne veut pas être à nouveau demandé. Ceci est utile pour désactiver l'interface utilisateur lorsque l'utilisateur a donné sa réponse finale à propos de ne pas vouloir d'une fonctionnalité.

  • runNowOrAskForPermissionsFirst - Utilisez cette option pour exécuter du code nécessitant des autorisations. Si l'utilisateur a déjà accordé une autorisation, le code s'exécutera immédiatement. Sinon, le code sera exécuté ultérieurement si l'utilisateur accorde l'autorisation. Ou pas du tout. C'est bien parce que vous spécifiez le code à un endroit.

Voici un exemple:

mFragment.runNowOrAskForPermissionsFirst(Manifest.permission.ACCESS_FINE_LOCATION, new Runnable() {
    @Override
    public void run() {
        ...do something if we have permission...
    }
});

Heureux d'avoir des retours à ce sujet. Non pas que cet exemple spécifique soit un peu simplifié dans la mesure où vous devez également vérifier si les services de localisation sont activés sur le périphérique. (Cela diffère des autorisations.) En outre, il ne prend en charge qu'une autorisation à la fois, mais il serait simple à modifier si vous en avez besoin pour prendre en charge plusieurs autorisations à la fois.

4
ZaBlanc

Ce peut être un moyen plus propre. Ajoutez toutes vos autorisations dans un tableau comme 

private static final String[] INITIAL_PERMS={
            Android.Manifest.permission.ACCESS_FINE_LOCATION,
            Android.Manifest.permission.ACCESS_COARSE_LOCATION
    };
    private static final int INITIAL_REQUEST=1337;

Quelle que soit votre permision, créez une méthode pour chaque permision

@RequiresApi(api = Build.VERSION_CODES.M)
private boolean canAccessFineLocation() {
    return(hasPermission(Manifest.permission.ACCESS_FINE_LOCATION));
}

@RequiresApi(api = Build.VERSION_CODES.M)
private boolean canAccessCoarseLocation() {
    return(hasPermission(Manifest.permission.ACCESS_COARSE_LOCATION));
}

@RequiresApi(api = Build.VERSION_CODES.M)
private boolean hasPermission(String perm) {
    return(PackageManager.PERMISSION_GRANTED == checkSelfPermission(perm));
}

Appelez cette méthode dans onCreate

 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
      if(!canAccessCoarseLocation() || !canAccessFineLocation()){
            requestPermissions(INITIAL_PERMS, INITIAL_REQUEST);
        }
 }

Maintenant, remplacez onRequestPermissionsResult

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

    if(requestCode == INITIAL_REQUEST){
        if (canAccessFineLocation() && canAccessCoarseLocation())  {
            //call your method
        }
        else {
            //show Toast or alert that this permissions is neccessary
        }
    }
}
4
Xar E Ahmer

Pour gérer les autorisations d'exécution, Google a fourni un projet de bibliothèque. Vous pouvez vérifier ceci à partir d'ici https://github.com/googlesamples/easypermissions

EasyPermissions est installé en ajoutant la dépendance suivante à votre fichier build.gradle:

dependencies {
compile 'pub.devrel:easypermissions:0.3.0'
}

Pour commencer à utiliser EasyPermissions, demandez à votre activité (ou à un fragment) de remplacer la méthode onRequestPermissionsResult:

public class MainActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

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

    // Forward results to EasyPermissions
    EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}

@Override
public void onPermissionsGranted(int requestCode, List<String> list) {
    // Some permissions have been granted
    // ...
}

@Override
public void onPermissionsDenied(int requestCode, List<String> list) {
    // Some permissions have been denied
    // ...
}
}

Vous obtiendrez ici un exemple concret du fonctionnement de cette bibliothèque https://github.com/milon87/EasyPermission

3
Din Islam Milon

Il existe une bonne bibliothèque qui peut être utilisée dans le cas où des autorisations doivent être demandées lorsqu'une autorisation est requise par un service en arrière-plan. Bien que la bibliothèque soit limitée, elle ne peut pas être utilisée pour déterminer si des autorisations sont actuellement accordées ou non à l'application. Il demande toujours à l'utilisateur si l'application ne les a pas déjà.

Faites un essai car il simplifie la vie: Autorisations Android

2
Nishkarsh

Pour plusieurs autorisations à la fois, vous pouvez utiliser ceci. Ce travail pour moi .. J'ai une autre solution. si vous donnez à votre targetSdkVersion ci-dessous 22 cela fonctionne pour moi. et cela se comporte comme si vous obteniez l’autorisation de manifest.xml. Testé et fonctionne pour moi. 

final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;

    private void insertDummyContactWrapper() {
        List<String> permissionsNeeded = new ArrayList<String>();

        final List<String> permissionsList = new ArrayList<String>();
        if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))
            permissionsNeeded.add("GPS");
        if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS))
            permissionsNeeded.add("Read Contacts");
        if (!addPermission(permissionsList, Manifest.permission.WRITE_CONTACTS))
            permissionsNeeded.add("Write Contacts");

        if (permissionsList.size() > 0) {
            if (permissionsNeeded.size() > 0) {
                // Need Rationale
                String message = "You need to grant access to " + permissionsNeeded.get(0);
                for (int i = 1; i < permissionsNeeded.size(); i++)
                    message = message + ", " + permissionsNeeded.get(i);
                showMessageOKCancel(message,
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                                        REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
                            }
                        });
                return;
            }
            requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                    REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
            return;
        }

        insertDummyContact();
    }

    private boolean addPermission(List<String> permissionsList, String permission) {
        if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
            permissionsList.add(permission);
            // Check for Rationale Option
            if (!shouldShowRequestPermissionRationale(permission))
                return false;
        }
        return true;
    }






@Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS:
                {
                Map<String, Integer> perms = new HashMap<String, Integer>();
                // Initial
                perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
                perms.put(Manifest.permission.READ_CONTACTS, PackageManager.PERMISSION_GRANTED);
                perms.put(Manifest.permission.WRITE_CONTACTS, PackageManager.PERMISSION_GRANTED);
                // Fill with results
                for (int i = 0; i < permissions.length; i++)
                    perms.put(permissions[i], grantResults[i]);
                // Check for ACCESS_FINE_LOCATION
                if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                        && perms.get(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED
                        && perms.get(Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
                    // All Permissions Granted
                    insertDummyContact();
                } else {
                    // Permission Denied
                    Toast.makeText(MainActivity.this, "Some Permission is Denied", Toast.LENGTH_SHORT)
                            .show();
                }
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

Pour plus de détails. Vérifiez le lien ci-dessous

https://inthecheesefactory.com/blog/things-you-neo-to-know-about-Android-m-permission-developer-edition/fr

2
Tariqul

Essaye ça

C'est le moyen le plus simple de demander la permission dans la version Marshmallow.

 if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED&&ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
    {
        //TO do here if permission is granted by user
    }
    else
    {
        //ask for permission if user didnot given
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
        {
            requestPermissions(new String[]{Manifest.permission.CAMERA,Manifest.permission.ACCESS_FINE_LOCATION}, 0);
        }
    }

Remarque: - N'oubliez pas d'ajouter cette même permission également dans le fichier manifeste

 <uses-permission Android:name="Android.permission.CAMERA" />
<uses-permission Android:name="Android.permission.ACCESS_FINE_LOCATION" />

Deuxième méthode Code de vérification de l'autorisation accordée ou non?

ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CAMERA}, 1);

Et remplacer la méthode 

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 1: {
            if (grantResults.length > 0 && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
         //                    grantResult[0] means it will check for the first postion permission which is READ_EXTERNAL_STORAGE
        //                    grantResult[1] means it will check for the Second postion permission which is CAMERA
                Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();
            }
            else
                Toast.makeText(this, "Permission not Granted", Toast.LENGTH_SHORT).show();
            return;
        }
    }
}
1
Sunil

Ce code ci-dessous fonctionne parfaitement. J'explique à l'aide d'un exemple.

Dans mon cas, j’ai placé les vérifications d’autorisation séparément dans une classe util et passé les autorisations spécifiques dont j’ai besoin pour vérifier auprès des classes appropriées. Cela permet de réutiliser le fichier util de vérification des autorisations dans toute l’application.

La partie de code ci-dessous montre l'appel de fonction. Dans ce cas, je demande l'autorisation Android.Manifest.permission.READ_EXTERNAL_STORAGE.

//the below call is from a fragment
     @OnClick(R.id.button)//butterknife implementation
        public void attachPressed() {
            if (PermissionUtils.hasThisPermission(getContext(), Android.Manifest.permission.READ_EXTERNAL_STORAGE)) {
                onAttachPressed();
            } else {
                PermissionUtils.isPermissionRequestNeeded(getActivity(), this, Android.Manifest.permission.READ_EXTERNAL_STORAGE, PermissionUtils.REQUEST_GROUP_STORAGE);
            }
        }   

Dans le cas ci-dessus, l'autorisation est cochée si elle est autorisée, la fonction onAttachPressed(); est appelée, sinon nous vérifions l'autorisation de demande.

Le code ci-dessous correspond au code présent dans la classe util dans mon cas PermissionUtils

public final class PermissionUtils {

    public static final int REQUEST_GROUP_STORAGE = 1508;

    private PermissionUtils() {
    }

    public static boolean hasThisPermission(Context context, String permission) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return ActivityCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
        } else {
            return true;
        }
    }

    public static boolean isPermissionRequestNeeded(Activity activity, Fragment fragment, String permission, int requestCode) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !hasThisPermission(activity, permission)) {
            final String[] permissions = new String[]{permission};
            if (fragment == null) {
                activity.requestPermissions(permissions, requestCode);
            } else {
                fragment.requestPermissions(permissions, requestCode);
            }
            return true;
        }
        return false;
    }
}

Et après la demande, si vous souhaitez appeler la fonction à partir de onRequestPermissionsResult, vous devrez sinon appuyer à nouveau sur le bouton pour l'appel de fonction.

Alors appelez-le de onRequestPermissionsResult

//the below call  is from a fragment
     @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
            if (requestCode == PermissionUtils.REQUEST_GROUP_STORAGE && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                onAttachPressed();
            } else {
                Log.e("value", "Permission Denied, You cannot use local drive .");
            }
        }
1
Amal p

Un moyen simple de demander la permission en évitant d’écrire beaucoup de code,

https://github.com/sachinvarma/EasyPermission

Comment ajouter :

repositories {
        maven { url "https://jitpack.io" }
    }

implementation 'com.github.sachinvarma:EasyPermission:1.0.1'

Comment demander la permission:

 List<String> permission = new ArrayList<>();
 permission.add(EasyPermissionList.READ_EXTERNAL_STORAGE);
 permission.add(EasyPermissionList.ACCESS_FINE_LOCATION);

 new EasyPermissionInit(MainActivity.this, permission);

En espérant que cela sera utile pour quelqu'un.

1
Sachin Varma

J'utilise RxPermission bibliothèque pour demander l'autorisation. Parce que c'est un code long que nous devons écrire pour demander la permission.

RxPermissions rxPermissions = new RxPermissions(this); // where this is an Activity instance // Must be done during an initialization phase like onCreate
rxPermissions
    .request(Manifest.permission.CAMERA)
    .subscribe(granted -> {
        if (granted) { // Always true pre-M
           // I can control the camera now
        } else {
           // Oups permission denied
        }
    });

Ajoutez ces dépendances dans votre build.gradle

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

dependencies {
    implementation 'com.github.tbruyelle:rxpermissions:0.10.1'
    implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
}
0
Khemraj

J'ai parcouru toutes les réponses, mais je n'ai pas trouvé la réponse exacte, voici donc un exemple que j'ai écrit et qui fonctionne parfaitement, même si l'utilisateur clique sur Ne plus demander case à cocher.

  1. Créez une méthode qui sera appelée lorsque vous souhaitez demander une autorisation d'exécution telle que readContacts() ou vous pouvez également avoir openCamera() comme indiqué ci-dessous:

    private void readContacts() {
        if (!askContactsPermission()) {
            return;
        } else {
            queryContacts();
        } }
    

Maintenant, nous devons créer askContactsPermission(), vous pouvez également le nommer comme suit: askCameraPermission() ou quelle que soit l'autorisation que vous allez demander.

    private boolean askContactsPermission() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        return true;
    }
    if (checkSelfPermission(READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
        return true;
    }
    if (shouldShowRequestPermissionRationale(READ_CONTACTS)) {
        Snackbar.make(parentLayout, R.string.permission_rationale, Snackbar.LENGTH_INDEFINITE)
                .setAction(Android.R.string.ok, new View.OnClickListener() {
                    @Override
                    @TargetApi(Build.VERSION_CODES.M)
                    public void onClick(View v) {
                        requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
                    }
                }).show();
    } else if (contactPermissionNotGiven) {
        openPermissionSettingDialog();
    } else {
        requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
        contactPermissionNotGiven = true;

    }
    return false;
}

Avant d'écrire cette fonction, assurez-vous d'avoir défini la variable d'instance ci-dessous, comme indiqué:

    private View parentLayout;
    private boolean contactPermissionNotGiven;;


/**
 * Id to identity READ_CONTACTS permission request.
 */
private static final int REQUEST_READ_CONTACTS = 0;

Dernière étape pour remplacer la méthode onRequestPermissionsResult comme indiqué ci-dessous:

/**
 * Callback received when a permissions request has been completed.
 */
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    if (requestCode == REQUEST_READ_CONTACTS) {
        if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            queryContacts();
        }
    }
}

Nous en avons terminé avec les autorisations RunTime. L'addon est la openPermissionSettingDialog() qui ouvre simplement l'écran Paramètre si l'utilisateur a désactivé l'autorisation en permanence en cliquant sur Ne plus demander case à cocher. ci-dessous est la méthode:

    private void openPermissionSettingDialog() {
    String message = getString(R.string.message_permission_disabled);
    AlertDialog alertDialog =
            new AlertDialog.Builder(MainActivity.this, AlertDialog.THEME_DEVICE_DEFAULT_LIGHT)
                    .setMessage(message)
                    .setPositiveButton(getString(Android.R.string.ok),
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    Intent intent = new Intent();
                                    intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                    Uri uri = Uri.fromParts("package", getPackageName(), null);
                                    intent.setData(uri);
                                    startActivity(intent);
                                    dialog.cancel();
                                }
                            }).show();
    alertDialog.setCanceledOnTouchOutside(true);
}

Qu'est-ce que nous avons manqué? 1. Définir les chaînes utilisées dans strings.xml

<string name="permission_rationale">"Contacts permissions are needed to display Contacts."</string>
    <string name="message_permission_disabled">You have disabled the permissions permanently,
        To enable the permissions please go to Settings -> Permissions and enable the required Permissions,
        pressing OK you will be navigated to Settings screen</string>

  1. Initialisation de la variable parentLayout dans la méthode onCreate

    parentLayout = findViewById (R.id.content);

  2. Définir l'autorisation requise dans AndroidManifest.xml

<uses-permission Android:name="Android.permission.READ_CONTACTS" />

  1. La méthode queryContacts, en fonction de vos besoins ou de l'autorisation d'exécution, vous pouvez appeler votre méthode avant laquelle la permission était nécessaire. dans mon cas, j'utilise simplement le chargeur pour récupérer le contact, comme indiqué ci-dessous:

    private void queryContacts() {
    getLoaderManager().initLoader(0, null, this);}
    

Cela fonctionne très bien le codage :) 

0
HAXM

Autorisation d'exécution AnyWhere In ApplicationVoici un exemple

use dependency
maven { url 'https://jitpack.io' }
dependencies {
implementation 'com.github.irshadsparky:PermissionLib:master-SNAPSHOT'
}

et appelez le code comme ceci: 

PermissionHelper.requestCamera(new PermissionHelper.OnPermissionGrantedListener() {
@Override
public void onPermissionGranted() {

}
});

vous pouvez trouver plus Github

0
irshad sheikh

Ajouter les autorisations au fichier AndroidManifest.xml

<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE"/>
<application ...>
 ....
</application>

Pour vérifier la version Android si elle nécessite une autorisation d'exécution ou non.

if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Lollipop_MR1) {
    askForPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, 1);
}

Demandez à l'utilisateur d'accorder l'autorisation s'il n'est pas accordé.

private void askForPermission(String permission, int requestCode) {
    if (ContextCompat.checkSelfPermission(c, permission)
            != PackageManager.PERMISSION_GRANTED) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, permission)) {
            Toast.makeText(c, "Please grant the requested permission to get your task done!", Toast.LENGTH_LONG).show();
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);
        } else {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);
        }
    }
}

Faites quelque chose si la permission a été accordée ou non. 

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case 1:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //permission with request code 1 granted
                Toast.makeText(this, "Permission Granted" , Toast.LENGTH_LONG).show();
            } else {
                //permission with request code 1 was not granted
                Toast.makeText(this, "Permission was not Granted" , Toast.LENGTH_LONG).show();
            }
            break;
        default:
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}
0
Muhammad
  if (CommonMethod.isNetworkAvailable(MainActivity.this)) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                        int permissionCheck = ContextCompat.checkSelfPermission(MainActivity.this,
                                Android.Manifest.permission.CAMERA);
                        if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
                            //showing dialog to select image
                            callFacebook();
                            Log.e("permission", "granted Marshmallow");
                        } else {
                            ActivityCompat.requestPermissions(MainActivity.this,
                                    new String[]{Android.Manifest.permission.READ_EXTERNAL_STORAGE,
                                            Android.Manifest.permission.WRITE_EXTERNAL_STORAGE, Android.Manifest.permission.CAMERA}, 1);
                        }
                    } else {
                        Log.e("permission", "Not Required Less than Marshmallow Version");
                        callFacebook();
                    }
                } else {
                    CommonMethod.showAlert("Internet Connectivity Failure", MainActivity.this);
                }
0
Keshav Gera

Vous pouvez utiliser ma bibliothèque - NoPermission (c'est juste une classe)

compile 'ru.alexbykov:nopermission:1.1.1'

Échantillon

PermissionHelper permissionHelper = new PermissionHelper(this); //don't use getActivity in fragment!

permissionHelper.check(Manifest.permission.READ_CONTACTS)
                .onSuccess(this::onSuccess)
                .onDenied(this::onDenied)
                .onNeverAskAgain(this::onNeverAskAgain)
                .run();

onRequestPermissionResult:

 @Override
  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
        permissionHelper.onRequestPermissionsResult(requestCode, permissions, grantResults);
   }

Je pense api plus pratique que EasyPermissions de Google.

0
no news