電話の状態を変更しようとするアプリケーションを作成します。 Android 2.2以下で動作しますが、Android.permission.MODIFY_PHONE_STATE権限の許可がないため、Android 2.3で例外をスローします(私は宣言しましたAndroidManifest.xmlでのこのアクセス許可)何か考えがありますか?以下は例外ログです:
01-15 09:14:23.210: ERROR/AndroidRuntime(404): FATAL EXCEPTION: main
01-15 09:14:23.210: ERROR/AndroidRuntime(404): Java.lang.RuntimeException: Unable to start receiver test.PhoneReceiver: Java.lang.SecurityException: Neither user 10031 nor current process has Android.permission.MODIFY_PHONE_STATE.
01-15 09:14:23.210: ERROR/AndroidRuntime(404): at Android.app.ActivityThread.handleReceiver(ActivityThread.Java:1780)
01-15 09:14:23.210: ERROR/AndroidRuntime(404): at Android.app.ActivityThread.access$2400(ActivityThread.Java:117)
01-15 09:14:23.210: ERROR/AndroidRuntime(404): at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:978)
01-15 09:14:23.210: ERROR/AndroidRuntime(404): at Android.os.Handler.dispatchMessage(Handler.Java:99)
01-15 09:14:23.210: ERROR/AndroidRuntime(404): at Android.os.Looper.loop(Looper.Java:123)
01-15 09:14:23.210: ERROR/AndroidRuntime(404): at Android.app.ActivityThread.main(ActivityThread.Java:3647)
01-15 09:14:23.210: ERROR/AndroidRuntime(404): at Java.lang.reflect.Method.invokeNative(Native Method)
01-15 09:14:23.210: ERROR/AndroidRuntime(404): at Java.lang.reflect.Method.invoke(Method.Java:507)
01-15 09:14:23.210: ERROR/AndroidRuntime(404): at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:839)
01-15 09:14:23.210: ERROR/AndroidRuntime(404): at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:597)
01-15 09:14:23.210: ERROR/AndroidRuntime(404): at dalvik.system.NativeStart.main(Native Method)
MODIFY_PHONE_STATEはシステムのみの権限であるため、アプリは取得できません。
これはプラットフォームの以前のバージョンから変更された可能性がありますが、プライベートAPIのみを保護しているため、問題ありませんプラットフォームのさまざまなビルドを壊します。
含めたスタッククロールは完全ではないため、実際に何をしているかを知る方法はありません。
あなたが抱えている問題はAndroid 2.3(Gingerbread)で導入されました。 MODIFY_PHONE_STATEを必要とするコードは、Android 2.2までは動作しますが、Android 2.3+では機能しなくなります。
変更がチェックインされました David Brownにより、MODIFY_PHONE_STATE権限の使用をシステムアプリに制限します。システムアプリは
ITelephonyのような隠されたAPIを使用しようとしているのではないでしょうか。私はそうでした-そして、私はこの変化によって燃えました。 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");
}
私は解決策を得た。
着信画面をオーバーライドするには、次の2つのことを行います。これにより、承諾ボタンと拒否ボタンにアクセスしたり、着信画面の上に画面を表示したりできます。
(1)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)IncomingCallActivityのoncreate()に以下のコードを追加します
getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
乾杯!
問題が発生した場合はお知らせください!