Отказ в разрешении на прием - PullRequest
0 голосов
/ 10 июня 2019

Я работаю над приложением, в котором мне нужно запустить виджет, когда телефон находится в состоянии вызова.

Я зарегистрировался для запроса широковещательной передачи в манифесте следующим образом:

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
...Other permissions required for screen overlay...

Iзарегистрировал мой широковещательный приемник в манифесте следующим образом:

    <receiver android:name=".phoneReceiver"
        android:exported="true"
        android:enabled="false">
        <intent-filter>
            <action android:name="android.intent.action.PHONE_STATE"/>
        </intent-filter>
    </receiver>

Примечание. Я включаю приемник во время выполнения, когда пользователь нажимает кнопку.Это также время, когда я запрашиваю перми, поскольку моя тестовая система работает под управлением Android 7.0

Затем я запрашиваю разрешения во время выполнения при нажатии кнопки как таковой:

    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_PHONE_STATE)
                    != PackageManager.PERMISSION_GRANTED){
                ActivityCompat.requestPermissions(MainActivity.this,
                        new String[]{Manifest.permission.READ_PHONE_STATE}, 2);
                showToast(getApplicationContext(), "Phone state requested");
            } else{
                enableWidget();    //if permissions are already granted
            }
        }
    });

Я жду результата запроса на разрешение как такового:

@Override
public void onRequestPermissionsResult(int req, @NonNull String[] perms, @NonNull int[] results){
    switch(req){
        case 2:
            if(results.length > 0 && results[0]==PackageManager.PERMISSION_GRANTED){
                showToast(this, "Phone state granted");
                enableWidget();
            }
            return;
    }
}

В enableWidget() я включаю широковещательный приемник как таковой:

private void enableWidget(){
    PackageManager pm = MainActivity.this.getPackageManager();
    ComponentName comp = new ComponentName(getApplicationContext(), phoneReceiver.class);
    pm.setComponentEnabledSetting(comp, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);
} 

Теперь согласнодля меня получатель должен вызываться всякий раз, когда состояние изменяется, но этого не происходит.Вместо этого я получаю следующее в logcat, что заставляет меня думать, что приемник включен, но все еще не вызывается.

W/BroadcastQueue: Permission Denial: receiving Intent { act=android.intent.action.PHONE_STATE flg=0x10 (has extras) } to com.example.myapplication/.phoneReceiver requires android.permission.READ_PRIVILEGED_PHONE_STATE due to sender android (uid 1000)

Что мне здесь не хватает?


PS Вот фрагмент моего Приемника за вычетом ненужных вещей:

public class phoneReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            if(ContextCompat.checkSelfPermission(context, Manifest.permission.SYSTEM_ALERT_WINDOW)
                != PackageManager.PERMISSION_GRANTED)
                return;
            if(ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE)
                != PackageManager.PERMISSION_GRANTED)
                return;
        }
        if(intent.getStringExtra(TelephonyManager.EXTRA_STATE)
            .equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
            showToast(context, "In call");
            startWidget(context);
        } else if(intent.getStringExtra(TelephonyManager.EXTRA_STATE)
            .equals(TelephonyManager.EXTRA_STATE_IDLE)){
            showToast(context, "Out of call");
            stopWidget(context);
        }
    }
    ...Definitions of showToast, start, stopWidget...
}

PPS Я проверил разрешения приложения в системных настройках и включил "телефон".


Я попытался оставить Receiver включенным по умолчанию, объявив его вМанифест как:

android:enabled="true"

и удаление раздела для включения виджета во время выполнения.Я все еще спрашиваю разрешения во время выполнения.Тем не менее, я получаю ту же ошибку.

Та же система, работающая на уровне API 22.

Ответы [ 2 ]

1 голос
/ 10 июня 2019

Получатели, объявленные манифестом: Если ваше приложение предназначено для уровня API 26 или выше, вы не можете использовать манифест для объявления получателя для неявных широковещательных рассылок (широковещательных рассылок, которые не нацелены на ваше приложениев частности), за исключением нескольких скрытых передач, которые освобождены от этого ограничения Список исключений .В большинстве случаев вы можете использовать запланированные задания вместо.

Приемники, зарегистрированные в контексте: Получать широковещательные сообщения, если их контекст регистрации действителен.Например, если вы регистрируетесь в контексте действия, вы получаете широковещательные сообщения до тех пор, пока действие не будет уничтожено.Если вы регистрируетесь в контексте приложения, вы получаете широковещательные сообщения, пока приложение работает.

Из-за улучшения памяти проверьте официальный сайт для получения дополнительной информации.

0 голосов
/ 10 июня 2019

Вы можете использовать API JobScheduler для запуска событий, я сталкивался с похожими проблемами ранее, когда работал с API геозон для одного из моих приложений

...