Android broadcastreceiver not triggering when app is not running

Asalas77 picture Asalas77 · Jan 20, 2017 · Viewed 7.3k times · Source

Following this guide https://developer.android.com/training/monitoring-device-state/battery-monitoring.html

I made a receiver that should log battery info to a file every time charger is plugged or unplugged. The activity reads the content of this file and displays it on screen. This is supposed to work always regardless of the app running, but it doesn't. It only registers if the app is open/in memory, when I clear the memory or reboot it stops working.

Manifest:

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

Receiver:

public class Receiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
      Intent chargingIntent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
      final int status = chargingIntent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
      int level = chargingIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
      int plugged = chargingIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
      Battery battery = new Battery();
      battery.setLevel(level);
      battery.setDate(new Date());
      battery.setPlugged(plugged);
      battery.setStatus(status);
      Logger.log(JSON.toJSONString(battery));
    }
}

Logger

public class Logger {

public static void log(String text)
{
    File logFile = new File(Environment.getExternalStorageDirectory().getPath()+"/batterylog.txt");
    Log.d("files"," logfile "+logFile+": "+logFile.exists());

    if (!logFile.exists())
    {
        try
        {
            logFile.createNewFile();
            Log.d("files","new logfile created"+logFile);
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    try
    {
        //BufferedWriter for performance, true to set append to file flag
        BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
        buf.append(text).append("\r\n");
        buf.flush();
        buf.close();
    }
    catch (IOException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}

This is what it looks like after unplugging while app is open:

enter image description here

When it's not it's just empty.

Answer

 Ekalips  picture Ekalips · Jan 20, 2017

Try to set android:enabled="true" to your receiver

Like this

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

Update

I just implemented it in my app your's way and it worked. But I did it with right click->new->other->broadcast receiver

After inserting intent-filter I got code like this

    <receiver
        android:name=".MyReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
            <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
        </intent-filter>
    </receiver>

And it actually calling onReceive method