2010-12-12 2 views
1

Я хотел создать приложение, которое снижает входящий звонок на основе некоторых настроек, что кажется невозможным на Android 1.6. Поэтому я решил написать приложение, которое изменяет Ringer для отключения звука, когда вызов будет удален. Дело в том, что когда я вызываю getSystemService (Context.AUDIO_SERVICE), я получаю исключение.Исключение из getSystemService (Context.AUDIO_SERVICE)

Это мои классы:

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

} 

И есть класс называется TMLService, который расширяет службу, которая содержит этот метод

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

Как я уже сказал, когда я вызываю AudioManager audioManage = (AudioManager) getSystemService (Context.AUDIO_SERVICE); приложение останавливается, и это то, что я получаю в LogCat:

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 

ответ

13

Звонок в номер getSystemService(...) не будет работать до onCreate(). Это происходит, когда служба запускается (например, [Контекст # bindService (...)] [1] или Context#startService(...)). Я видел тот же NPE при попытке вызвать getSystemService() из конструктора (т. Е. До вызова onCreate()).

Вы просто звоните (new TMLService()).ManageIncomingCall(incomingNumber), что не позволяет Android инициализировать вашу службу, что является основной причиной этого NPE.

Чтобы получить работу, вам необходимо запустить службу, а затем вызвать метод в службе. Чтобы вызвать метод, я думаю, вам нужно его открыть, используя AIDL. Это может быть сложнее, чем вам нужно (может быть?).

Я слышал, что IntentService - это более простой способ делать вещи на службе без сложностей AIDL. Вот пример того, как я думаю, IntentService должен работать. Не проверял его, но, надеюсь, его полезно начать.

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, целое)

+0

Я собираюсь вознаградить вас за очки, потому что вы действительно объяснили, что произошло ... но я исправил его прошлой ночью и сразу заснул. В конце концов, все, что мне нужно было сделать, это попросить службу в другом классе вместо создания нового. @ MyPhoneStateListener tml.v1.UI.MainActivity.GetService(). ManageIncomingCall (incomingNumber); – PedroC88

+0

Спасибо :) Я рад, что у вас это работает. –

0

У вас есть правильное разрешение? Если вам не хватает завивку, то приложение будет жаловаться на это в журналах где-то

+0

У меня есть эти разрешения (среди прочих) READ_PHONE_STATE и 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); 
} 

Почему вы называете super.onCreate() в методе, кроме onCreate()? Это звучит действительно, действительно неправильно.

+0

Слушайте это укомплектовывает совет. А затем отчитайтесь, если у вас все еще есть такая же проблема. –

+0

Извините, я тогда что-то тестировал и забыл стереть эту строку ... да, ошибка сохраняется с или без super.onCreate() – PedroC88

0

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

Первое, что я бы сделать, это окружить код в ManageIncomingCall() с TRY/поймать блок. Это может по крайней мере дать объяснение относительно того, что происходит.

+0

ex.getMessage() == null – PedroC88

+0

Но вы все еще получаете логарифм запись, относящаяся к исключению «uncaught», когда у вас есть блок try/catch? Я предполагаю, что вы также не перебрасываете исключение. – Squonk

+0

Никаких исключений в logcat после try-catch и nop, я не переустанавливаю исключение. – 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) 

Вы получаете NullPointerException на линии 94 TMLService.java, я предполагаю, что это линия, где вы звоните:

audioManage.setRingerMode(AudioManager.RINGER_MODE_SILENT); 

и я предполагаю, что audioManage является недействительным.

+0

Я получаю исключение в AudioManager audioManage = (AudioManager) getSystemService (Context.AUDIO_SERVICE); – PedroC88

Смежные вопросы