getSystemService的异常(Context.AUDIO_SERVICE)

时间:2010-12-12 17:17:37

标签: android android-service

我想创建一个根据某些设置丢弃来电的应用,这在Android 1.6上似乎是不可能的。所以我决定编写一个应用程序,当呼叫被删除时,将Ringer改为静音。问题是,当我调用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

5 个答案:

答案 0 :(得分:13)

在Android框架调用getSystemService(...)之前,对onCreate()的调用无效。这在服务启动时发生(即通过[Context#bindService(...)] [1]或Context#startService(...))。我在尝试从构造函数调用getSystemService()时(即在调用onCreate()之前)看到了相同的NPE。

您只是致电(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,int)

答案 1 :(得分:0)

你有正确的许可吗?如果你错过了烫发,那么应用程序会在某个地方的日志中抱怨这个

答案 2 :(得分:0)

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

为什么您在super.onCreate()以外的方法中调用onCreate()?这听起来真的非常错误。

答案 3 :(得分:0)

  

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

我要做的第一件事是使用try / catch块包围ManageIncomingCall()中的代码。它至少可以解释发生了什么。

答案 4 :(得分: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)

您在TMLService.java的第94行收到NullPointerException,我猜这是您调用的行:

audioManage.setRingerMode(AudioManager.RINGER_MODE_SILENT);

我猜这个audioManage是空的。