Ответ 1
Уровень API для вашего целевого API - 23, то есть android M (6.0). В android M есть огромные изменения, связанные с правами пользователя. Здесь - хорошая статья, объясняющая изменения.
Я только что обновил свой Nexus 5 до android 6, до сих пор мое приложение работало нормально, но теперь широковещательные приемники не работают. Что-то изменилось в новой версии? Вот код, который я пробовал, который работал над предыдущими версиями, но не в зефире -
Манифест 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>
широковещательный приемник
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 для вашего целевого API - 23, то есть android M (6.0). В android M есть огромные изменения, связанные с правами пользователя. Здесь - хорошая статья, объясняющая изменения.
Как указано в Android - Запрос разрешений
Начиная с Android 6.0 (уровень API 23), пользователи предоставляют разрешения для приложений во время работы приложения, а не при установке приложения... Пользователь может в любое время отменить разрешения...
Он также заявил, что:
Системные разрешения делятся на две категории: нормальные и опасные:
Обычные разрешения напрямую не угрожают конфиденциальности пользователей. Если ваше приложение отображает нормальное разрешение в своем манифесте, система автоматически предоставляет разрешение
Опасные разрешения могут предоставить приложению доступ к конфиденциальных данных. Если вы перечислите опасное разрешение, пользователь должен явно дать разрешение на ваше приложение
Вот полные списки Опасные разрешения и Нормальные разрешения
Все это в основном означает, что вам необходимо вручную запросить любое опасное разрешение, когда оно действительно необходимо.
Так как он потенциально может понадобиться несколько раз в вашем коде, вы можете создать метод повторного использования, который проверяет, предоставлено ли уже определенное разрешение, а если нет - запрашивать его у пользователя.
Вот пример:
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 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
}
}
}
Примечание:
Если вам нужно использовать PermissionManager.check
внутри Fragment
, используйте в качестве его первого параметра: getActivity()
.
Вы можете использовать checkSelfPermission
внутри Service
экземпляр, чтобы проверить, разрешение уже предоставлено, но не requestPermissions
, чтобы запросить его. Поскольку checkSelfPermission
может использоваться для любого Context
, но requestPermissions
только для Activity
Зефир блокирует опасные разрешения.
Это не относится к указанному сценарию, но может помочь кому-то другому. Я все время приходил к этому, потому что некоторые из наших вещательных приемников не работали. У нас есть настраиваемая настройка разрешений и android:protectionLevel="dangerous"
. Изменено на android:protectionLevel= "signature"
, и все началось.