Passing data from android activity to broadcast receiver on device boot up - java

I always get bundle value null when I pass data from activity to broadcast receiver.
My receiver will start on boot up.
This is the code in my activity class
Intent intent= new Intent();
intent.setAction("android.intent.action.BOOT_COMPLETED");
intent.putExtra("test", "test");
sendBroadcast(intent);
This is the code in my receiver class:
String testValue = intent.getStringExtra("test");

Your code in activity will never be called upon booting up. System invokes onReceive() with its own intent. You can check this by putting some logs in activity code - this log will not be printed in logcat.

Related

java.lang.IllegalStateException error :"Can not perform this action after onSaveInstanceState"

I am writing an app where i am trying to display a dialog fragment on Activity A. Activity-A launch Activity-B using an intent. I am launching the Dialogfragment using a broadcast intent whose receiver is registered on Activity-A . But when i switch from activity A to activity B , i get the an IllegalStateException error when Activity A broadcast receiver receives the intent . The eror displays : Can not perform this action after onSaveInstanceState . Could you help me please ?

Android-Java: Starting an activity from a Broadcast Receiver

I'm trying to launch an activity directly from a broadcast receiver without the user having to manually open up my app. What I'm hoping to achieve is to automatically open up my app after a device restart. I have a receiver listening for a BOOT_COMPLETED event, which from that I want to open up an activity, or start my app.
Is this possible?
This is the code I'm currently using to launch the activity inside the receiver:
Intent i = new Intent();
i.setClassName(packageName, activityName);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);

Android Notification Click to Broadcast Receiver getting same intent string

I have a broadcast receiver which is triggered on a notification click. I'm passing a string in the intent of notification for the broadcast receiver. The values of the string differs everytime however when I am testing my app, I can only see the value I received the first time I clicked the notification. Now every value I'm getting from my notification to the broadcast receiver is same despite passing new values.
My code:
//Creating notification
Intent snoozeIntent = new Intent(getApplicationContext(), ServiceLauncherBroadcast.class);
snoozeIntent.putExtra("order_id", orderId);
//In the broadcast receiver
startWorkManager(intent.getStringExtra("order_id")
//Manifest
<receiver android:name = ".utils.ServiceLauncherBroadcast" />
In your PendingIntent please use this flag:
PendingIntent.FLAG_CANCEL_CURRENT

BroadcastReceiver onReceive method not called?

I have a service running in which I am getting location updates. The service returns the location successfully. But after that I am trying to broadcast the location to any activity that might be listening. I have registered the receiver in my activity but for some reason the onReceive method is not being called.
Here is the code inside my onLocationChanged method inside my service.
#Override
public void onLocationChanged(Location location) {
Intent intent = new Intent();
intent.setAction("LocationBroadcast");
double lat = location.getLatitude();
double lng = location.getLongitude();
intent.putExtra("lat", lat);
intent.putExtra("lng", lng);
//I am initializing the broadcaster object in onCreate method of my service but I am putting it here for simplicity
broadcaster = LocalBroadcastManager.getInstance(this);
//This Toast successfully shows my coordinates so I know the problem is not with this method
Toast.makeText(GoogleFusedLocationApiService.this, ""+lat+", "+lng+"", Toast.LENGTH_SHORT).show();
broadcaster.sendBroadcast(intent);
}
Inside my activity in my onCreate method, I am registering for the LocationBroadcast like so.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
...
IntentFilter intentFilter = new IntentFilter("LocationBroadcast");
super.registerReceiver(mMessageReceiver, intentFilter);
startService(new Intent(MyApp.getAppContext(), GoogleFusedLocationApiService.class));
}
I've tried this.registerReceiver(mMessageReceiver, intentFilter); and LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, intentFilter); but neither worked.
Here is my mMessageReceiver defined,
public BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
double lat = intent.getDoubleExtra("lat", 0);
double lng = intent.getDoubleExtra("lng", 0);
// This Toast never shows and neither can I debug this method at all
// so for now the only conclusion is the broadcast is not being received
Toast.makeText(MyApp.getAppContext(), "Cordinates are "+lat+", "+lng+"", Toast.LENGTH_SHORT).show();
}
};
Moreover, some of the details that I might think matter after some research. I haven't declared receiver in the manifest because I read that you only do that when you want your application to launch when the broadcast is received but I only want my application to react when it is already running. Not launch whenever the services sends a broadcast.
And I haven't extended the activity to BroadcastReceiver either since the activity is already extended to FragmentActivity
The app does not crash and onLocationChanged is located inside the service that is being started after the BroadcastReceiver is registered so onLocationChanged is not invoked before the BroadcastReceiver has been registered
I managed to solve the issue. I will post my findings and the answer for anyone else faced with this issue in the future. I have probably dumbed down a lot of concepts here but for the purpose of understanding this specific problem I'll try to be accurate to the best of my understanding.
The Answer:
The problem was that I was not sending the Broadcast and receiving the broadcast with the same Context. What I mean by that is, this is how I had declared my service in the Manifest file
<service
android:name=".GoogleFusedLocationApiService"
android:process=":google_fused_location_api_service"/>
The android:process attribute meant that this service would run on a different process from the process that the app is running on. So when I was calling, super.registerReceiver(mMessageReceiver, intentFilter); it was being called from the context of the Activity and when I was calling broadcaster = LocalBroadcastManager.getInstance(this); broadcaster.sendBroadcast(intent); here sendBroadcast is being called from the context of the service which has a different process running for it. So you see I was registering the receiver from a different context and sending broadcast from a different context.
LocalBroadcastManager only works when the broadcast is being sent and received from the same process i.e., context. So in this case, since my service and my app/activity are running or separate processes i.e., contexts I cannot use LocalBroadcastManager. I need to use the Global broadcasts and make sure that I am registering the broadcast and sending the broadcast from the same context.
Now since the I have a static context of the app that I can use anywhere by simply calling, MyApp.getAppContext() which you can learn how to do from this answer now if I register the broadcast receiver and send broadcasts using this context, that means both are done from the same context which is MyApp.getAppContext() and now I begin to receive broadcasts successfully.
So to sum it up, if you have separate process for your service, use MyApp.getAppContext().registerReceiver() and MyApp.getAppContext().sendBroadcast()
If you have the same process for your service or don't have the android:process attribute in your service tag in Manifest file, then you can use LocalBroadcastManager.getInstance(this).registerReceiver() and LocalBroadcastManager.getInstance(this).sendBroadcast().
You can still use MyApp.getAppContext here but using LocalBroadcastManager is the best practice and the proper way of doing things in the second case.

Android: Intent Extras not passed with startActivity() outside Activity context

I have a class that listens to SMS broadcast and, it then open an activity in the same application to display the message. This is part of a larger project.
Since the broadcast class does not extend the activity class, calling an Activity with intent requires that I flag it with Intent.FLAG_ACTIVITY_NEW_TASK.
Now the Intent has an extra (the SMS message and some parameters as a single string) which i want to send with the intent. All went well but the Extras are not sent with the intent.
Here are my code
From the broadcast class
//After getting the message into String S and doing some process
Intent inte = new Intent(context.getApplicationContext(), StartApp.class);
inte.putExtra("messageAsString", S.toString()); //Where S is declared somewhere
inte.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(inte);
From the activity recieving the Intent in the onCreate() method
if(getIntent().hasExtra("messageAsString")) {
String message = getIntent().getStringExtra("messageAsString").toString();
Toast toast = Toast.makeText(this, "Received SMS: " + message , Toast.LENGTH_LONG);
toast.show();
}
The application may have already running, the home button has been pressed. Either way, what I want to achieve is that as the registered reciever receives the message, I want to start an activity automatically and pass the message and its meta data to it.
I know I'm missing something somewhere but will appreciate your swift help
You also need to handle onNewIntent(), which may be called if the activity already exists and startActivity() brings an existing instance back to the foreground. Your extra is probably in there.

Categories