I have a service, that starts an activity like this:
Intent i = new Intent();
i.setClass(this, MyActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
How to inform the service, that MyActivity has finished?
Any hints appreciated,
Marcus
in OnDestroy method of the activity, either you can invoke a method of the service, if you have service class object, if you don't have, Use Broadcast Receiver, to send some message, to Service, and in Service implement that Broadcast Receiver.
Related
I'm using service to run Bluetooth in background,but i don't no how to send data from another activity to service
Service and other activities work in the same process
To start a Service, use following statement:
Intent intent = new Intent(context, Service.class);
// intent put some extra
startService(intent);
Calling this statement firstly, Service call onCreate() method and onStartCommand().
Not firstly, Service just call onStartCommand().
You can check if it is called firstly by extra in intent.
So you can send data with the same method startService(Intent intent).
Service works in another process
use [bindService](https://developer.android.com/reference/android/content/Context.html#bindService(android.content.Intent, android.content.ServiceConnection, int)) and AIDL
It is suggested that make service and other activities work in the same process when your target is not complex.
I am bit new to android. I would like to know how to communicate with a foreground started service.
So, I got a Foreground service with a notification.
This notification has a (X) button to stop the service.
The service got a Static broadcastreceiver.
public static class NotificationStopButtonHandler extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"Close Clicked",Toast.LENGTH_SHORT).show();
Log.i(LOG_TAG, "In Closed");
// imposible to do context.stopForground(true) or
// to call any other private coded by me
}
}
So my question is :
Is BroadcastReceiver is the best way ?
If it is : How I can communicate with the service to call stopForeground in the broadcastReceiver ?
Thanks in advance for your responses.
Same question like mien... But I would like to know which are the other solution than broadcastReceiver. thx
In your notification you will have a PendingIntent for the X button. I presume you have built that PendingIntent with
PendingIntent.getBroadcast(/* ... */);
What you can do instead is to create a PendingIntent for your service
Intent intent = /* intent for starting your service */;
intent.putExtra("STOP_FOREGROUND", true);
PendingIntent.getService(context, requestCode, intent, flags);
and in the intent you pass to the PendingIntent you would add an extra (STOP_FOREGROUND). When this intent is fired, your service will get called in onStartCommand(). Here you check the intent and if it contains your extra, you know you're expected to call stopForeground.
Instead of broadcasts, you can use PendingIntent with an Intent to the Service and tell the Service to shut down. You assign the PendingIntent to the close button action and/or to the notifications onDelete call when you build the notification.
Assuming that you're starting the Service with the notification, you can put commands in the Intent to tell the service to stop itself. Service#onStartCommand will be called on the service with the new Intent. The service checks for the shutdown call and calls stopSelf() when done.
Basically, the reason this works is because there can only be one Service started. Every subsequent attempt to start the service will send the intent to Service#onStartCommand, but it will not restart the Service. Thus, this is a way you can send commands to the service through means outside of binding. Plus it's way cleaner than using broadcasts.
The task is to process somehow "share" intent in already running service.
As far as ACTION_SEND is an activity action we have to pick up intent in activity and broadcast it to service.
The problem is that it's logically to implement all "share intent" processing in service and use activity only for broadcasting intent.
So the service have to receive the intent (which previously received and broadcasted by activity) so we can call getType() and get****Extra***() to it in order to know what was actually shared and process this data somehow.
The intent we received in activity has the action ACTION_SEND (or ACTION_SEND_MULTIPLE), right? So logically we can change action with calling setAction() to intent object and broadcast it to our service which is already listening to this particular action.
public class HandleShareIntentActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
Intent broadcastIntent = new Intent(intent);
// If I initialize empty intent there is no problem,
// I'll receive it in service
// Intent broadcastIntent = new Intent();
broadcastIntent.setAction(Constants.ACTION_SHARE);
broadcastIntent.setFlags(0);
sendBroadcast(broadcastIntent);
finish();
}
// ...
}
But that is not working, I'm not receiving this intent in service.
If I don't copy intent I got and broadcast an empty one, I do receive it in my service.
What I'm doing wrong?
First, to start a service, call startService(), not sendBroadcast(). There is no reason to have the service respond to broadcasts, and you are adding security problems to your app by doing so.
Second, you have to call startService() on an Intent that will identify your service (e.g., new Intent(this, ThisIsTheService.class)). In your case, you are taking an Intent identifying an activity, using a copy constructor to make a copy of it, changing the action string, and then trying to use that.
And, since an Intent is Parcelable, you could just add it as an extra to a service-specific Intent:
startService(new Intent(this, ThisIsTheService.class).putExtra(EXTRA_SEND, getIntent()));
and your service can pick EXTRA_SEND out in onHandleIntent() (if it is an IntentService) or onStartCommand() (if it is not). This code snippet assumes that you define EXTRA_SEND to be some string somewhere.
I have used the method finish() before in several activities without problems.
however when I tried to call it inside of the broadcast receiver I get the error message from the compiler that "the method finish() is undefined for the type AudioService"
AudioService is the name of my Service class in my Android app.
If there is no finish() method in a Service than what can I call to kill this Service dead?
use this line:
this.stopSelf();
to kill itself.
Or from outside use stopService(intent);
you can try as to stop your AudioService service from broadcast receiver :
Intent intent = new Intent();
intent.setClass(context, AudioService.class);
context.stopService(intent);
where context is first param which you received in on Receive of broadcast receiver
I have an activity class that contains a button. When I click the button it starts a service that will populate my SQLite database in a separate thread. Once the service completes I would like a textview in my activity class to display a new value from the database.
I have everything set up correctly and my database is storing the correct info. The only thing I am still confused on is how do I tell my activity class that the service is complete?
You can send a broadcast when your service completes.
In your activity onResume
IntentFilter intentFilter = ; //Look up how to make an intent filter with an action as specified in the below service code
receiver =new BroadcastReceiver();
this.registerReceiver(receiver, intentFilter);
In your activity onPause
this.unregisterReceiver(receiver);
In your service.
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.blablablaablla.ACTION_REFRESH");
this.sendBroadcast(broadcastIntent);
Create an Intent with your own action name "mike.intent.DB_POPULATE_DONE" or something... it's just a string you can examine in onNewIntent() if you choose to.
Send an Intent from the Service by calling Context.startActivity().
To receive the Intent, implement Activity.onNewIntent()