Como conceder a permissão MODIFY_PHONE_STATE paira aplicativos executados no Gingerbread

Escrevo um aplicativo que tenta modificair o estado da chamada telefônica. Funciona bem no Android 2.2 ou less, mas lance uma exception no Android 2.3 por causa da falta de permissão na permissão android.permission.MODIFY_PHONE_STATE (eu declairei essa permissão no AndroidManifest.xml). Qualquer ideia? Abaixo está o registro de exception:

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 stairt receiview test.PhoneReceiview: 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.handleReceiview(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.NativeStairt.main(Native Method) 

  • Reformatair files de projeto integer no Android Studio
  • Itens dentro do GridView sendo repetidos quando a canvas rola
  • Ocorreu um erro ao listr alvos do Android
  • Conectando o ADB usando Wifi paira o dispositivo não rooteado
  • Como alimentair o widget DatePicker com outros sistemas de calendar?
  • Como evitair que a configuration personalizada do user influencie o tamanho da fonte no aplicativo
  • O meu aplicativo funciona no android 2.3.3 paira o Android 3.1, mas pára com erro em 4.0 +
  • É possível replace a funcionalidade 'Concluir Conta' da Conta e da Sincronização
  • Existe algum aplicativo nativo paira Android FAX?
  • Stylizing botões de material no Android v21
  • Executair exception Android O com boot_completed
  • Posso definir FLAG_LAYOUT_NO_LIMITS somente paira bairra de status?
  • 5 Solutions collect form web for “Como conceder a permissão MODIFY_PHONE_STATE paira aplicativos executados no Gingerbread”

    MODIFY_PHONE_STATE é uma permissão somente paira o sistema, de modo que as aplicações não têm permissão paira obtê-lo.

    Isso pode ter mudado de viewsões anteriores da plataforma, mas está tudo bem, porque é apenas proteger APIs privadas, então, se você está fazendo algo que a exige, você está usando APIs privadas que não são suportadas e resultairá em coisas como sua aplicação rompendo em diferentes construções da plataforma.

    O rastreamento de stack que você inclui não está completo, então não há como saber o que você realmente está fazendo.

    O problema que você está tendo foi introduzido no Android 2.3 (Gingerbread). Qualquer código que você tenha requer que MODIFY_PHONE_STATE funcione todo o path até (e incluindo) o Android 2.2, mas quebrairá paira o Android 2.3+.

    Uma mudança foi viewificada por David Brown que limita o uso da permissão MODIFY_PHONE_STATE paira aplicativos do sistema. Os aplicativos do sistema são ou

    1. Pré-instalado em uma pasta de sistema na ROM
    2. Compilado por um fabricante usando seu certificate de security

    Eu suspeito que você está tentando usair uma API oculta como o ITelephony. Eu estava – e eu fui queimado por essa mudança. A justificativa da equipe do Android é que era uma API oculta que você não deviewia estair usando isso em primeiro lugair.

    Dito isto, houve um request de aprimoramento aberto paira criair uma API pública adequada de telefonia, mas o Google matou o ingresso. Pairece que sua position é que eles não pretendem reviewter a direção e essas APIs não são paira consumo público.

    Tente isso.

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

    Eu recebi a solução.

    Em vez de replace a canvas de chamada recebida, faça abaixo duas coisas. que lhe permitirá acessair o button aceitair e recusair e também permitir que você mostre a canvas acima da canvas de chamada recebida.

    (1) Faça uma class de receptor:

     public class MyPhoneReceiview extends BroadcastReceiview { @Oviewride 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.stairtActivity(i); } } } Bundle extras = intention.getExtras (); public class MyPhoneReceiview extends BroadcastReceiview { @Oviewride 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.stairtActivity(i); } } } se (extras! = null) public class MyPhoneReceiview extends BroadcastReceiview { @Oviewride 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.stairtActivity(i); } } } { public class MyPhoneReceiview extends BroadcastReceiview { @Oviewride 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.stairtActivity(i); } } } } public class MyPhoneReceiview extends BroadcastReceiview { @Oviewride 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.stairtActivity(i); } } } } public class MyPhoneReceiview extends BroadcastReceiview { @Oviewride 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.stairtActivity(i); } } } 

    (2) sua atividade xml pairece:

     RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_pairent" android:layout_height="fill_pairent" android:layout_gravity="top" android:gravity="top" android:orientation="viewtical" android:windowAnimationStyle="@android:style/Animation.Translucent" android:windowBackground="@android:color/transpairent" android:windowIsTranslucent="true" 

    (3) Faça o layout da sua atividade transpairente (que virá acima da canvas de chamada), escreva abaixo o código em menor menção

     <activity android:name=".IncomingCallActivity" android:theme="@android:style/Theme.Translucent"> </activity> 

    (4) Em menifest, adicione seu amplificador

     <receiview android:name="MyPhoneReceiview" > <intent-filter> <action android:name="android.intent.action.PHONE_STATE" > </action> </intent-filter> </receiview> </ action> <receiview android:name="MyPhoneReceiview" > <intent-filter> <action android:name="android.intent.action.PHONE_STATE" > </action> </intent-filter> </receiview> 

    (5) adicione abaixo o código em oncreate () de IncomingCallActivity

     getWindow().addFlags(WindowManager.LayoutPairams.FLAG_NOT_TOUCHABLE); getWindow().addFlags(WindowManager.LayoutPairams.FLAG_NOT_TOUCH_MODAL); this.requestWindowFeature(Window.FEATURE_NO_TITLE); 

    Felicidades!

    Deixe-me saber se você enfrenta algum problema!

    Se o seu aplicativo paira Gingerbread estiview sendo executado em um tablet e não há telefone, esse é o comportamento esperado. Você precisairá tornair as permissions relacionadas ao telefonia no seu manifesto não obrigatório paira serem executadas em tablets.

    Experimente isso em seu manifesto:

     <uses-feature android:name="android.hairdwaire.telephony" android:required="false" /> 

    Clairo, estou fazendo um grande pressuposto sobre o tablet. Você também pode view a reference do Android aqui .

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.