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
Related
I'm working on AndroidService, where every 5 minutes a network call is made to search new data from database. I have implemented BroadcastListener to listen for constant connection inside service, but the app is crashing everytime.
Error:
java.lang.RuntimeException: Error receiving broadcast Intent { act=android.net.conn.CONNECTIVITY_CHANGE flg=0x4000010 (has extras) } in com.test.service.MyService$1#d3df904
Globally declared:
BroadcastReceiver receiver;
Code:
#Override
public void onCreate() {
super.onCreate();
registerReceiver(receiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(ConnectionStatus.isConnected(MyService.this)){
//some work
}
else {
//some task
}
}
};
registerReceiver(receiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
return START_STICKY;
}
onCreate happens before onStartCommand so you are trying to register a broadcast receiver with a null receiver. Remove the register from onCreate and it should work.
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.
My problem is that I think my service runs multiple times. The service is controlled by a switch calling a method that starts and stops the service. I have a broadcast listener inside my service and the receiver logs whenever it receives a broadcast. at first switch on, it logs two times. After switch off and on, it logs four times.
public class Service1 extends Service implements DetectionListener {
private static final String TAG = "ListenerService";
private final broadcastReceiver1 receiver = new broadcastReceiver1();
public HashMap<String, String> hashMapData;
private ARSonicManager arSonicManager;
public ListenerService() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter();
filter.addAction("com.digify.almostrealsonic.broadcast_intent");
registerReceiver(receiver, filter);
}
#Override
public void onDestroy() {
unregisterReceiver(receiver);
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startId) {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (null != intent) {
try {
hashMapData = (HashMap<String, String>) intent.getSerializableExtra("hashMapData");
// Do something with hashMapData
} catch (Exception e) {
Log.i("onStartCommand", e.toString());
}
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onMarkerDetected(String markerKey) {
Intent intent = new Intent();
intent.putExtra("hashMapData", hashMapData);
intent.setAction("com.broadcastReceiver1_intent");
sendBroadcast(intent);
}
public static class broadcastReceiver1 extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String hashMapData = intent.getStringExtra("hashMapData");
Log.i("receiver", "Got message: " + hashMapData);
}
}
}