java write Android M Permissions: onRequestPermissionsResult() n'étant pas appelé




uses permission android name android permission write (16)

Je met à jour notre application pour utiliser le nouveau système d'autorisations M. Tout fonctionne en dehors de onRequestPermissionsResult (). J'ai besoin de vérifier une permission sur un bouton, et si c'est réussi, envoyer un message texte. Lorsque j'accorde la permission de le faire, la boîte de dialogue se ferme, mais le texte envoyé ne se déclenche que lorsque j'appuie de 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 s'appelle d'abord:

    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 at-il rencontré un problème similaire? Apprécier toute aide avec cela. Merci

https://code.i-harness.com


Détails

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

Algorithme

module - caméra, emplacement, ....

  1. Vérifiez si hasSystemFeature (si le module existe dans le téléphone)
  2. Vérifier si l'utilisateur a accès au module
  3. Envoyer une demande d'autorisation (demander à l'utilisateur d'autoriser l'utilisation du module )

Caractéristiques

  1. Travailler avec des activités et des fragments
  2. N'a qu'une réponse de résultat
  3. Peut vérifier plusieurs modules en une seule demande

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 en activité (dans le même fragment)

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 -> {
//                }
//            }
        }
    }
}

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

vérifiez le code de onRequestPermissionsResult () dans FragmentActivity.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);
        }
    }
}

Cela fonctionnera ..

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

D' après la réponse de goodgamerguy, la solution est la suivante:

myFragment.this.requestPermissions(....)

Ici, je veux montrer à mon code comment j'ai géré cela.

public class CheckPermission {

public Context context;

public static final int PERMISSION_REQUEST_CODE =  200;

public CheckPermission(Context context){
    this.context = context;
}

public boolean isPermissionGranted(){
    int read_contact = ContextCompat.checkSelfPermission(context.getApplicationContext() , READ_CONTACTS);
    int phone = ContextCompat.checkSelfPermission(context.getApplicationContext() , CALL_PHONE);

    return read_contact == PackageManager.PERMISSION_GRANTED && phone == PackageManager.PERMISSION_GRANTED;
   }
}

Ici, dans cette classe, je veux vérifier l'autorisation accordée ou non. N’est-ce pas alors que je vais appeler la permission de mon MainActivity

public void requestForPermission() {
       ActivityCompat.requestPermissions(MainActivity.this, new String[]    {READ_CONTACTS, CALL_PHONE}, PERMISSION_REQUEST_CODE);
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case PERMISSION_REQUEST_CODE:
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (shouldShowRequestPermissionRationale(ACCESS_FINE_LOCATION)) {
                    showMessageOKCancel("You need to allow access to both the permissions",
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                        requestPermissions(new String[]{Manifest.permission.READ_CONTACTS, Manifest.permission.CALL_PHONE},
                                                PERMISSION_REQUEST_CODE);
                                    }
                                }
                            });
                    return;
                }
            }
    }
}

Maintenant, dans la méthode onCreate, vous devez appeler la fonction requestForPermission ().

C'est ça.Vous pouvez également demander plusieurs autorisations à la fois.


J'ai découvert qu'il est important d' android.support.v4.app.Fragment.requestPermissions .

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

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);

}

J'ai rencontré ce problème aussi. Si vous souhaitez que l'activité qui gère les autorisations ne figure pas dans l'historique / les modifications récentes, vous serez tenté de modifier 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"

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

Vous pouvez résoudre ce problème en supprimant les deux indicateurs de 'AndroidManifest.xml' et en terminant votre activité avec finishAndRemoveTask() .


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:

  • Dans AppCompatActivity , vous devez utiliser ActivityCompat.requestPermissions ;
  • Lorsque vous êtes dans android.support.v4.app.Fragment , vous devez simplement utiliser requestPermissions (il s'agit d'une méthode d'instance d'android.support.v4.app.Fragment).

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

J'espère que cela t'aides!


J'espère que ça fonctionne bien

Pour l'activité:

 ActivityCompat.requestPermissions(this,permissionsList,REQUEST_CODE);

Pour le fragment:

 requestPermissions(permissionsList,REQUEST_CODE);

Si vous appelez ce code depuis un fragment, il a sa propre méthode requestPermissions.

Donc, le concept de base est, si vous êtes dans une activité, alors appelez

ActivityCompat.requestPermissions(this,
                            permissionsList,
                            permissionscode);

et si dans un fragment, il suffit d'appeler

requestPermissions(permissionsList,
                            permissionscode);

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

Vous devez utiliser requestPermissions(permissions, PERMISSIONS_CODE);


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 devez appeler manuellement le fragment super.onRequestPermissionsResultez-vous 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);
    }
...

Vous pouvez essayer ceci:

requestPermissions(permissions, PERMISSIONS_CODE);

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

Conseil professionnel si vous souhaitez que la fonction onRequestPermissionsResult() dans un fragment: FragmentCompat.requestPermissions(Fragment fragment, String[] permissions, int requestCode)


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


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();
    }
}

 /* 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);




android-permissions