web-dev-qa-db-fra.com

Les récepteurs de diffusion ne fonctionnent pas dans Android 6.0 Marshmallow

Je viens de mettre à jour mon Nexus 5 vers Android 6, jusqu'à présent mon application fonctionnait bien, mais maintenant les récepteurs de diffusion ne fonctionnent pas. Quelque chose a changé dans la nouvelle version? Voici le code que j'ai essayé qui fonctionnait sur les versions précédentes mais pas dans Marshmallow -

Manifeste Android

    <intent-filter >
        <action Android:name="Android.provider.Telephony.SMS_RECEIVED"/>
    </intent-filter>
<uses-permission Android:name="Android.permission.RECEIVE_SMS"></uses-permission>
<uses-permission Android:name="Android.permission.READ_SMS" ></uses-permission>

récepteur de diffusion

public String TAG ="someClass";
private static String ACTION_SMS_RECEIVED = "Android.provider.Telephony.SMS_RECEIVED";
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    if (action.equalsIgnoreCase(ACTION_SMS_RECEIVED)) {
        Log.d(TAG, "Received...");
    }
}

Service

Broadcast_receiver broadcast_receiver = new Broadcast_receiver();
IntentFilter filter1 = new IntentFilter();
filter1.addAction("Android.provider.Telephony.SMS_RECEIVED");
registerReceiver(broadcast_receiver, filter1);

De même, le récepteur de diffusion pour PHONE_STATE ne fonctionne pas non plus.

13
Imdad

Le niveau d'API cible de votre application est de 23, soit Android M (6.0). Dans Android M, il y a d'énormes changements liés aux autorisations utilisateur. Ici est un bel article expliquant les changements.

16
Artur Szymański

Comme indiqué dans Android - Demande d'autorisations

À partir de Android 6.0 (API niveau 23), les utilisateurs accordent des autorisations aux applications pendant que l'application est en cours d'exécution, pas lorsqu'ils installent l'application ... L'utilisateur peut révoquer les autorisations à tout moment .. .

Il est également indiqué que:

Les autorisations système sont divisées en deux catégories, normales et dangereuses:

  1. Les autorisations normales ne compromettent pas directement la confidentialité de l'utilisateur. Si votre application répertorie une autorisation normale dans son manifeste, le système accorde automatiquement l'autorisation

  2. Des autorisations dangereuses peuvent donner à l'application accès aux données confidentielles de l'utilisateur. Si vous indiquez une autorisation dangereuse, l'utilisateur doit explicitement approuver votre application

Voici la liste complète des autorisations dangereuses et autorisations normales

Tout cela signifie essentiellement que vous devez demander manuellement une autorisation dangereuse, lorsqu'elle est réellement nécessaire.

Puisqu'il peut potentiellement être nécessaire plusieurs fois dans votre code, vous pouvez créer une méthode réutilisable qui vérifie si une autorisation spécifique est déjà accordée et si elle ne l'est pas - pour la demander à l'utilisateur.

Voici un exemple:

Java

public class PermissionManager {
    //A method that can be called from any Activity, to check for specific permission
    public static void check(Activity activity, String permission, int requestCode){
        //If requested permission isn't Granted yet 
        if (ActivityCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
            //Request permission from user
            ActivityCompat.requestPermissions(activity,new String[]{permission},requestCode);
        }
    }
}

Kotlin

object PermissionManager {
    //A method that can be called from any Activity, to check for specific permission
    fun check(activity: Activity, permission: String, requestCode: Int) {
        //If requested permission isn't Granted yet
        if (ActivityCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
            //Request permission from user
            ActivityCompat.requestPermissions(activity, arrayOf(permission), requestCode)
        }
    }
}

Usage:

Java

//Inside your activity:
//1. Define static constant for each permission request
public static final int REQUEST_CODE_FOR_SMS=1;
//2. When needed (for example inside .onStart event) use method PermissionManager.check for requested permission 
@Override
protected void onStart() {
    super.onStart();
    PermissionManager.check(this, Manifest.permission.RECEIVE_SMS, REQUEST_CODE_FOR_SMS);
}
//3. Handle User's response for your permission request
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    if(requestCode==REQUEST_CODE_FOR_SMS){//response for SMS permission request
        if(grantResults[0]==PackageManager.PERMISSION_GRANTED){
            //What to do if User allowed SMS permission
        }else{
            //What to do if user disallowed requested SMS permission
        }
    }
}

Kotlin

//Inside your activity:
//1. Define static constant for each permission request
val REQUEST_CODE_FOR_SMS = 1
//2. When needed (for example inside .onStart event) use method PermissionManager.check for requested permission
override fun onStart() {
    super.onStart()
    PermissionManager.check(this, Manifest.permission.RECEIVE_SMS, REQUEST_CODE_FOR_SMS)
}

//3. Handle User's response for your permission request
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
    if (requestCode == REQUEST_CODE_FOR_SMS) {//response for SMS permission request
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            //What to do if User allowed SMS permission
        } else {
            //What to do if user disallowed requested SMS permission
        }
    }
}

Remarque:

  1. Si vous devez utiliser PermissionManager.check À l'intérieur de l'instance Fragment , utilisez: getActivity() comme premier paramètre.

  2. Vous pouvez utiliser checkSelfPermission à l'intérieur de l'instance Service , pour vérifier si une autorisation est déjà accordée, mais pas requestPermissions pour le demander. Parce que checkSelfPermission peut être utilisé pour n'importe quel Context, mais requestPermissions uniquement pour Activity

10
Nikita Kurtin

Marshmallow bloque les autorisations dangereuses.

Cela ne s'applique pas au scénario répertorié, mais cela pourrait aider quelqu'un d'autre. Je n'arrêtais pas d'y arriver SO pour savoir pourquoi certains de nos récepteurs de diffusion ne fonctionnaient pas. Nous avons une configuration d'autorisation personnalisée et avions le Android:protectionLevel="dangerous". Changé en Android:protectionLevel= "signature"et tout a commencé à fonctionner.

3
FinHead