2013-04-23 171 views
2

我在程序中拒絕來電。 「呼叫拒絕」和「sendSMS」正常工作, 但我只想在電話處於充電模式時拒絕來電。檢測電池充電Android

我試圖執行以下代碼:

case TelephonyManager.CALL_STATE_RINGING: 

     if (isCharging()) 
     { 
      reject(); 
      sendSMS(incomingNumber); 
     } 

    break; 

isCharging:

public boolean isCharging() 
{ 
    IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); 
    Intent batteryStatus = contextMember.registerReceiver(null, ifilter); 
    int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1); 
    boolean bCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || 
         status == BatteryManager.BATTERY_STATUS_FULL; 
    return bCharging; 
} 

但應用程序可以使破碎的來電。

請幫我弄清楚這一點!

我收到的logcat的以下錯誤:

E/AndroidRuntime(11160): FATAL EXCEPTION: main 
    E/AndroidRuntime(11160): android.content.ReceiverCallNotAllowedException:   IntentReceiver components are not allowed to register to receive intents 
    E/AndroidRuntime(11160): at  android.app.ReceiverRestrictedContext.registerReceiver(ContextImpl.java:163) 
    E/AndroidRuntime(11160): at android.app.ReceiverRestrictedContext.registerReceiver(ContextImpl.java:157) 
    E/AndroidRuntime(11160): at com.SmartDialer_app.SmartDialer.MyPhoneStateListener.isCharging(MyPhoneStateListener.java:106) 
    E/AndroidRuntime(11160): at com.SmartDialer_app.SmartDialer.MyPhoneStateListener.onCallStateChanged(MyPhoneStateListene r.java:57) 
    E/AndroidRuntime(11160): at android.telephony.PhoneStateListener$2.handleMessage(PhoneStateListener.java:393) 
    E/AndroidRuntime(11160): at android.os.Handler.dispatchMessage(Handler.java:99) 
    E/AndroidRuntime(11160): at android.os.Looper.loop(Looper.java:137) 
    E/AndroidRuntime(11160): at android.app.ActivityThread.main(ActivityThread.java:4898) 
    E/AndroidRuntime(11160): at java.lang.reflect.Method.invokeNative(Native Method) 
    E/AndroidRuntime(11160): at java.lang.reflect.Method.invoke(Method.java:511) 
    E/AndroidRuntime(11160): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006) 
    E/AndroidRuntime(11160): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773) 
    E/AndroidRuntime(11160): at dalvik.system.NativeStart.main(Native Method) 
    E/AndroidRuntime(11160): FATAL EXCEPTION: main 
    E/AndroidRuntime(11160): android.content.ReceiverCallNotAllowedException: IntentReceiver components are not allowed to register to receive intents 
    E/AndroidRuntime(11160): at android.app.ReceiverRestrictedContext.registerReceiver(ContextImpl.java:163) 
    E/AndroidRuntime(11160): at android.app.ReceiverRestrictedContext.registerReceiver(ContextImpl.java:157) 
    E/AndroidRuntime(11160): at com.SmartDialer_app.SmartDialer.MyPhoneStateListener.isCharging(MyPhoneStateListener.java:1 06) 
    E/AndroidRuntime(11160): at com.SmartDialer_app.SmartDialer.MyPhoneStateListener.onCallStateChanged(MyPhoneStateListener.java:57) 
    E/AndroidRuntime(11160): at android.telephony.PhoneStateListener$2.handleMessage(PhoneStateListener.java:393) 
    E/AndroidRuntime(11160): at android.os.Handler.dispatchMessage(Handler.java:99) 
    E/AndroidRuntime(11160): at android.os.Looper.loop(Looper.java:137) 
    E/AndroidRuntime(11160): at android.app.ActivityThread.main(ActivityThread.java:4898) 
    E/AndroidRuntime(11160): at java.lang.reflect.Method.invokeNative(Native Method) 
    E/AndroidRuntime(11160): at java.lang.reflect.Method.invoke(Method.java:511) 
    E/AndroidRuntime(11160): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006) 
    E/AndroidRuntime(11160): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773) 
E/AndroidRuntime(11160): at dalvik.system.NativeStart.main(Native Method) 

謝謝。

+5

檢查LogCat並查看與您的「粉碎」相關的堆棧跟蹤。 – CommonsWare 2013-04-23 19:10:56

回答

3

isCharging()方法可能正在從BroadcastReceiveronReceive()調用。在這種情況下,您不能直接撥打registerReceiver(),即使是null的第一個參數。

相反的:

Intent batteryStatus = contextMember.registerReceiver(null, ifilter); 

嘗試:

Intent batteryStatus = contextMember.getApplicationContext().registerReceiver(null, ifilter); 

更多背景信息,請參閱this blog post

+0

你是對的!我傾向於一些東西。 :) 謝謝。 – OlejkaKL 2013-04-23 20:39:35

1

在您的活動中,創建一個新的BroadcastReceiver實例或擴展它的類實例。同時創建您的IntentFilter和意圖被過濾。然後在您的活動中,覆蓋onReceive()並在活動收到相應的意圖時添加您想要執行的任何操作。

您可以在onResume()中實例化接收器類,並在onPause()中取消其註冊。

事情是這樣的:

public class YourAc extends Activity{ 
BroadcastReceiver br; 
@Override 
public void onResume(){ 
    //instantiate your intent filter and other related stuff here 
    //register the receiver 
} 
@Override 
public void onPause(){ 
    //unregister your receiver 
} 
@Override 
public void onReceive(){ 
    //change the boolean isCharging to false 
} 
} 
+2

這應該沒有必要。問題中顯示的代碼用於確定電池的當前狀態。 – CommonsWare 2013-04-23 19:27:14

+0

@CommonsWare,True。我認爲您可以在需要檢查電池狀態時註冊接收器,並在檢查後取消註冊。所以也許重寫'onResume()'和'onPause()'是額外的工作。 – StoneBird 2013-04-23 19:41:54

+0

使用OP所具有的代碼會更簡單。 – CommonsWare 2013-04-23 20:05:54

7

添加permisions你Manifiest文件

<receiver android:name=".PowerConnectionReceiver"> 
    <intent-filter> 
    <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/> 
    <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/> 
    </intent-filter> 
</receiver> 

在你的類添加該代碼,你可以設置一個varible標誌isCharging和檢查被設置好的。 BatteryManager以包含充電狀態的粘性Intent廣播所有電池和充電細節。

充電狀態可以隨設備插入一樣方便地更改,因此監視充電狀態以更改並相應地更改刷新率非常重要。

Ref:// developer.android.com documentation。

public class PowerConnectionReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1); 
     boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || 
          status == BatteryManager.BATTERY_STATUS_FULL; 


     int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); 
     boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB; 
     boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC; 
     //remove some variables if you don't need it. 
    } 
}