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

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

Android Manifest

     

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

 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 также не работает.

    Целевой уровень 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); } } } 

    Котлин

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

    Применение:

    Ява

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

    Котлин

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

    Заметка:

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

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

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

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

    Давайте будем гением компьютера.