1

いくつかの設定に基づいて着信をドロップするアプリを作成したかったのですが、これは Android 1.6 では不可能と思われます。そこで、通話が切断されたときにリンガーをミュートに変更するアプリを作成することにしました。getSystemService(Context.AUDIO_SERVICE) を呼び出すと、例外が発生します。

これらは私のクラスです:

着信者

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

}

そして、このメソッドを含む Service を拡張する 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
4

5 に答える 5

13

willへの呼び出しは、Android フレームワークによって呼び出されるgetSystemService(...)前には機能しません。onCreate()これは、サービスが開始されたときに発生します (つまり、 [Context#bindService(...)][1] またはContext#startService(...)によって)。getSystemService()コンストラクターから呼び出そうとすると (つまり、呼び出される前に) 、同じ NPE を見てきましたonCreate()

を呼び出すだけで(new TMLService()).ManageIncomingCall(incomingNumber)、Android がサービスを初期化できなくなります。これが、この NPE の根本的な原因です。

機能させるには、サービスを開始してから、サービスのメソッドを呼び出す必要があります。メソッドを呼び出すには、 AIDLを使用して公開する必要があると思います。これは必要以上に複雑かもしれません (たぶん?)。

IntentServiceは、複雑な AIDL を使わずにサービス内で処理を行う簡単な方法であると聞いたことがあります。これは、IntentService がどのように機能するべきだと私が考えるかのサンプルです。テストはしていませんが、始めるのに役立つことを願っています。

着信者

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)

于 2010-12-16T09:58:44.897 に答える
1
public void ManageIncomingCall(String incomingNumber)  
{
    super.onCreate();
    AudioManager audioManage = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
    audioManage.setRingerMode(AudioManager.RINGER_MODE_SILENT);
}

super.onCreate()以外のメソッドで呼び出しているのはなぜですかonCreate()? それは本当に、本当に間違っているように聞こえます。

于 2010-12-12T20:02:45.813 に答える
0

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

私が最初にすることは、ManageIncomingCall()のコードをtry/catchブロックで囲むことです。それは少なくとも何が起こっているかについての説明を与えるかもしれません。

于 2010-12-15T00:54:39.790 に答える
0

あなたは正しい許可を持っていますか?パーマが抜けている場合、アプリはどこかのログでこれについて不平を言います

于 2010-12-12T17:33:09.147 に答える
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それはnullだと思います。

于 2010-12-15T22:23:56.947 に答える