BroadcastReceiver in Service is not working after boot completed - android

I am using a Service to listen for a broadcast after boot completed. But the BroadcastReceiver is not registering when boot completed. If instead of a Service I use a BroadcastReceiver to listen for boot completed it works. It doesn't when I register it with a Service. What am I doing wrong? Code is given below.
private BroadcastReceiver sim_change;
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
IntentFilter filter = new IntentFilter();
filter.addAction(action);
sim_change = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "Boradcast Receiver registered successfully", Toast.LENGTH_LONG).show();
}
};
registerReceiver(sim_change, filter);
}#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unregisterReceiver(sim_change);
Toast.makeText(getApplicationContext(), "Boradcast Receiver unregistered successfully", Toast.LENGTH_LONG).show();
}

You have to register for BOOT_COMPLETED in your Manifest. It doesn't make sense to register for it from a Service, because the Service won't be running at boot in order to register for it.

You can't register for BOOT_COMPLETED from within a Service because the reboot removes that registration.
You must do it from your BroadcastReceiver.
There are many ways to handle the enable/disable feature - either using the suggested setComponentEnabledSetting(), or just by storing a value in the app's shared preferences, which you can check when your service starts.

Related

Is my Activity 'active'? [duplicate]

This question already has answers here:
Checking if an Android application is running in the background
(35 answers)
Closed 5 years ago.
My app consists of just one activity (launchMode=singleTask) with a viewpager in it. In the app, the user schedules alarms through the AlarmManager. When these alarms are triggered, a broadcast receiver creates notifications in the status bar (wether the app is open or not).
I'd like to update a RecyclerView in the activity whenever a notification is issued AND THE ACTIVITY IS IN THE FOREGROUND. If the activity is in the background or not 'active' at all (doesn't exist), there's no need to call it to the front or open it just to update the RecyclerView.
How can I check if my activity exists before calling, say, "MyActivity.updateMyRecyclerView()"? (I have an idea on how to check if it's in the foreground or not, I think that wouldn't be a problem.)
You can use broadcast receiver for your activity. You can send a broadcast and if your activity is 'alive' and is registered to receive the broadcast you can trigger the recyclerView update from there.
Send the broadcast when you are creating the notification like this
Intent intent = new Intent("key_to_identify_the_broadcast");
Bundle bundle = new Bundle();
bundle.putBoolean("updateRecyclerView",true);
intent.putExtra("bundle_key_for_intent", bundle);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
and in your Activity where you want to receive this intent, you can use a broadcast receiver
private final BroadcastReceiver mHandleMessageReceiver = new
BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle =
intent.getExtras().getBundle("bundle_key_for_intent");
if(bundle!=null){
boolean shouldRefresh = bundle.getBoolean("updateRecyclerView");
if(shouldRefresh){
//Refresh your recyclerView
}
}
}
};
You need to register and unregister the receiver to work
In your onResume method you can register this receiver to receive the broadcast
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
IntentFilter filter = new IntentFilter("key_to_identify_the_broadcast");
LocalBroadcastManager.getInstance(this)
.registerReceiver(mHandleMessageReceiver,filter);
}
You also need to unregister it before your activity gets paused
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
try {
LocalBroadcastManager.getInstance(this)
.unregisterReceiver(mHandleMessageReceiver);
} catch (Exception e) {
Log.e("UnRegister Error", "> " + e.getMessage());
}
}

Gps Location Logging through Service in Android

I am making an android app to log current user location to my server every few hour. So far I have made a class to give me current user location and i have also been able to send location data to web. I have also been able to register a service in my app to run, even my app has been cleared from background. Now I want to integrate all these, but cant seem to integrate it.
My main activity is
public class MainPage extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mainpage);
Intent i= new Intent(MainPage.this, RunnerService.class);
this.startService(i);
}
}
and my service is:
public class RunnerService extends Service {
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.d("SahiyogiHaat", "Service created");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.d("SahiyogiHaat", "Service started");
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
So where should I make object of my location tracker class to run the service and access user location every 1 hour. In addition to this I tried to implement on reboot broadcast receiver as follows and implement the service from there when user switches on his mobile:
public class MyReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Intent i= new Intent(context, RunnerService.class);
// potentially add data to the intent
context.startService(i);
}
}
but the service doest start but it says "unfortunately application stopped working", which mean the broadcast has been received but there is some problem.
My manifest file is as below:
If you want to get user's location every hour, you need to use one of the location listener mechanisms (either the native Android location API or the Google Location Services API). You can then register with the location manager for location callbacks every hour. In this case you should pass a PendingIntent to the location manager, so that it either starts your Service every hour or triggers a BroadcastReceiver every hour with the GPS location data.
Also, Android cannot start your BroadcastReceiver on device boot. To fix this, remove
android:exported="true"
from the manifest declaration for <receiver>

Communicating between Service and Activity using Broadcasts/intents

I am trying to communicate/update UI from Service to activity. The broadcast I receive is not what I had sent. Any ideas why?
Service code:
#Override
//binder returns NULL
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
Intent i = new Intent();
i.putExtra("lol", "haha");
i.setAction(MYACTION);
sendBroadcast(i);
Activity code:
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
IntentFilter intentFilter = new IntentFilter(MYACTION);
registerReceiver(recv, intentFilter);
}
BroadcastReceiver recv = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Intent getintent = getIntent();
String action = getintent.getAction();
//ACTION RECEIVED IS DIFFERENT FROM MYACTION. IT IS ACTION.MAIN
// VALUE RECEIVED IS NULL
String val = getintent.getStringExtra("lol");
}
I have not registered the receiver in manifest. Is it necessary?
As mentioned in comments: I do not receive the same action in broadcast receiver and the value from intent is NULL.
What am I doing wrong?
Thanks for your help.
You dont need to use getIntent, because it translates to Activity's intent, not received broadcast's intent. So in your case, you need to use intent only which refers to broadcasted intent. And make sure you do make a check before reading the desired value from bundle, because there might be a possibility that you are getting another broadcast first which doesn't contain lol in its bundle.
So in your broadcast receiver, do it like this:
....
String val = getintent.getStringExtra("lol");
if(val.equals("your_action_string"){
String val = intent.getStringExtra("lol"); //getIntent() replaced by intent
}
....
P.S. no, you dont need to register any broadcast receiver because it is created and being used programmatically
If you are making web requests or extended tasks I'd check out the async task. It makes it way easier to update the UI. Just make sure you call onPreExecute() and onPostExecute() to do this. I don't like services and receivers.
http://developer.android.com/reference/android/os/AsyncTask.html

controlling broadcast from activity

I am doing an android application. In my project I am checking phonestates using broadcast receiver.Using the folowing code I am checking my phonestate.
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Bundle bun=intent.getExtras();
if(bun!=null){
String state=bun.getString(TelephonyManager.EXTRA_STATE);
Log.w("DEBUG", state);
if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){
String phoneno=bun.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
Toast.makeText(context, "phone no. is"+phoneno, Toast.LENGTH_LONG).show();
}
}
}
Now i want control this application from activity. I mean using an button i have start the broadcast and using an off button i have to close the broadcast run.the second problem is i want run the application when the application is in closed state too. So i think I have call a service from activity and that service make that broadcast receiver to run in the background. And if i want to stop my application's processing open app and click the button to off. Help me friends..
You can ,
When click on
Registered your broadcast
IntentFilter filter=new IntentFilter(TelephonyManager.EXTRA_STATE);
registerReceiver(new BroadcastReceiverClass.class, filter);
when click off
unregistered your broadcast
unregisterReceiver(new BroadcastReceiverClass());

BroadcastReceiver for screen lock not being triggered

I'm trying to turn the GPS location updates off when the screen locks. Having read the answer to this question Android - how to receive broadcast intents ACTION_SCREEN_ON/OFF?
I've written some code to implement a BroadcastReceiver but it's not working when the screen goes off.
I've registered a BroadcastReceiver in my code with
#Override
public void onResume() {
super.onResume();
IntentFilter iFilter = new IntentFilter();
iFilter.addAction("android.intent.action.ACTION_SCREEN_ON");
iFilter.addAction("android.intent.action.ACTION_SCREEN_OFF");
registerReceiver(screenStatReceiver, iFilter);
and the receiver itself is just a stub for now:
public BroadcastReceiver screenStatReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.d("BCAST_TAG", "Got broadcast");
String action = intent.getAction();
}
};
and in the manifest I have:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Any ideas as to why it's not being triggered when I debug it on my phone?
For this problem, you have to create a infinite service, which is registering a local broadcast receiver for these intents. If you do this way, then your app will look for screen off but make sure you have to make service which will always running in background like reboot receiver
You are registering the reciever in the onResume() method. Why dont you register it in the onCreate() so you can have persistent "listening"?
In this case you are listening for changes only after the activity is resumed.

Categories

Resources