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);
Related
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);
}
I have an application that using "AlarmService". For handling alarms i have a Broadcast receiver. That receiver has to start certain activity. Code i'm using for achieving that is following:
#Override
public void onReceive(Context context, Intent intent) {
...other code....
Intent intIntent = new Intent(context, MainActivity.class);
intIntent .putExtra("IsAlarm", true);
Intent alarmChooser = Intent.createChooser(intIntent , "Alarm");
alarmChooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(alarmChooser);
}
That works but only if activity isn't shown already (if it's not in the foreground). If called activity is already opened nothing happens. How can i overcome that?
Is there a flag that will start the activity if it's not started OR send intent to it even if it's in the foreground?
P.S. i tried using dedicated "broadcast" above the provided code. Reciever for that broadcast is registered programmatically in the MainActivity: "onResume" would register dedicated receiver, "onPause" would unregister it. That way in case MainActivity is already on it will receive a broadcast but then i have a problem when phone goes to "stand by" - "dedicated" receiver is unregistered.
Check in the activity onNewIntent callback
there should be the new intent from the receiver
I think you don't need the chooser:
#Override
public void onReceive(Context context, Intent intent) {
Intent intIntent = new Intent(context, MainActivity.class);
intIntent.putExtra("IsAlarm", true);
context.startActivity(intIntent);
}
i am new to Android and trying to understand the communication between apps.
I am trying to write 3 little apps which can communicate with each other. If you want to sent a message to everybody you just use an implicit broadcast.
implicit Intent intent.setAction("com.example.myChatMessage")
if you want to adress only 1 specifc receiver i did it with
explicite Intentintent.setComponent("com.example.test.android.broadcastreceiver.b",
"com.example.test.android.broadcastreceiver.b.myBroadcastReceiver")
this works, when the broadcast receiver is a seperate class and defined in the AndroidManifest.xml.
My Question: Is it possible to explicit adress a dynamicall registered broadcast receiver?
package com.example.test.android.broadcastreceiver.b;
public class MainActivity extends Activity {
private final IntentFilter intentfilter = new IntentFilter("com.example.myChatMessage");
private myBroadcastReceiver broadcastreceiver;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
broadcastreceiver = new myBroadcastReceiver();
registerReceiver(broadcastreceiver, intentfilter);
}
public static class myBroadcastReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
String message = intent.getStringExtra("message");
Log.d("message", "B received: "+message);
}
}
}
It receives all implicit broadcasts but no explicit one - i don't know hot to adress it. Can you help me?
It does not appear possible to send an explicit intent to a dynamically registered broadcast receiver. Registering the receiver in AndroidManifest.xml is the only way.
If you dynamically register a BroadcastReceiver – by calling Context.registerReceiver() – you supply a BroadcastReceiver instance ... If you try to send an Intent to the receiver by naming the class of the BroadcastReceiver, it will never get delivered .. The Android system will not match the Intent you declared to the class of the BroadcastReceiver instance you registered.
Source: http://onemikro2nd.blogspot.com/2013/09/darker-corners-of-android.html
on a broadcast I want to call a non static method from Service XYZ. The Service is start by the receiver on boot.
Has someone a idea to run methods from this running service?
One solution in this forum is to make the method static and use a singleton pattern to execute. But is there another method? Maybe with a binder?
//EDIT for example i have the following clases:
public class MyService extends Service{
.....
public void method(){
//TODO
}
}
public class MyBroadcastReceiver extends BroadcastReceiver{
.....
public void onReceive(Context context, Intent intent) {
String intentAction=intent.getAction();
if(intentAction.equals(Intent.ACTION_BOOT_COMPLETED)){
//start service
Intent serviceIntent = new Intent(context, MyService.class);
context.startService(serviceIntent);
}
else{
//TODO call method() in MyService
}
}
how can i call the method method()? I know that i can cast with context.getSystemService() system services. But how can i get my own service object?
greetings
You can add an action string to your intent using setAction in the intent that launches the Service. In your service's onStartcommand you can extract the intent's action, and based off that you can execute the method in your service.
You will always send commands to your service using startService this will not launch your service twice. It will either get started once, or the new intent is sent to the service.
So, in your on boot completed section you should set the intent action to whatever you want, and start the service - you can remove the else block completely.
In your Service implement the onStartCommand, extract the intent's action, and based off that action you can just execute your method.
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.