我想创建一个根据某些设置丢弃来电的应用,这在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
答案 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
是空的。