I have a foreground service uploading images and broadcasting status using intent with action "myAction".
My app needs to react on the broadcast, like send a server request after receiving success message or pop up a notification after receiving failure message. I'm following this https://developer.android.com/training/run-background-service/report-status.html
Sending an broadcast Intent doesn't start or resume an Activity. The
BroadcastReceiver for an Activity receives and processes Intent
objects even when your app is in the background, but doesn't force
your app to the foreground. If you want to notify the user about an
event that happened in the background while your app was not visible,
use a Notification. Never start an Activity in response to an incoming
broadcast Intent.
I first try to register my broadcast receiver statically in Manifest. It doesn't work. Then, I follow this instruction, Keep broadcast receiver running after application is closed, to start a service to register my broadcast receiver. Both don't work(no log shows) when I swipe out or close the app.To be specific, I can see "HAHAHAHA" and "HEHEHEHE" logs come out when is in the foreground. It doesn't come out once I swipe it out from app lists or click back to exit the app.
Here is my code. Where do I miss?
In my manifest
<application...>
<receiver android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="false">
<intent-filter android:priority="0">
<action android:name="myAction"/>
</intent-filter>
</receiver>
<service
android:name=".MyService"
android:exported="false"/>
</application>
MyBroadcastReceive.java
public class MyBroadcastReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Log.d("HAHAHAHA", "Broadcast received.");
}
}
MyService.java
public class MyService extends Service {
BroadcastReceiver mReceiver;
// use this as an inner class like here or as a top-level class
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// do something
Log.d("HEHEHEHE", "Broadcast received.");
}
}
#Override
public void onCreate() {
// get an instance of the receiver in your service
IntentFilter filter = new IntentFilter();
filter.addAction("myAction");
mReceiver = new MyReceiver();
registerReceiver(mReceiver, filter);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
Log.d("HEHEHEHE", "onDestroy");
super.onDestroy();
}
}
MainActivity.java
onStart() {
Intent intent = new Intent(this, MyService.class);
startService(intent);
}
Broadcast is called like below:
LocalBroadcastManager.getInstance(service).sendBroadcast(intent);
I first try to register my broadcast receiver statically in Manifest. It doesn't work.
You cannot use manifest-registered receivers with LocalBroadcastManager. Only receivers registered via LocalBroadcastManager.getInstance().registerReceiver() will respond to local broadcasts.
My app needs to react on the broadcast, like send a server request after receiving success message or pop up a notification after receiving failure message.
Get rid of the broadcast and do that work in the service.
Related
I have a widget that should start a broadcast receiver when it is created.
This receiver handles widget update when there was a battery change.
This is my code:
AppWidgetProvider code:
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
broadcastReceiver = new BatteryInfo();
IntentFilter mIntentFilter = new IntentFilter();
mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
context.getApplicationContext().registerReceiver(broadcastReceiver, mIntentFilter);
}
BroadcastReceiver code
public class BatteryInfo extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
// some actions...
}
}
This works correctly after widget is added. Widget's onUpdate is called, then receiver keeps getting called when there is change in battery state.
Problem begins after device is rebooted. After device is back on, after few seconds widget reinitializes itself, again Widget's onUpdate is called, then receiver is called twice and instantly dies. This appears in logcat right after that:
1950-3391/? I/ActivityManager: Process [my process name] (pid 7752) has died: cch+4CEM
1950-2013/? W/BroadcastQueue: Background execution not allowed: receiving Intent { act=android.intent.action.ACTION_POWER_DISCONNECTED flg=0x4000010 (has extras) } to [my process name]/.BatteryInfo
1950-2013/? W/BroadcastQueue: Background execution not allowed: receiving Intent { act=android.intent.action.ACTION_POWER_CONNECTED flg=0x4000010 (has extras) } to [my process name]/.BatteryInfo
Why does it matter if widget was reinitialised after reboot?
How can I ensure my receiver stays alive as long as widget is on screen?
Have you forgot to Unregister your BroadCastReceiver? please check and if you have not Unregistered your broadcastReciever than do it.
This is expected.
After reboting your device, all listeners are deleted and you should register them again. In this case, you need to listen to BOOT_COMPLETE events to register your broadcast again.
Something like:
AndroidManifest.xml:
<manifest>
...
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
...
<application>
...
<!-- UPDATE YOUR BatteryInfo RECEIVER WITH the INFO BELOW -->
<receiver
...
android:permission="android.permission.RECEIVE_BOOT_COMPLETED"
android:exported="true">
<intent-filter>
...
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
BatteryInfo.java
public class BatteryInfo extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if("android.intent.action.BOOT_COMPLETED".equals(action) {
Log.v("BatteryInfo", "Boot completed. Registering to battery info events");
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
context.getApplicationContext().registerReceiver(this, intentFilter);
} else if() {
Log.v("BatteryInfo", "Battery event");
// Some Actions
} else {
Log.e("BatteryInfo", "Action not expected: " + action);
}
}
}
I'm using the following library to read the sms messages that have been sent from my default application. The problem that I'm having is that when the application is close the service is not working to save the message that i have send. Does anyone knows how i can start the service when a message has been sent from my device?
Library
https://github.com/tuenti/SmsRadar
UPDATE 1:
BroadcastReceiver class
public class Broadcast_Receiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("android.provider.Telephony.SMS_SENT")){
Intent service = new Intent(context, SMSService.class);
context.startService(service);
Log.d("Broadcast_Receiver", "message sent");
}
else if ((intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")))
{
Log.d("Broadcast_Receiver", "message received");
}
}
}
manifest
<receiver android:name=".APPServices.SMS.Broadcast_Receiver" android:enabled="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_SENT"/>
</intent-filter>
</receiver>
Thank you
You'll need to use a "Broadcast Reciever" for that
As the name suggests: broadcast receiver waits for an event to occur and when the event occurs , it receives that info, which was broadcast-ed by the event.
Here is a great tutorial which describes how to implement it step by step (A little long to type it here)
http://androidexample.com/Incomming_SMS_Broadcast_Receiver_-_Android_Example/index.php?view=article_discription&aid=62&aaid=87
I'm very new to Android and Programming in general, so I'm playing around with different
tutorials and info gathered here on stackoverflow.
What I would like to accomplish, is having the app with my SMS BroadcastReceiver run as a service, so I can get all the SMS broadcasts when app is in the background.
Also, how can I add a BroadcastReceiver for receiving broadcast of BOOT_COMPLETED and start app automatically?
Would I need several services for this, or is 1 service sufficient? (for detecting SMS + BOOT_COMPLETED continuously)
Currently I have a created a BroadcastReceiver for getting SMS, like this;
public class SMS extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
.. etc ..
.. etc ..
}
and my AndroidManifest.xml file has receiver and intent-filter with the
additional android.provider.Telephony.SMS_RECEIVED
Getting the SMS broadcast works fine, but I'm not sure where to go from here.
All help is much appreciated :)
Thanks.
To start your service on BOOT_COMPLETED event and to receive SMS intent continuously.
AndroidManifest.xml:
<receiver android:name="BootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
BootReceiver.java:
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, SMSService.class);
context.startService(service);
}
}
SMSService.java:
public class SMSService extends IntentService {
#Override
protected void onHandleIntent(Intent intent) {
String action = intent.getAction();
if (Intent.BOOT_COMPLETED.equals(action)) {
//write your code to process BOOT_COMPLETED intent here
}
else if(Intent.SMS_RECEIVED.equals(action)) {
//Write your code for processing SMS intent here
}
}
}
As, Fildor has pointed out, it is unnecessary to start service on BOOT_COMPLETED intent. InentService would do the work. So, above two code snippets are not required. Just the last snippet would do the work.
I have BroadcastReceiver (NetworkListener).
public class NetworkReceiver extends BroadcastReceiver {
Context context;
public static NetworkReceiver instance = new NetworkReceiver();
public static InnerObservable observable = instance. new InnerObservable();
...
This receiver sends notifications:
#Override
public void onReceive(Context ctx, Intent intent) {
Log.d("tag", "onReceive");
NotificationManager notif = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(android.R.drawable.ic_dialog_alert,"bla-bla-bla",System.currentTimeMillis());
Manifest file:
<receiver
android:name="com.mypckg.network.NetworkReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
It works fine. But after phone reboot, it continues to work. how to avoid it?
If you want your broadcast receiver to start working when application gets launched then you should register/unregister it programatically from your main activity:
private BroadcastReceiver networkReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
networkReceiver = new NetworkReceiver();
registerReceiver(networkReceiver, ConnectivityManager.CONNECTIVITY_ACTION);
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(networkReceiver)
}
You can mess around with the PackageManager to disable a BroadcastReceiver registered in your manifest, check this thread for code.
Another solution would be to register this receiver dynamically, possibly in a service. The receiver would be active and registered as long as the service is alive, so you could easily toggle the receiver by starting/stopping the service. This might not fit you use case however, you didn't provide much detail on that.
I am trying to start up a BroadcastReceiver within a Service. What I am trying to do is have a background running service going that collects incoming text messages, and logs incoming phone calls. I figured the best way to go about this is to have a service running that incorporates a broadcast receiver that can catalog either.
How do i go about doing this? I already have my service up and running.
as your service is already setup, simply add a broadcast receiver in your service:
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals("android.provider.Telephony.SMS_RECEIVED")){
//action for sms received
}
else if(action.equals(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED)){
//action for phone state changed
}
}
};
in your service's onCreate do this:
IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
filter.addAction(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED);
filter.addAction("your_action_strings"); //further more
filter.addAction("your_action_strings"); //further more
registerReceiver(receiver, filter);
and in your service's onDestroy:
unregisterReceiver(receiver);
and you are good to go to receive broadcast for what ever filters you mention in onCreate. Make sure to add any permission if required. for e.g.
<uses-permission android:name="android.permission.RECEIVE_SMS" />
The better pattern is to create a standalone BroadcastReceiver. This insures that your app can respond to the broadcast, whether or not the Service is running. In fact, using this pattern may remove the need for a constant-running Service altogether.
Register the BroadcastReceiver in your Manifest, and create a separate class/file for it.
Eg:
<receiver android:name=".FooReceiver" >
<intent-filter >
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
When the receiver runs, you simply pass an Intent (Bundle) to the Service, and respond to it in onStartCommand().
Eg:
public class FooReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// do your work quickly!
// then call context.startService();
}
}