Широковещательные приемники не работают в Android 6.0 Marshmallow

Я только что обновил свой Nexus 5 до android 6, до сих пор мое приложение работало нормально, но теперь широковещательные приемники не работают. Что-то изменилось в новой версии? Вот код, который я пробовал, который работал над предыдущими версиями, но не в зефире –

Android Manifest

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

Широковещательный приемник

 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..."); } } 

обслуживание

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

Точно так же приемник вещания для PHONE_STATE также не работает.

Solutions Collecting From Web of "Широковещательные приемники не работают в Android 6.0 Marshmallow"

Целевой уровень API вашего приложения – 23, то есть android M (6.0). В android M есть огромные изменения, связанные с правами пользователя. Вот хорошая статья, объясняющая изменения.

Как указано в Android – Запрос разрешений

Начиная с Android 6.0 (API-уровень 23), пользователи предоставляют разрешения для приложений во время работы приложения, а не при установке приложения … Пользователь может в любое время отменить разрешения …

Также говорится, что:

Системные разрешения делятся на две категории: нормальные и опасные:

  1. Обычные разрешения напрямую не влияют на конфиденциальность пользователя. Если ваше приложение отображает нормальное разрешение в своем манифесте, система автоматически предоставляет разрешение

  2. Опасные разрешения могут предоставить приложению доступ к конфиденциальным данным пользователя. Если вы указываете опасное разрешение, пользователь должен явно разрешить ваше приложение

Вот полные списки опасных разрешений и нормальных разрешений

Все это в основном означает, что вам необходимо вручную запросить любое опасное разрешение, когда оно действительно необходимо.

Поскольку это потенциально может потребоваться несколько раз в вашем коде, вы можете создать метод многократного использования, который проверяет, предоставлено ли уже определенное разрешение, а если нет – запрашивать его у пользователя.

Вот пример:

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

Пример использования:

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

Заметка:

  1. Если вам нужно использовать PermissionManager.check внутри экземпляра Fragment , в качестве первого параметра используйте: getActivity() .

  2. Вы можете использовать checkSelfPermission внутри экземпляра Service , чтобы проверить, предоставлено ли какое-либо разрешение уже, но не requestPermissions чтобы запросить его. Поскольку checkSelfPermission может использоваться для любого Context , но requestPermissions только для Activity

Зефир блокирует опасные разрешения.

Это не относится к указанному сценарию, но может помочь кому-то другому. Я все время приходил к этому, потому что некоторые из наших вещательных приемников не работали. У нас есть настраиваемая настройка разрешений и имеет android:protectionLevel="dangerous" . Изменил его на android:protectionLevel= "signature" и все начало работать.