Exception on getSystemService(Context.AUDIO_SERVICE)

五迷三道 提交于 2019-12-01 10:14:39

问题


I wanted to create an app that drops an incoming call based on some settings, that seems to be impossible on Android 1.6. So I decided to write an app that changes the Ringer to mute when the call would've been dropped. The thing is that when I call getSystemService(Context.AUDIO_SERVICE) I get an exception.

These are my classes:

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

}

And there is a class called TMLService that extends Service which contains this method

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

Like I said, when I call AudioManager audioManage = (AudioManager)getSystemService(Context.AUDIO_SERVICE); the application stops and this is what I get in the 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

回答1:


The call to getSystemService(...) will not work before onCreate() is called by the Android framework. This happens when the service is started (i.e. by [Context#bindService(...)][1] or Context#startService(...)). I've seen the same NPE when trying to call getSystemService() from a constructor (i.e. before onCreate() is called).

You're simply calling (new TMLService()).ManageIncomingCall(incomingNumber), which doesn't allow Android to initialize your service, which is the root cause of this NPE.

In order to get it working, you'll have to start the service and then call a method on the service. To call a method, I think you have to expose it using AIDL. It might be more complicated than you need for this (maybe?).

I've heard that IntentService is an easier way to do stuff in a service without the complexity of AIDL. Here's a sample of how I think IntentService should work. Haven't tested it, but hopefully its useful to get started.

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)




回答2:


Do you have the correct permission? If you are missing a perm, then the app will complain about this in the logs somewhere




回答3:


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

Why Are you calling super.onCreate() in a method other than onCreate()? That sounds really, really wrong.




回答4:


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

The first thing I'd do is surround the code in ManageIncomingCall() with a try/catch block. It might at least give an explanation as to what is going on.




回答5:


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)

You are getting a NullPointerException at line 94 of TMLService.java, I am guessing that this is the line where you call:

audioManage.setRingerMode(AudioManager.RINGER_MODE_SILENT);

and I am guessing that audioManage is null.



来源:https://stackoverflow.com/questions/4422866/exception-on-getsystemservicecontext-audio-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!