so i am trying to create a battery statistics android app but neither i'm able to receive broadcast using broadcastmanager cos its not available for android oreo and nor my service is running on background for more than a few minutes.
my question is how do i receive battery broadcasts like plug,unplug,level..... in background on android oreo api 26+
i run the service from the activity on destroy
/////my service code/////
public class bservice extends Service {
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
IntentFilter ifl = new IntentFilter();
registerReceiver(bcr,new IntentFilter(Intent.ACTION_POWER_DISCONNECTED));
registerReceiver(bcr,new IntentFilter(Intent.ACTION_POWER_CONNECTED));
registerReceiver(bcr,new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
registerReceiver(bcr,new IntentFilter(Intent.ACTION_SCREEN_OFF));
registerReceiver(bcr,new IntentFilter(Intent.ACTION_SCREEN_ON));
registerReceiver(bcr,ifl);
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(10000);
update();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
Log.d("msg","running in background 1");
return Service.START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
private final BroadcastReceiver bcr = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
update();
Log.d("msg","running in background 2");
}
};
#Override
public void onDestroy() {
super.onDestroy();
//unregisterReceiver(bcr);
Log.d("msg","service destroyed");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(new Intent(this,bservice.class));
Log.d("msg","serv restarted");
}
}
void update()
{.......... my updating code
updaten(pct,cc,isCharging,isCharging);
}
Notification notification;
NotificationManager notificationManager;
void updaten(float pct,float cc,boolean a,boolean ot)
{.........my notification update code
notificationManager.notify(id, notification);
}
}
}
Use JobIntentService instead of Service and then register broadcast receiver dynamically from service.
https://developer.android.com/reference/android/support/v4/app/JobIntentService.html
Related
When I close main app servic stops broadcasting intents. Where is mistake? I can't find any way to keep it running.
Broadcast recevier:
public class CustomReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Custom Broadcast recevied", Toast.LENGTH_SHORT).show();
}}
Service (AAA.java):
public class AAA extends Service {
final class MyThreadClass implements Runnable {
int service_id;
MyThreadClass(int service_id) {
this.service_id = service_id;
}
#Override
public void run() {
synchronized (this) {
try {
while (true) {
Thread.sleep(3000);
Intent i = new Intent();
i.setAction("cz.johnyapps.custombroadcast");
sendBroadcast(i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Thread thread = new Thread(new MyThreadClass(startId));
thread.start();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}}
Manifest:
<service android:name="cz.johnyapps.notificationservice.AAA"
android:exported="true"
android:process=":ServiceProcess"/>
Main activity: startService(new Intent(this, AAA.class));
Use startForeground method inside the Service to prevent such behavior
According to my knowledge one way is to make service running even after closing the app.
You have to make as notification in you app which will bind the
service to it. if the app is closed that notification will be attached
which will be binding the service to it.
Example: Android phone default Media sound playing app, if you close the app an notification is shown on the notification bar which maintains the service to keep the music playing in the service.
What are the best practices for running worker threads in the background that periodically update UI elements in an activity. The goal here is to avoid any screen freezing on any kind of updates and if there are any specific guidelines/standards that should be followed.
Try Service for Background Work.
I have made an example for you.
Try this.
TestActivity.java
public class TestActivity extends AppCompatActivity {
private final String TAG = "TestActivity";
public final static String RECEIVER_ACTION = "com.action.MyReceiverAction";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_work);
registerMyReceiver();
startService(new Intent(this, BackgroundService.class));
}
MyReceiver myReceiver = new MyReceiver();
private void registerMyReceiver() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(RECEIVER_ACTION);
registerReceiver(myReceiver, intentFilter);
}
class MyReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "onReceive() called");
}
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myReceiver);
}
}
BackgroundService.java
public class BackgroundService extends Service {
private String TAG = "BackgroundService";
#Override
public void onCreate() {
super.onCreate();
Log.e(TAG, "onCreate() called");
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind() called");
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand() called");
notifyToUI();
return super.onStartCommand(intent, flags, startId);
}
/**
* This Methd will notify your Activity
*/
private void notifyToUI()
{
Intent myIntent = new Intent();
myIntent.setAction(TestActivity.RECEIVER_ACTION);
sendBroadcast(myIntent);
}
}
Now at the end register BackgroundService in AndroidManifest.xml file
<service android:name=".BackgroundService"/>
Use AlarmManager (or some other timer) to periodically start a service. That service then updates the model, and notifies UI thread with for example LocalBroadcastManager. UI thread can then use BroadcastReceiver to catch the Intent and update itself.
i want to receive a broad cast when the screen is turned off in android. I have written the following code. This is the Receiver's code.
#Override
public void onReceive(Context context, Intent intent) {
helper = new FeedReaderDBHelper(context);
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
System.out.println("Screen Off Receiver just received something");
if(helper.getValue(FeedReaderContract.FeedEntry.onlock).equals("YES"))
{
helper.lockAll();
wasScreenOn = false;
}
else if(helper.getValue(FeedReaderContract.FeedEntry.onLock3).equals("YES"))
{
System.out.println("Running 3 minutes thread");
Runner runner = new Runner(context);
Thread t = new Thread(runner);
t.setName("LockThreeThread");
t.start();
}
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
// and do whatever you need to do here
wasScreenOn = true;
}
}
I am registering and unregistering the Receiver in a Service. The code is as follows.
Registring Receiver in onStartCommand method
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
isScreenOn = pm.isScreenOn();
RegisterReceiver();
//Toast.makeText(getApplicationContext(), "Service Started", Toast.LENGTH_SHORT).show();
//System.out.println("StartRemove");
helper = new FeedReaderDBHelper(this);
names = helper.getNames();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
startChecker();
}
});
t.start();
return START_STICKY;
}
And this is how i unregister in onDestroy of the Service method.
private void RegisterReceiver()
{
receiver = Factory.getScreeReceiver();
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
registerReceiver(receiver, filter);
}
Please let me know what could be the problem. I have been digging into it for long time. Last two days were wasted on this. Nothing seems to work.
I think you're overly complicating this.
This is the activity you would need
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent startServiceIntent = new Intent(this, MyService.class);
startService(startServiceIntent);
}
This is the service
public class MyService extends Service {
public MyService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("APP", "Service started");
ScreenOffReceiver receiver = new ScreenOffReceiver();
registerReceiver(receiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
return START_STICKY;
}
}
And this is the Broadcast Receiver
public class ScreenOffReceiver extends BroadcastReceiver {
public ScreenOffReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
Log.i("APP", "EVENT occured");
}
}
I just tried out this code and the logging worked fine.
When you start this via a service, and start a new thread to do the job in the onStartCommand() method, be noted that the thread will start every time you invoke the onCreate() of the activity.
Hope this helps
I have developed an app with Android BLE (bluetooth low enbergy)
It is working fine but when Android require more memory, my service is killed.
I am using a foreground service with a separate process.
< receiver android:name=".BluetoothLeService$MyReceiver"/>
< service android:name=".BluetoothLeService"
android:enabled="true"
android:exported="true"
android:process=":myservice"/>
I start my service from activity as:
startService(new Intent(this, BluetoothLeService.class));
and in my service:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
SetNotification(0);
return START_STICKY;
}
but when my service got killed by OS, it doesn't restart.
I have tried closing all recent app but not getting any solution....
Is there any solution for this? Please help me. Any help will be appreciated. Thank you in advance.
--- Poweramp app isn't never killed --- why?
EDIT:
MainActivity in OnCreate:
...
startService(new Intent(this, BluetoothLeService.class));
In BluetoothLeService:
#Override
public void onDestroy() {
unregisterReceiver(mReceiver); // receiver for bt on and bt off
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
SetNotification(0);
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void SetNotification(int VerdeRosso){
if (VerdeRosso == 1) { // connected
remoteViews = new RemoteViews(getPackageName(), R.layout.notification_connesso);
}else {
remoteViews = new RemoteViews(getPackageName(), R.layout.notification_disconnesso);
}
mBuilder = new NotificationCompat.Builder(getApplicationContext());
mBuilder.setContent(remoteViews);
mBuilder.setSmallIcon(R.mipmap.ic_launcher);
startForeground(123, mBuilder.build()); // 123 รจ l'id a caso
}
#Override
public void onCreate() {
mBluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
mBluetoothAdapter = mBluetoothManager.getAdapter();
//broadcaster = LocalBroadcastManager.getInstance(this);
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
mReceiver = new MyReceiver();
registerReceiver(mReceiver, filter);
scanLeDevice(true);
}
--- EDIT 2
private final IBinder myBinder = new LocalBinder();
public class LocalBinder extends Binder {
BluetoothLeService getService() {
return BluetoothLeService.this;
}
}
....
#Override
public IBinder onBind(Intent intent) {
return myBinder;
}
You can check when the service is killed and restart it again by this way:
#Override
public void onLowMemory() {
//Send broadcast to the Activity to kill this service and restart it.
super.onLowMemory();
}
#Override
public void onTaskRemoved(Intent rootIntent)
{
//Send broadcast to the Activity to restart the service
super.onDestroy();
}
You can make 2 broadcast or only one of these above.
I have broadcast receiver that activates on phone boot
public class autostart extends BroadcastReceiver {
public void onReceive(Context arg0, Intent arg1) {
Intent intent = new Intent(arg0, MyService.class);
arg0.startService(intent);
Log.i("Autostart", "started");
}
}
The service is very simple it just keeps registered an broadcast receiver that can be only registered by code and not from manifest
public class MyService extends Service
{
private static final String TAG = "MyService";
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
}
ScreenOffReceiver actionScreenOffReceiver;
#Override
public void onStart(Intent intent, int startid)
{
try {
IntentFilter intentfilter = new IntentFilter();
intentfilter.addAction(Intent.MY_ACTION);
registerReceiver(actionScreenOffReceiver = new ScreenOffReceiver(),
intentfilter);
} catch (Exception e) {
}
}
}
The problem is that if the app get closed, for example with call of finish() on some activity, then the service just dies.
How can I keep the service running till the phone is turned on
what is the right way to do this ?
You don't need an BroadcastReceiver just add this code in your Service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
Source: Service | Android Developers