Android M Permissions: onRequestPermissionsResult () n'est pas appelé

Je mets à jour notre application pour utiliser le nouveau système D'autorisations M. Tout fonctionne en plus de onRequestPermissionsResult(). Je dois vérifier une autorisation sur une pression de bouton, et si elle réussit, envoyer un message texte. Lorsque j'accorde la permission de le faire, la boîte de dialogue se ferme, mais elle ne déclenche pas L'envoi de texte jusqu'à ce que j'appuie à nouveau sur le bouton.

J'ai débogué et défini des points d'arrêt dans la méthode onRequestPermissionsResult() mais elle n'y va jamais.

Cette méthode est appelée premier:

    private void askForPermission() {
    String[] permissions = new String[]{Manifest.permission.SEND_SMS};
    ActivityCompat.requestPermissions(getActivity(), permissions, PERMISSIONS_CODE);
}

Et puis Mon Rappel ressemble à ceci:

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

    if (requestCode == PERMISSIONS_CODE) {
        for (int i = 0; i < permissions.length; i++) {
            String permission = permissions[i];
            int grantResult = grantResults[i];

            if (permission.equals(Manifest.permission.SEND_SMS)) {
                if (grantResult == PackageManager.PERMISSION_GRANTED) {
                    onPPSButtonPress();
                } else {
                    requestPermissions(new String[]{Manifest.permission.SEND_SMS}, PERMISSIONS_CODE);
                }
            }
        }
    }
}

Quelqu'un a-t-il rencontré un problème similaire? Appréciez toute aide avec cela. Merci

249
demandé sur AndyOHart 2015-09-22 13:42:13

22 réponses

J'ai rencontré le même problème et je viens de trouver la solution. Lorsque vous utilisez la bibliothèque de Support, vous devez utiliser les appels de méthode corrects. Par exemple:

  • Lorsque dans AppCompatActivity, vous devez utiliser ActivityCompat.requestPermissions ;
  • Quand dans android.soutien.v4.App.Fragment, vous devez utiliser simplement requestPermissions (c'est une méthode d'instance de android.soutien.v4.App.Fragment)

Si vous appelez ActivityCompat.requestPermissions dans un fragment, le rappel onRequestPermissionsResult est appelé sur l'activité et non sur le fragment.

J'espère que cela aide!

535
répondu yavor87 2015-10-12 12:04:42

, Vous pouvez essayer ceci:

requestPermissions(permissions, PERMISSIONS_CODE);

Si vous appelez ce code à partir d'un fragment, il a sa propre méthode requestPermissions. Je crois que le problème est que vous appelez la méthode statique.

Astuce Pro si vous voulez le onRequestPermissionsResult() dans un fragment: FragmentCompat.requestPermissions(Fragment fragment, String[] permissions, int requestCode)

92
répondu Tieru 2016-08-09 10:53:31

J'espère que cela fonctionne bien

Pour L'Activité:

 ActivityCompat.requestPermissions(this,permissionsList,REQUEST_CODE);

Pour Le Fragment:

 requestPermissions(permissionsList,REQUEST_CODE);
56
répondu Sanjay Mangaroliya 2017-07-23 18:07:15

, j'ai rencontré ce problème aussi. Si vous voulez que l'activité qui gère les autorisations ne figure pas dans l'historique/les récents, vous serez tenté de changer votre entrée AndroidManifest.xml.

Si vous définissez l'activité que vous appelez requestPermissions ou AppCompatActivity.requestPermissions avec

android:noHistory="true"
android:excludeFromRecents="true"

Votre AndroidManifest.xml, puis onRequestPermissionsResult() ne sera pas appelé. Cela est vrai si votre activité est dérivée de Activity ou AppCompatActivity.

Cela peut être corrigé en supprimant les deux drapeaux de ' AndroidManifest.xml' et terminer votre activité avec finishAndRemoveTask() à la place.

46
répondu Simon Featherstone 2016-03-04 14:20:05

Si vous avez onRequestPermissionsResult dans activity et fragment, assurez-vous d'appeler super.onRequestPermissionsResult dans activity. Il n'est pas nécessaire dans fragment, mais il est en activité.

35
répondu Dusan Zivkovic 2015-11-30 10:40:56

À l'intérieur du fragment, vous devez appeler:

FragmentCompat.requestPermissions(permissionsList, RequestCode)

Pas:

ActivityCompat.requestPermissions(Activity, permissionsList, RequestCode);
31
répondu Ben.Slama.Jihed 2016-08-09 10:54:53

Si vous utilisez requestPermissions dans fragment, il accepte 2 paramètres au lieu de 3.

Vous devriez utiliser requestPermissions(permissions, PERMISSIONS_CODE);

15
répondu Don AkKi 2015-12-16 14:45:00

Si, pour une raison quelconque, vous avez étendu une activité personnalisée située dans une bibliothèque externe qui n'appelle pas le SUPER, vous devrez appeler manuellement le Super Fragment.onRequestPermissionsResult vous-même dans votre activité onRequestPermissionsResult.

YourActivity extends SomeActivityNotCallingSuperOnRequestPermissionsResult{
Fragment requestingFragment;//the fragment requesting the permission
...
@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if(requestingFragment!=null)
            requestingFragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
...
14
répondu TouchBoarder 2016-01-22 11:20:03

Vous avez la fonctioncheckpermissions pour les périphériques pré Marshmallow dans FragmentCompat. J'utilise comme ceci:

FragmentCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
12
répondu Marta Rodriguez 2015-09-30 11:48:25

, j'ai découvert que est importante où vous appelez android.support.v4.app.Fragment.requestPermissions.

Si vous le faites dans onCreate(), onRequestPermissionsResult() n'est jamais appelée.

Solution: appelez-le dans onActivityCreated();

@Override
public void onActivityCreated(Bundle savedInstanceState) {

    super.onActivityCreated(savedInstanceState);

    if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_DENIED) 
        requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, 0);

}
12
répondu almisoft 2016-02-15 23:33:00

Ce problème a été causé par NestedFragments. Fondamentalement, la plupart des fragments que nous avons étendent un HostedFragment qui à son tour étend un CompatFragment. Avoir ces fragments imbriqués a causé des problèmes qui ont finalement été résolus par un autre développeur sur le projet.

Il faisait des choses de bas niveau comme la commutation de bits pour que cela fonctionne, donc je ne suis pas trop sûr de la solution finale réelle

9
répondu AndyOHart 2015-10-12 12:28:51
 /* use the object of your fragment to call the 
 * onRequestPermissionsResult in fragment after
 * in activity and use different request Code for 
 * both Activity and Fragment */

   if (isFragment)
    mFragment.requestPermissions(permissions.toArray(new
    String[permissions.size()]),requestPermission);

   else
    ActivityCompat.requestPermissions(mActivity,permissions.toArray(new
    String[permissions.size()]),requestPermission);
9
répondu Shahab Rauf 2016-03-03 13:31:12

Cela fonctionnera..

@Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
6
répondu Sumit khare 2016-02-07 00:05:56

Si vous appelez ce code à partir d'un fragment, il a sa propre méthode requestPermissions.

Le concept de base est donc, si vous êtes dans une activité, appelez

ActivityCompat.requestPermissions(this,
                            permissionsList,
                            permissionscode);

Et si dans un Fragment, appelez simplement

requestPermissions(permissionsList,
                            permissionscode);
4
répondu PounKumar Purushothaman 2017-07-23 17:56:27

Avant de tout vérifier selon les réponses ci-dessus, assurez-vous que votre code de demande n'est pas 0!!!

Vérifiez le code de onRequestPermissionsResult () dans Fragmentaactivity.java:

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
        @NonNull int[] grantResults) {
    int index = (requestCode>>16)&0xffff;
    if (index != 0) {
        index--;

        String who = mPendingFragmentActivityResults.get(index);
        mPendingFragmentActivityResults.remove(index);
        if (who == null) {
            Log.w(TAG, "Activity result delivered for unknown Fragment.");
            return;
        }
        Fragment frag = mFragments.findFragmentByWho(who);
        if (frag == null) {
            Log.w(TAG, "Activity result no fragment exists for who: " + who);
        } else {
            frag.onRequestPermissionsResult(requestCode&0xffff, permissions, grantResults);
        }
    }
}
2
répondu Chandler 2016-07-07 01:50:13

Basé sur la réponse de goodgamerguy la solution est:

myFragment.this.requestPermissions(....)
2
répondu Hamza Elmi 2017-08-04 13:30:26
private void showContacts() {
    if (getActivity().checkSelfPermission(Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {
        requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, PERMISSIONS_REQUEST_READ_CONTACTS);
    } else {
        doShowContacts();
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        doShowContacts();
    }
}
1
répondu user2002721 2017-01-04 00:10:40

Vous pouvez utiliser requestPermissions(PERMISSIONS, MULTIPLE_PERMISSIONS_CODE);. N'utilisez pas FragmentCompat si vous utilisez v4.

1
répondu Remario 2017-07-21 04:07:36

UPDATE: j'ai vu la réponse de quelqu'un d'autre à propos de l'appel de super.onRequestPermissionResult() dans Activity et qui corrige le problème de code de requête que j'ai mentionné et appelle onRequestPermissionResult du fragment.

Ignorer ce genre de choses:

Pour moi, il appelait onRequestPermissionResult de l'activité malgré que j'appelle fragment.requestPermission(...), Mais il a renvoyé le résultat avec un requestCode incorrect (111 transformé en 65647 pourquoi ??? Je ne le saurai jamais).

Heureusement c'est la seule autorisation que nous demandons sur cet écran, donc j'ignore simplement le code de la demande (je n'ai pas le temps de comprendre pourquoi ce n'est pas correct en ce moment)

1
répondu grgrssll 2017-10-12 22:23:44

J'ai une solution incroyable pour y parvenir faire une BaseActivity comme celle-ci.

public class BaseActivity extends AppCompatActivity {

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this));


}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
    switch (requestCode) {
        case 1: {
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                CustomToast.getInstance().setCustomToast("Now you can share the Hack.");

            } else {
                Toast.makeText(this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

}

Maintenant, vous pouvez appeler le code pour demander la permission comme ceci

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

Maintenant, chaque fois que cela se produit n'importe où, que ce soit dans votre fragment ou dans n'importe quelle activité, l'activité de base serait appelée.

Merci

0
répondu Abhishek Dubey 2018-01-15 07:53:56

Détails

  • Kotlin 1.2.70
  • vérifié dans minSdkVersion 19
  • Android Studio 3.1.4

Algorithme

Module - appareil photo, l'emplacement, l' ....

  1. Vérifiez si hasSystemFeature (Si module existent dans le téléphone)
  2. Vérifiez si l'Utilisateur a accès au module
  3. Envoyer des autorisations de demande (demander à l'utilisateur d'autoriser module utilisation)

Caractéristiques

  1. travailler avec des activités et Fragments
  2. N'a qu'une seule réponse de résultat
  3. Pouvez vérifier plusieurs modules dans une requête

Solution

class PermissionType(val manifest_permission: String, val packageManager: String) {
    object Defined {
        val camera = PermissionType(Manifest.permission.CAMERA, PackageManager.FEATURE_CAMERA)
        val currentLocation = PermissionType(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.FEATURE_LOCATION_GPS)
    }
}

class  Permission {

    enum class PermissionResult {
        ACCESS_ALLOWED, ACCESS_DENIED, NO_SYSTEM_FEATURE;
    }

    interface ManagerDelegate {
        fun permissionManagerDelegate(result: Array<Pair<String, PermissionResult>>)
    }

    class Manager internal constructor(private val delegate: ManagerDelegate?) {

        private var context: Context? = null
        private var fragment: Fragment? = null
        private var activity: AppCompatActivity? = null
        private var permissionTypes: Array<PermissionType> = arrayOf()
        private val REQUEST_CODE = 999
        private val semaphore = Semaphore(1, true)
        private var result: Array<Pair<String, PermissionResult>> = arrayOf()


        constructor(permissionType: PermissionType, delegate: ManagerDelegate?): this(delegate) {
            permissionTypes = arrayOf(permissionType)
        }

        constructor(permissionTypes: Array<PermissionType>, delegate: ManagerDelegate?): this(delegate) {
            this.permissionTypes = permissionTypes
        }

        init {
            when (delegate) {
                is Fragment -> {
                    this.fragment = delegate
                    this.context = delegate.context
                }

                is AppCompatActivity -> {
                    this.activity = delegate
                    this.context = delegate
                }
            }
        }

        private fun hasSystemFeature(permissionType: PermissionType) : Boolean {
            return context?.packageManager?.hasSystemFeature(permissionType.packageManager) ?: false
        }

        private fun hasAccess(permissionType: PermissionType) : Boolean {
            return if (Build.VERSION.SDK_INT < 23) true else {
                context?.checkSelfPermission(permissionType.manifest_permission) == PackageManager.PERMISSION_GRANTED
            }
        }

        private fun sendRequest(permissionTypes: Array<String>) {

            if (fragment != null) {
                fragment?.requestPermissions(permissionTypes, REQUEST_CODE)
                return
            }

            if (activity != null){
                ActivityCompat.requestPermissions(activity!!, permissionTypes, REQUEST_CODE)
            }
        }

        fun check() {

            semaphore.acquire()
            AsyncTask.execute {
                var permissionsForSendingRequest: Array<String> = arrayOf()
                this.result = arrayOf()

                for (it in permissionTypes) {
                    if (!hasSystemFeature(it)) {
                        result += Pair(it.manifest_permission, PermissionResult.NO_SYSTEM_FEATURE)
                        continue
                    }

                    if (hasAccess(it)) {
                        result += Pair(it.manifest_permission, PermissionResult.ACCESS_ALLOWED)
                    } else {
                        permissionsForSendingRequest += it.manifest_permission
                    }
                }

                if (permissionsForSendingRequest.isNotEmpty()) {
                    sendRequest(permissionsForSendingRequest)
                } else {
                    delegate?.permissionManagerDelegate(result)
                }
            }
        }

        fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
            when (requestCode) {
                REQUEST_CODE -> {
                    if (grantResults.isEmpty()) {
                        return
                    }
                    for ((i,permission) in permissions.withIndex()) {
                        for (item in this.permissionTypes) {
                            if (permission == item.manifest_permission && i < grantResults.size) {
                                result += if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                                    Pair(item.manifest_permission, PermissionResult.ACCESS_ALLOWED)
                                } else {
                                    Pair(item.manifest_permission, PermissionResult.ACCESS_DENIED)
                                }
                                break
                            }
                        }
                    }
                    delegate?.permissionManagerDelegate(result)
                }
            }
            semaphore.release()
        }
    }
}

Utilisation dans L'activité (dans le fragment le même)

class BaseActivity : AppCompatActivity(), Permission.ManagerDelegate {

    private lateinit var permissionManager: Permission.Manager

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

        permissionManager = Permission.Manager(arrayOf(PermissionType.Defined.camera, PermissionType.Defined.currentLocation), this)
        permissionManager.check()
    }

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


    override fun permissionManagerDelegate(result: Array<Pair<String, Permission.PermissionResult>>) {
        result.forEach {
            println("!!! ${it.first} ${it.second}")
//            when (it.second) {
//                Permission.PermissionResult.NO_SYSTEM_FEATURE -> {
//                }
//
//                Permission.PermissionResult.ACCESS_DENIED  -> {
//                }
//
//                Permission.PermissionResult.ACCESS_ALLOWED -> {
//                }
//            }
        }
    }
}
0
répondu Vasily Bodnarchuk 2018-09-16 22:40:58

J'ai eu un problème similaire accepter que j'appuyais sur le bouton pour faire un appel, ce qui déclenche le callIntent. J'ai d'abord vérifié l'autorisation, si non accordée, je demande l'autorisation et onRequestPermissionResult j'appelle l'autorisation de vérification et appelle à nouveau.

 @Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case Constants.PERMISSIONS_REQUEST_CALL_PHONE: {
            if ( grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                checkPermissionsAndCall();
            }
        }
    }
}

public void checkPermissionsAndCall(){
    if (Build.VERSION.SDK_INT > 22) {
        if(ContextCompat.checkSelfPermission(getContext(),
                Manifest.permission.CALL_PHONE)
                != PackageManager.PERMISSION_GRANTED){
            requestPermissions( new String[]{Manifest.permission.CALL_PHONE}, Constants.PERMISSIONS_REQUEST_CALL_PHONE);
        }
        else{
            callIntent();
        }
    }
}
0
répondu ndheti 2018-09-30 00:57:12