How to call IntentService from WakefulBroadcastReceiver - android

I have an IntentService defined as below:
<service android:name=".service.AppService" android:process=":app_process" android:icon="#mipmap/ic_launcher" />
I have a WakefulBroadcastReceiver that receives some data and I would like to call my already running service above. The service above is always running, even if it is killed, it restarts. How can I pass messages to that?
I read the following:
http://www.mysamplecode.com/2011/10/android-intentservice-example-using.html
http://www.truiton.com/2014/09/android-service-broadcastreceiver-example/
http://developer.android.com/guide/components/services.html
I tried to do a startService, PendingIntent among other things and nothing seems to work.

First of all, remember that an IntentService works in a different worker thread, there for it's not possible to have intercommunication with the Activity that invoked it. That's why mostly we use them for synchronization on background where feedback to the user is not needed. However, if you want to pass some information to the Activity, you have to use a BroadcastReceiver as you said, and from there create the Intent that will send "data" to the Activity.
Going back to your question, you have to add the service and the receiver in your AndroidManifest.xml inside the <application> tag
<service android:name=".AppService"
android:enabled="true"/>
<receiver android:name=".WakefulBroadcastReceiver" >
</receiver>
Then in your Activity launch the service like this (whenever you need it, in the onCreate, or in a button listener)
IntentFilter filter = new IntentFilter(WakefulBroadcastReceiver.ACTION_RESP);
filter.addCategory(Intent.CATEGORY_DEFAULT);
WakefulBroadcastReceiver broadcastReceiver = new WakefulBroadcastReceiver();
registerReceiver(broadcastReceiver, filter);
In your BroadcastReceiver you override the onReceive() method like this:
#Override
public void onReceive(Context context, Intent intent) {
// HERE IS WHERE YOU RECEIVE THE INFORMATION FROM THE INTENTSERVICE, FROM HERE YOU CAN START AN ACTIVITY OR WHATEVER YOU AIM
Toast.makeText(context, "IntentService Broadcasting", Toast.LENGTH_SHORT).show();
}
Also in the same BroadcastReceiver add this variable that identifies the intentfilter:
public static final String ACTION_RESP = "MY_FILTER_NAME"
In your IntentService class you have to override the onHandleIntent() method like this:
#Override
protected void onHandleIntent(Intent intent) {
String msg = intent.getStringExtra("MSG");
Intent broadcast = new Intent();
broadcast.setAction(WakefulBroadcastReceiver.ACTION_RESP);
broadcast.addCategory(Intent.CATEGORY_DEFAULT);
broadcast.putExtra("MSG", resultTxt);
// HERE IS WHERE YOU SEND THE INFORMATION YOU LOADED TO THE APP
sendBroadcast(broadcast);
}
I have a demo project in my GitHub account here, where I use bound and unbound services and IntentServices:
https://github.com/isaacurbina/PermissionsAndServices
I hope it helps.
Kind regards!

You can write this in your class that extends WakefulBroadcastReceiver :
#Override
public void onReceive(Context context, Intent intent) {
Intent gcmIntent = new Intent(context, MessageService.class);
gcmIntent.putExtras(intent.getExtras());
startWakefulService(context, gcmIntent);
setResultCode(Activity.RESULT_OK);
}
And write this in your class that extend IntentService :
#Override
protected void onHandleIntent(Intent intent) {
Bundle bundle = intent.getExtras();
//do sth with that data
MessageReceiver.completeWakefulIntent(intent);
}

Related

Android Change a variable in service from other app

the title says all, I need to change the variable of my service from a activity in my other app , what to finalize the service or not, this is possible?
I found the Message object , but I do not quite understand
The simplest solution would be to implement a BroadcastReceiver. Your Service listens for the Broadcast and the other App sends the Broadcast.
Example Reciever:
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Get bundle from intent and use it to set your Variable in your Service
}
}
Example Broadcaster (courtesy of Vogella):
Intent intent = new Intent();
intent.setAction("de.vogella.android.mybroadcast");
sendBroadcast(intent);

Stopping a Service from Activity

I have problem with stopping a service from activity.
Declaration of my service:
public class MyService extends Service implements LocationListener { .. }
This service is called when the button is pressed:
public void startMyService(View view)
{
ComponentName comp = new ComponentName(getPackageName(), MyService.class.getName());
ComponentName service = startService(new Intent().setComponent(comp));
}
In another method (launched by button click) I want to stop it:
public void stopMyService(View view)
{
stopService(new Intent(this, MyService.class));
}
Unfortunately, it is not working. It seems to me that this service is replaced by another one. Furthermore, it´s cumulating - for example, when I start the service for the second time, there are two of them, running, etc. Could somebody help me? Thanks in advance for your help.
UPDATE : Android Manifest (only my service):
<service android:name=".MyService"
android:enabled="true"
android:exported="false"
android:label="LocationTrackingService"
/>
You could add a BroadcastReceiver to your service (or a static method - depending on your preferences) and call Context.stopService() or stopSelf(), e.g. add ...
public static String STOP_SERVICE = "com.company.SEND_STOP_SERVICE";
private final BroadcastReceiver stopReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(STOP_SERVICE)){
MyService.this.stopSelf();
}
}
};
... to your service (assuming it's called MyService). Then call registerReceiver(stopReceiver, STOP_SERVICE); in the onStartCommand() method and unregisterReceiver(stopReceiver); in onDestroy(). Finally send the broadcast from anywhere you need to stop the service:
Intent intent=new Intent();
intent.setAction(MyService.STOP_SERVICE);
sendBroadcast(intent);
If you have some threads you have to stop them before (probably you have and you started the service sticky, did you?)

Update the UI of the calling activity or start a new activity when the alarm is triggered from a broadcast receiver

I am writing an alarm code and using a broadcast receiver. I am able to receive the broadcast receiver. but now I want to come back to the calling activity and update the UI of my activity. I am not able to this.
I used the following code in my activity but it is never executing that code.
private BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "I am back!!", Toast.LENGTH_LONG).show();
}
};
#Override
protected void onPause()
{
super.onPause();
unregisterReceiver(myBroadcastReceiver);
}
#Override
protected void onResume()
{
super.onResume();
IntentFilter intentFilter = new IntentFilter("com.test.Main");
registerReceiver(myBroadcastReceiver, intentFilter);
}
in the manifest file I have included the following, here gotAlarm is the broadcast receiver file
<receiver android:name=".gotAlarm"
android:enabled="true">
</receiver>
gotAlarm file is one which gets called from the pending intent of the alarm set
public class gotAlarm extends BroadcastReceiver {
public void onReceive(Context context, Intent intent){
Toast.makeText(context, "Wake Up!!", Toast.LENGTH_LONG).show();
}
}
May be I am missing something very basic.
please help.
Two things:
If you dynamically register the receiver via Context.registerReceiver() then you won't receive broadcasts when Activity is paused (or stopped or not-running). If you need to receive broadcasts even when Activity is paused then create a top-level BroadcastReceiver class (as opposed to your inner class) and use <receiver> to register it.
BroadcastReceiver lifecycle docs state that BroadcastReceiver object is alive only during processing of onReceive(). You can not do any async tasks like showing dialogs, etc.. In your case (Activities might not be running and you receive a broadcast) you should use NotificationManager to notify user something happened.
I have dropped this way and I am starting a new activity on receiving broadcast. And I am sending information data from calling activity to broadcast and from broadcast to next activity. This has served the purpose.
Did you register your BroadcastReceiver (you can do this in the 'onResume'-method of your Activity)? Also, you should unregister your BroadcastReceiver in the 'onPause'-method.

service displays points on map android

i have a android service running in the background which receives the coordinates from the server every few seconds. i am not sure how do i display the coordinates on a map every time the service receives a response from the server. kindly help or give an idea.
thanks
I don't know any tutorials on this, but here's a version of mine:
To send a broadcast, you use the 'sendBroadcast(Intent i)' method of the Context class. The Service class extends Context, so you can access it from your implementation.
So in your Service goes:
public static final String BROADCAST_ACTION="com.yourservice.update";
public void onStart( Intent intent, int startId ) {
...
Intent broadcastIntent = new Intent(BROADCAST_ACTION);
sendBroadcast(broadcastIntent);
...
}
You have to register a receiver for this broadcast in you Activity (possibly before you start boradcasting them), like this:
private BroadcastReceiver receiver=new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
//Here goes handling the stuff you got from the service
Bundle extras = intent.getExtras();
if(extras != null)processUIUpdate(extras);
}
};
public void onResume() {
...
//Register for the update broadcasts from the torrent service
registerReceiver(receiver, new IntentFilter(YourService.BROADCAST_ACTION));
...
}
Don't forget to deregister when the Activity goes background:
public void onPause() {
...
//Deregister for the update broadcast from the torrent service
unregisterReceiver(receiver);
...
}
This should work.
Your service could broadcast intents whenever it wants to update the displayed location on the map. The Activity displaying the map should register a receiver for that boradcast, and the boradcast's intent can hold the values for lat. and long.

Android-Broadcast Receiver and Intent Filter

I am new to android platform.please help me out how the Broadcast Receiver and Intent Filter behaves in android.please explain in simple line or with example.thanks in advance...
A broadcast receiver is a class in your Android project which is responsible to receive all intents, which are sent by other activities by using android.content.ContextWreapper.sendBroadcast(Intent intent)
In the manifest file of you receicving activity, you have to declare which is your broadcast receiver class, for example:
<receiver android:name="xyz.games.pacman.network.MessageListener">
<intent-filter>
<action android:name="xyz.games.pacman.controller.BROADCAST" />
</intent-filter>
</receiver>
As you can see, you also define the intent filter here, that is, which intents should be received by the broadcas receiver.
Then you have to define a class which extends BroadcastReceiver. This is the class you defined in the manifest file:
public class MessageListener extends BroadcastReceiver {
/* (non-Javadoc)
* #see android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent)
*/
#Override
public void onReceive(Context context, Intent intent) {
...
}
Here, all intents which are passed through the filter are received and you can access them using the parameter passed in the method call.
A BroadcastReceiver can be registered in two ways: dynamic or static. Static is nothing but declaring the action through an intent-filter in AndroidManifest.xml to register a new BroadcastReceiver class. Dynamic is registering the receiver from within another class. An intent-filter determines which action should be received.
To create a BroadcastReceiver, you have to extend the BroadcastReceiver class and override onReceive(Context,Intent) method. Here you can check the incoming intent with Intent.getAction() and execute code accordingly.
As a new class, static would be
public class Reciever1 extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String str = intent.getAction();
if(str.equalsIgnoreCase("HELLO1")) {
Log.d("Abrar", "reciever....");
new Thread() {
public void run() {
Log.d("Abrar", "reciever....");
System.out.println("Abrar");
}
}.start();
}
or, if placed inside an existing class, it is called dynamically with
intentFilter = new IntentFilter();
intentFilter.addAction("HELLO1");
//---register the receiver---
registerReceiver(new Reciever1(), intentFilter);
BroadcastReceiver : 'Gateway' with which your app tells to Android OS that, your app is interested in receiving information.
Intent-Filter : Works with BroadcastReceiver and tells the 'What' information it is interested to receive in. For example, your app wants to receive information on Battery level.

Categories

Resources