Search code examples
androidandroid-serviceandroid-notificationsandroid-alarms

Getting battery status even when the application is closed


Hey I am trying to make an application that tells me when the battery is full when the phone is connected to power. I made a service and used a broadcast receiver in that to check the battery status. Whenever i connect or disconnect the phone from the power, my app crashes. The service still runs and i get the notification when battery is full.

I dont know why is the app crashing again and again. Here is my code

public class Srvc extends Service{

@Override
public int onStartCommand(Intent intent, int flags, int startId){
    // TODO Auto-generated method stub

     final IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); 
     this.registerReceiver(this.br, ifilter);


    System.out.println("started the service");


    return super.onStartCommand(intent,flags,startId);
}



public final BroadcastReceiver br = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {

        System.out.println("inside on recieve");

        chckbttry(intent);

    }
};

private void chckbttry(Intent intent) {
    // TODO Auto-generated method stub

    System.out.println("inside chckbttry method");

    final int currLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
    final int maxLevel = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
    int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
    boolean isCharged = status == BatteryManager.BATTERY_STATUS_FULL;
    final int percentage = (int) Math.round((currLevel * 100.0) / maxLevel);

    if (status == BatteryManager.BATTERY_STATUS_CHARGING)
    {
         System.out.println("calling the BrdCst_strt");


     if (percentage == 100 || isCharged==true) {

         System.out.println("bttry fully chrged");
         Intent i = new Intent(getBaseContext(),PlayMus.class); //call another activity
         i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         i.putExtra("msg", "Battery fully charged");
         getApplication().startActivity(i);
     }
    else
     {
        System.out.println("not yet charged");
        Intent i = new Intent(getBaseContext(), Test.class);
         i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         i.putExtra("msg", "Battery not fully charged");
         getApplication().startActivity(i);


    } 
    }

    if (status == BatteryManager.BATTERY_STATUS_DISCHARGING)
    {
        System.out.println("unregistering the service");
        unregisterReceiver(br);
    }

} 

@Override
public void onDestroy() {
    // TODO Auto-generated method stub
    System.out.println("service stopped");
    unregisterReceiver(br);
    super.onDestroy();

}

}

Please help me.

Thanks.


Solution

  • System messages like the battery level are sent as a Broadcast through the whole system. You can receive them with a so called BroadcastReceiver.

    While Activities have an UI, you need to use a Service which are meant to be used for longer work in the background while your App is not visible. Your App has to be started at least once before for you to be able to start this Service.

    MainActivity.java

    public class MainActivity extends ActionBarActivity {
    
        private MyService service;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            if (service == null) {
                // start service
                Intent i = new Intent(this, MyService.class);
                startService(i);
            }
            // finish our activity. It will be started when our battery is full.
            finish();
        }
    }
    

    MyService.java

    public class MyService extends Service {
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.d("MyService", "onStartCommand");
            // do not receive all available system information (it is a filter!)
            final IntentFilter battChangeFilter = new IntentFilter(
                    Intent.ACTION_BATTERY_CHANGED);
            // register our receiver
            this.registerReceiver(this.batteryChangeReceiver, battChangeFilter);
            return super.onStartCommand(intent, flags, startId);
        }
    
        private final BroadcastReceiver batteryChangeReceiver = new BroadcastReceiver() {
    
            @Override
            public void onReceive(final Context context, final Intent intent) {
                checkBatteryLevel(intent);
            }
        };
    
        @Override
        public IBinder onBind(Intent intent) {
            // There are Bound an Unbound Services - you should read about the differences. This one is an unbound one.
            return null;
        }
    
        private void checkBatteryLevel(Intent batteryChangeIntent) {
            // some calculations
            final int currLevel = batteryChangeIntent.getIntExtra(
                    BatteryManager.EXTRA_LEVEL, -1);
            final int maxLevel = batteryChangeIntent.getIntExtra(
                    BatteryManager.EXTRA_SCALE, -1);
            final int percentage = (int) Math.round((currLevel * 100.0) / maxLevel);
    
            Log.d("MySerive", "current battery level: " + percentage);
    
            // full battery
            if (percentage == 100) {
                Log.d("MySerive", "battery fully loaded");
                Intent intent = new Intent(getBaseContext(), SecondActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                getApplication().startActivity(intent);
            }
            // do not forget to unregister
            unregisterReceiver(batteryChangeReceiver);
        }
    
    }
    

    Manifest.xml: You need an entry for your Serivice - just like for an Activity.

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.mybatteryservice"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="19" />
    
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name="com.example.mybatteryservice.MainActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity android:name="com.example.mybatteryservice.SecondActivity" >
            </activity>
            <service android:name="com.example.mybatteryservice.MyService" >
            </service>
        </application>
    
    </manifest>
    

    Please let me know if you have any more questions!

    Best regards Vincent