OlejkaKL
OlejkaKL

Reputation: 521

Detecting Battery Charging Android

I;m programmatically rejecting an incoming calls. The "call reject" and "sendSMS" work fine, but I want to reject the call only if the phone is in charging mode.

I'm trying to implement the following code :

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

But the app keeps crushing on incoming call.

Please help me to figure this out!

I'm receiving the following errors on the 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)

Thank you.

Upvotes: 3

Views: 15968

Answers (3)

CommonsWare
CommonsWare

Reputation: 1006614

Your isCharging() method is presumably being called from onReceive() of a BroadcastReceiver. In that case, you cannot call registerReceiver() directly, even with a null first parameter.

Instead of:

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

try:

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

See this blog post for more background.

Upvotes: 3

schwertfisch
schwertfisch

Reputation: 4579

Add the permisions in you Manifiest File

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

Add this code in your class, you can set a varible flag isCharging and check is is setted. The BatteryManager broadcasts all battery and charging details in a sticky Intent that includes the charging status.

The charging status can change as easily as a device can be plugged in, so it's important to monitor the charging state for changes and alter your refresh rate accordingly.

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

Upvotes: 8

StoneBird
StoneBird

Reputation: 1940

In your activity, create a new BroadcastReceiver instance or your class instance that extends it. Also create your IntentFilter and the intent to be filtered. Then in your activity, override onReceive() and add whatever you want to do when the activity receives the corresponding intent there.

You can instantiate the receiver class in onResume() and unregister it in onPause().

Something like this:

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

Upvotes: 1

Related Questions