39 votes

Comment accorder MODIFY_PHONE_STATE autorisation pour les applications couru sur pain d'épice

J'écris une application qui tente de modifier de téléphone d'appel de l'état. Il fonctionne bien sur Android 2.2 ou moins, mais de lever une exception sur Android 2.3 en raison de l'absence de l'autorisation sur android.la permission.MODIFY_PHONE_STATE autorisation (j'ai déclaré cette autorisation sur AndroidManifest.xml). Une idée? Ci-dessous l'exception du journal:

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)

55voto

skylarsutton Points 1766

Le problème que vous rencontrez a été introduit dans Android 2.3 (Gingerbread). Tout code que vous avez qui nécessite MODIFY_PHONE_STATE va travailler tout le chemin jusqu'à (et y compris) Android 2.2, mais pause pour Android 2.3+.

Un changement a été vérifié par David Brown, qui limite l'utilisation de la MODIFY_PHONE_STATE la permission de système d'applications. Système d'applications sont soit

  1. Pré-installé dans un dossier système sur la ROM
  2. Compilé par un fabricant à l'aide de leur certificat de sécurité

Il y avait un problème ouvert, mais Google l'a tué. Ils l'ont fait sur le but, non pas par accident, et n'ont manifestement aucune intention de le renverser.

Je soupçonne que vous essayez d'utiliser un caché API comme ITelephony. Je suis - et je me suis brûlé par cette. L'Android de l'équipe de justification est qu'il a été caché et vous ne devriez pas avoir pu l'utiliser de toute façon. Ma conviction personnelle est qu'il n'y a pas de risque pour la sécurité (il avait besoin d'une autorisation) il suffit donc de laisser en place jusqu'à la fin de la construction d'un public approprié API de Téléphonie.

David Brown, adresse e-mail peut être trouvé dans le checkin journal (lien ci-dessus)... bien que je ne suis pas sûr si c'est une adresse jetable ou d'un suivi actif par lui. Il vaut certainement la peine de lui tendez la main pour voir pourquoi il a changé ce / si il va reculer.

EDIT(1): Android fermé le Numéro 14789 ET le Numéro 15022, j'ai donc mis à jour le lien de l'actuelle demande d'amélioration.

EDIT(2): Android fermé le nouveau problème, et ne montre aucun signe de revenir sur la question... donc, on dirait que c'est une mort cause.

20voto

hackbod Points 55292

MODIFY_PHONE_STATE est un système d'seule autorisation, les applications ne sont pas autorisés à obtenir.

Cela peut avoir changé depuis les versions précédentes de la plate-forme, mais c'est correct parce que c'est seulement la protection Api privées, donc si vous faites quelque chose qui le nécessite, vous êtes en utilisant des Api privées qui ne sont pas pris en charge et entraînera des choses comme votre application de rupture sur les différentes versions de la plate-forme.

La pile d'analyse vous est pas complète, donc il n'y a aucun moyen de savoir ce que vous êtes en train de faire.

6voto

user1163234 Points 434

Essayez ceci.

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

5voto

Dhrupal Points 678

J'ai eu la solution.

Plutôt pour remplacer écran d'appel entrant, faire en dessous de deux choses. qui vous permettra d'accéder à accepter et refuser des bouton et vous permettent également d'afficher l'écran au-dessus de votre écran d'appel entrant.

(1) Faire une classe de récepteur:

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) votre activité xml ressembler à:

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)Faire de votre activité mise en page transparents(ce qui viendra au-dessus de l'appel de l'écran),écrire de code ci-dessous dans menifest

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

(4)Dans menifest ajouter votre exprimés large récepteur

<receiver android:name="MyPhoneReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.PHONE_STATE" >
            </action>
        </intent-filter>
</receiver>

(5) ajouter le code ci-dessous dans oncreate() de IncomingCallActivity

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

Cheers!

Laissez-moi savoir si vous rencontrez le moindre problème!

-5voto

Jerry Brady Points 1817

Si votre demande de pain d'épice est en cours d'exécution sur une tablette et il n'y a pas de téléphone, puis c'est le comportement attendu. Vous aurez besoin pour faire de la téléphonie liées autorisations dans votre manifeste, non obligatoire pour fonctionner sur les tablettes.

Essayez ceci dans votre manifeste:

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

Bien sûr, je suis en train de faire une grosse supposition au sujet de la tablette. Vous pouvez également voir le Android de référence ici.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X