Riffing on @ ответ SuperNova , вот подход с использованием классов ES6, который поддерживает контекст для , этот
правильный в вашем обратном вызове:
класс Мышь {constructor () {this.x = 0; this.y = 0; this.callbacks = {mouseenter: [], mousemove: [],}; } get xPos () {return this.x; } get yPos () {return this.y; } get position () {return `$ {this.x}, $ {this.y}`; } addListener (type, callback) {document.addEventListener (type, this); // Передаем `this`, как второй arg, чтобы сохранить контекст правильно this.callbacks [type] .push (callback); } // `handleEvent` является частью API-интерфейса браузера EventListener. // https://developer.mozilla.org/en-US/docs/Web/API/EventListener/handleEvent handleEvent (event) {const isMousemove = event.type === 'mousemove'; const isMouseenter = event.type === 'mouseenter'; if (isMousemove || isMouseenter) {this.x = event.pageX; this.y = event.pageY; } this.callbacks [event.type] .forEach ((callback) = & gt; {callback ();}); }} const mouse = new Mouse (); mouse.addListener ('mouseenter', () = & gt; console.log ('mouseenter', mouse.position)); mouse.addListener ('mousemove', () = & gt; console.log ('mousemove A', mouse.position)); mouse.addListener ('mousemove', () = & gt; console.log ('mousemove B', mouse.position));
MODIFY_PHONE_STATE - это системное разрешение, поэтому приложениям не разрешено его получать.
Возможно, это изменилось с предыдущих версий платформы, но это нормально, потому что он защищает только частные API, поэтому, если вы делаете что-то, что требует этого, вы используете закрытые API, которые не поддерживаются, и это приведет к тому, что ваши приложения будут разбиты на разные сборки платформы.
Сканирование стека, которое вы включили, не завершено , поэтому нет способа рассказать, что вы на самом деле делаете.
Я получил решение.
Скорее, чтобы переопределить экран входящих вызовов, сделайте ниже двух вещей. который позволит вам получить доступ к кнопке «Принять и отклонить», а также отобразить экран над экраном вашего входящего вызова.
(1) Сделать один класс приемника:
public class MyPhoneReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, final Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null)
{
String state = extras.getString(TelephonyManager.EXTRA_STATE);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING))
String phoneNumber = extras.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
Intent i = new Intent(context, IncomingCallActivity.class);
i.putExtras(intent);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
}
(2 ) ваша активность xml выглядит следующим образом:
RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="top"
android:gravity="top"
android:orientation="vertical"
android:windowAnimationStyle="@android:style/Animation.Translucent"
android:windowBackground="@android:color/transparent"
android:windowIsTranslucent="true"
(3) Сделайте прозрачность макета вашей деятельности (которая выйдет выше экрана вызова), напишите ниже код в манифесте
<activity android:name=".IncomingCallActivity"
android:theme="@android:style/Theme.Translucent">
</activity>
( 4) В манифесте добавьте свой широколистный приемник
<receiver android:name="MyPhoneReceiver" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" >
</action>
</intent-filter>
</receiver>
(5), добавьте ниже код в oncreate () из IncomingCallActivity
getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
Приветствия!
Дайте мне знать, если вы столкнулись с какой-либо проблемой!
Если ваше приложение для Gingerbread работает на планшете, и нет телефона, то это ожидаемое поведение. Вам нужно будет сделать разрешения, связанные с телефонией, в вашем манифесте не обязательным для работы на планшетах.
Попробуйте это в своем манифесте:
<uses-feature android:name="android.hardware.telephony"
android:required="false" />
Конечно, я делая большое предположение о планшете. Вы также можете увидеть ссылку на Android здесь .
Проблема, с которой вы столкнулись, была представлена в Android 2.3 (Gingerbread). Любой код, который вам нужен, который требует MODIFY_PHONE_STATE, будет работать вплоть до (и в том числе) Android 2.2, но будет разорван на Android 2.3 +.
Изменено в Дэвидом Браун ограничивает использование разрешения MODIFY_PHONE_STATE для системных приложений. Системные приложения либо
Я подозреваю, что вы пытаетесь использовать скрытый API, такой как ITelephony. Я был ... и меня сожгли это изменение. Обоснование команды Android состоит в том, что это был скрытый API, который вы не должны использовать в первую очередь.
Тем не менее, был открыт запрос расширения для создания надлежащего общедоступного API телефонии, но Google убил билет. Похоже, их позиция заключается в том, что они не намерены менять направление, и эти API не предназначены для общественного потребления.
Попробуйте это.
public static void answerPhoneHeadsethook(Context context) {
// Simulate a press of the headset button to pick up the call
// SettingsClass.logMe(tag, "Simulating headset button");
Intent buttonDown = new Intent(Intent.ACTION_MEDIA_BUTTON);
buttonDown.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK));
context.sendOrderedBroadcast(buttonDown, "android.permission.CALL_PRIVILEGED");
// froyo and beyond trigger on buttonUp instead of buttonDown
Intent buttonUp = new Intent(Intent.ACTION_MEDIA_BUTTON);
buttonUp.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));
context.sendOrderedBroadcast(buttonUp, "android.permission.CALL_PRIVILEGED");
}