2010-12-12 8 views
1

Ich wollte eine App erstellen, die einen eingehenden Anruf basierend auf einigen Einstellungen ableitet, was auf Android 1.6 unmöglich scheint. Also beschloss ich, eine App zu schreiben, die den Klingelton stummschaltet, wenn der Anruf gelöscht wurde. Die Sache ist, dass wenn ich getSystemService (Context.AUDIO_SERVICE) aufrufen, bekomme ich eine Ausnahme.Ausnahme bei getSystemService (Context.AUDIO_SERVICE)

Das sind meine Klassen:

CallReceiver

public class CallReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     MyPhoneStateListener phoneListener = new MyPhoneStateListener(); 
     TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); 
     telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);  
    } 

} 

MyPhoneStateListener

public class MyPhoneStateListener extends PhoneStateListener { 

    public void onCallStateChanged(int state, String incomingNumber){ 

     if (state == TelephonyManager.CALL_STATE_RINGING) 
     { 
      Log.d("DEBUG", "RINGING"); 
      (new TMLService()).ManageIncomingCall(incomingNumber); 
     } 
    } 

} 

Und es gibt eine Klasse namens TMLService die Service erweitert, die diese Methode enthält

public void ManageIncomingCall(String incomingNumber) 
{ 
    super.onCreate(); 
    AudioManager audioManage = (AudioManager)getSystemService(Context.AUDIO_SERVICE); 
    audioManage.setRingerMode(AudioManager.RINGER_MODE_SILENT); 
} 

Wie ich schon sagte, wenn ich AudioManager anrufe audioManage = (AudioManager) getSystemService (Context.AUDIO_SERVICE); Die Anwendung stoppt und das ist, was ich im LogCat bekomme:

D/DEBUG ( 356): RINGING 
D/AndroidRuntime( 356): Shutting down VM 
W/dalvikvm( 356): threadid=3: thread exiting with uncaught exception (group=0x4001aa28) 
E/AndroidRuntime( 356): Uncaught handler: thread main exiting due to uncaught exception 
D/CallNotifier( 103): RINGING... (new) 
E/AndroidRuntime( 356): java.lang.NullPointerException 
E/AndroidRuntime( 356): at android.content.ContextWrapper.getSystemService(ContextWrapper.java:335) 
E/AndroidRuntime( 356): at tml.v1.Service.TMLService.ManageIncomingCall(TMLService.java:94) 
E/AndroidRuntime( 356): at tml.v1.Service.MyPhoneStateListener.onCallStateChanged(MyPhoneStateListener.java:14) 
E/AndroidRuntime( 356): at android.telephony.PhoneStateListener$2.handleMessage(PhoneStateListener.java:298) 
E/AndroidRuntime( 356): at android.os.Handler.dispatchMessage(Handler.java:99) 
E/AndroidRuntime( 356): at android.os.Looper.loop(Looper.java:123) 
E/AndroidRuntime( 356): at android.app.ActivityThread.main(ActivityThread.java:4203) 
E/AndroidRuntime( 356): at java.lang.reflect.Method.invokeNative(Native Method) 
E/AndroidRuntime( 356): at java.lang.reflect.Method.invoke(Method.java:521) 
E/AndroidRuntime( 356): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791) 
E/AndroidRuntime( 356): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549) 
E/AndroidRuntime( 356): at dalvik.system.NativeStart.main(Native Method) 
D/CallNotifier( 103): onNewRingingConnection(): incoming 

Antwort

13

Der Anruf an getSystemService(...) wird nicht funktionieren, bevor onCreate() vom Android-Framework aufgerufen wird. Dies passiert, wenn der Dienst gestartet wird (d.h. durch [Kontext # bindService (...)] [1] oder Context#startService(...)). Ich habe die gleiche NPE beim Versuch gesehen, getSystemService() von einem Konstruktor aufzurufen (d. H. Bevor onCreate() aufgerufen wird).

Sie rufen einfach (new TMLService()).ManageIncomingCall(incomingNumber) an, wodurch Android Ihren Dienst, der die Hauptursache für diese NPE ist, nicht initialisieren kann.

Damit es funktioniert, müssen Sie den Dienst starten und dann eine Methode für den Dienst aufrufen. Um eine Methode aufzurufen, müssen Sie sie unter Verwendung von AIDL verfügbar machen. Es könnte komplizierter sein, als Sie dafür benötigen (vielleicht?).

Ich habe gehört, dass IntentService eine einfachere Möglichkeit ist, Sachen in einem Dienst ohne die Komplexität von AIDL zu tun. Hier ist ein Beispiel, wie IntentService funktionieren sollte. Habe es nicht getestet, aber hoffentlich ist es nützlich, um loszulegen.

CallReceiver

public class CallReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     MyPhoneStateListener phoneListener = new MyPhoneStateListener(context); 
     TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); 
     telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE); 
    } 

} 

MyPhoneStateListener

public class MyPhoneStateListener extends PhoneStateListener { 
    private final Context mContext; 

    public MyPhoneStateListener(Context context) { 
     this.mContext = context; 
    } 

    public void onCallStateChanged(int state, String incomingNumber){ 

     if (state == TelephonyManager.CALL_STATE_RINGING) 
     { 
      Log.d("DEBUG", "RINGING"); 

      // OPTION 1: Do it on the main thread (might be bad :)) 
      //AudioManager audioManage = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); 
      //audioManage.setRingerMode(AudioManager.RINGER_MODE_SILENT); 

      // OPTION 2: Use an IntentService (a bit easier than AIDL) 
      Intent intent = new Intent(TMLIntentService.ACTION_SILENCE_RINGER); 
      mContext.startService(intent); 
     } 
    } 

} 

TMLIntentService

public class TMLIntentService extends IntentService { 
    public static final String ACTION_SILENCE_RINGER = "org.example.intentservice.ACTION_SILENCE_RINGER"; 

    @Override 
    public void onHandleIntent(Intent intent) { 
     if(ACTION_SILENCE_RINGER.equals(intent.getAction()) { 
      AudioManager audioManage = (AudioManager)getSystemService(Context.AUDIO_SERVICE); 
      audioManage.setRingerMode(AudioManager.RINGER_MODE_SILENT); 
     } 
    } 
} 

AndroidManifest.xml

<service android:name=".TMLIntentService"> 
    <intent-filter> 
     <action android:name="org.example.intentservice.ACTION_SILENCE_RINGER" /> 
    </intent-filter> 
</service> 

[1]: http://d.android.com/reference/android/content/Context.html#bindService(android.content.Intent, android.content.ServiceConnection, int)

+0

Ich werde dir die Punkte belohnen, weil du tatsächlich erklärt hast, was passiert ist ... aber ich habe es letzte Nacht repariert und bin sofort eingeschlafen. Am Ende musste ich nur um eine andere Klasse bitten, anstatt eine neue zu erstellen. @ MyPhoneStateListener tml.v1.UI.MainActivity.GetService(). ManageIncomingCall (eingehende Nummer); – PedroC88

+0

Danke :) Ich bin froh, dass es funktioniert hat. –

0

Haben Sie die richtige Erlaubnis? Wenn Sie eine Dauerwelle fehlen, dann wird die App darüber beschwert in den Protokollen irgendwo

+0

Ich habe diese Berechtigungen (unter anderem) READ_PHONE_STATE und MODIFY_AUDIO_SETTINGS – PedroC88

0
public void ManageIncomingCall(String incomingNumber) 
{ 
    super.onCreate(); 
    AudioManager audioManage = (AudioManager)getSystemService(Context.AUDIO_SERVICE); 
    audioManage.setRingerMode(AudioManager.RINGER_MODE_SILENT); 
} 

Warum rufen Sie sind super.onCreate() in einem anderen Verfahren als onCreate()? Das klingt wirklich, wirklich falsch.

+0

diesen mans Rat hören. Und dann melde dich zurück, wenn du immer noch das gleiche Problem hast. –

+0

Entschuldigung, ich habe etwas zu der Zeit getestet und vergessen, diese Zeile zu löschen ... ja, der Fehler bleibt bestehen mit oder ohne die super.onCreate() – PedroC88

0

E/AndroidRuntime( 356): Uncaught handler: thread main exiting due to uncaught exception

Das erste, was ich tun würde, ist, den Code in ManageIncomingCall() mit einem try/catch-Block umgeben. Es könnte zumindest eine Erklärung geben, was vor sich geht.

+0

ex.getMessage() == null – PedroC88

+0

Aber Sie erhalten immer noch die Logcat Eintrag in Bezug auf eine 'uncaught' Ausnahme, wenn Sie einen try/catch Block dort haben? Ich gehe davon aus, dass Sie die Ausnahme nicht erneut auslösen. – Squonk

+0

Keine Ausnahme im Logcat nach dem try-catch und nop, ich wiederhole die Ausnahme nicht. – PedroC88

0
E/AndroidRuntime( 356): java.lang.NullPointerException 
E/AndroidRuntime( 356): at android.content.ContextWrapper.getSystemService(ContextWrapper.java:335) 
E/AndroidRuntime( 356): at tml.v1.Service.TMLService.ManageIncomingCall(TMLService.java:94) 

Sie erhalten eine Nullpointer in Zeile 94 von TMLService.java, ich vermute, dass dies die Linie ist, wo Sie anrufen:

audioManage.setRingerMode(AudioManager.RINGER_MODE_SILENT); 

und ich vermute, dass audioManage null ist.

+0

Ich bekomme die Ausnahme bei AudioManager audioManage = (AudioManager) getSystemService (Context.AUDIO_SERVICE); – PedroC88

Verwandte Themen