检测Android电池充电状态

3

我正在以编程方式拒绝来电。 "呼叫拒绝"和"发送短信"都很好用,但我只想在手机处于充电模式下才拒绝来电。

我正在尝试实现以下代码:

  case TelephonyManager.CALL_STATE_RINGING:

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

  break;

正在充电:

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
3个回答

8

在您的清单文件中添加权限

  <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>

将以下代码添加到您的类中,您可以设置一个变量标志isCharging并检查是否已设置。BatteryManager在粘性Intent中广播所有电池和充电详细信息,其中包括充电状态。
由于设备可以轻松插入,因此充电状态可能会发生变化,因此重要的是监视充电状态的变化并相应地更改刷新率。
参考://developer.android.com文档。
    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.
    }
}

3

假设您的isCharging()方法是从BroadcastReceiveronReceive()方法中调用的。在这种情况下,即使使用null作为第一个参数,也不能直接调用registerReceiver()

替代方法:

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

尝试:

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

查看此博客文章以了解更多背景信息。


你说得完全正确!我学到了一些东西。 :) 谢谢。 - OlejkaKL

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
@CommonsWare,没错。我认为你可以在需要检查电池状态的时候注册接收器,并在检查后注销。因此,重写onResume()onPause()可能是多余的工作。 - StoneBird
@CommonsWare 是的,你说得对。感谢指出这一点。非常感激。 - StoneBird

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接