how to call a service from an activity? - android

I have a service which starts an activity by
Intent dialogIntent = new Intent(getBaseContext(), dialog.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(dialogIntent);
But I'm not sure how to pass a call when this new activity finishes to the service?
Note that "startActivityForResult" does not work from a service. ;)
On the other hand, maybe there is some "when focus comes back" listener for the service?
Thanks!
edit:
activity finishes by
Intent dialogIntent = new Intent(getBaseContext(), TotalKeyboard.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(dialogIntent);
finish();
yet this, in service, doesn't get the call
#Override public void onStart(Intent intent, int startid)
{
Toast.makeText(getApplicationContext(), "aaa!", Toast.LENGTH_SHORT).show();
}

when you try to start service which is already running then it's onCreate method does not get the call but it's onStart() methods gets the call......you can use this property to meet your need...

You never get foucs on a Service. I'm not sure what you are trying to achieve, and maybe this is not the best solution but you can bound from you Activity to the Service and declare a method in your Service class and then you can call that method from your Activity, after you are bound to your service.
EDIT: You can simulate a dialog show from a Service by creating an Activity that looks like a dialog. You can do this by setting the theme attribute in your AndroidManifest.xml:
<activity
android:name="myPackages.ui.DialogActivity"
android:theme="#android:style/Theme.Dialog"
android:launchMode="singleInstance"
android:excludeFromRecents="true"
android:finishOnTaskLaunch="true" />
You can declare a method in your Service let's say:
public void performAction(boolean userChoice){
//implementation
}
and in your DialogActivity class you can bound to your Service class and on the press of a button you can call :
mBoundService.performAction(true);
or
mBoundService.performAction(false);
based on the user choice.

In Short , Activity itself has to take care of this.

Related

Is it possible to make intent not to start a new activity, but only be received by existing one?

I want to send an Intent from a service by startActivity(...) method.
I also want this intent to be received if the Activity is running (and/or paused)
If activity not running, I do not want to start it, I want the intent just get lost.
Is it possible to implement such behavior?
Have your activity register a BroadcastReceiver in onCreate() and unregister it in onPause(). That will ensure that your receiver is only active for the duration of your activity.
public void onStart() {
mBroadcastReceiver = new MyBroadcastReceiver(...);
registerReceiver(mBroadcastReceiver, filter);
}
...
public void onPause() {
unregisterReceiver(mBroadcastReceiver);
registerReceiver is defined in Context.
If activity not running, I do not want to start it,
I don't know about the part, but if you don't want to create another instance of the same activity when there is already one running, you may want to try android:launchMode="singleTask" on your Manifest:
<activity
android:name=".MyActivity"
android:launchMode="singleTask"/>

android : How to work around the fact that a singleInstance activity cannot expect to rely onActivityResult when starting subActivity?

I am making an android application, which has the following execution flow:
A service registers a PendingIntent with the AlarmManager
When the alarm is launched, a Receiver receives the intent, and (given some conditions) calls startsActivity() for my Main Activity, which in the manifest has been declared as android:launchMode="singleInstance". Note that for this call to work, the intent passed should have an Intent.FLAG_ACTIVITY_NEW_TASK
When started, Main Activity modifies itself a bit, and calls startActivityForResult for an Activity, which we'll call WebviewActivity (because it contains a webview, but that's besides the point)
When the user is done interacting with theWebViewActivity, setResult() and finish() are called on it, and one would expect for MainActivity.onActivityResult() to be called.
But of course this does not happen, as has been documented in many discussions here, the reason apparently being that an Activity launched from a singleInstance Activity, runs in a different Task.
A solution I think would be to have the WebActivity start the MainActivity instead.
The question is, is there a way to maintain onActivityResult being called at the right time? In that case, which aspects from the starting point of the execution flow should change?
Please note that MainActivity should not have multiple instances at the same time (it is basically an interface to the service) but if its launchMode is set to standard, the Receiver, because of the FLAG_ACTIVITY_NEW_TASK that is required, will do just that.
Manifest declaration of MainActivity:
<activity android:name=".activities.MainActivity"
android:label="#string/app_name"
android:launchMode="singleInstance"
android:configChanges="keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
android:uiOptions=”splitActionBarWhenNarrow”
</activity>
Receiver launches MainActivity by calling
onReceive(Context context, Intent intent)
{
intent.setClass(context, MainActivity.class);
int flag = Intent.FLAG_ACTIVITY_NEW_TASK;
intent.setFlags(flag);
context.startActivity(intent);
}
I use the following workaround for this problem:
Activity A is the caller
Activity B is the singleInstance activity from which I want the result
In activity A I register a broadcast receiver as following
PickReceiver receiver=new PickReceiver();
IntentFilter filter=new IntentFilter();
filter.addAction("ActivityA_pick");
registerReceiver(receiver,filter);
class PickReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(intent.getAction().equals("ActivityA_pick")){
//get data from intent extras
}
}
In ActivityB when it's time to send the data I use:
sendBroadcast("ActivityA_pick").putExtra("...data...");
finish();
This way i can get the result I want when I want a result from one of my own activities. If you want a result from the system or another app you can adjust this using a dummy activity that doesn't have launch mode singleInstance, have it start the activity for result and when it gets it onActivityResult it sends the broadcast to the caller.
Hope this helps
As the Main Activity is a single instance, is doing what it has been told.
So yes, you have to start the Main Activity from the Web Activity in order to be coherent with the tasks executions

Start an Activity from a BroadcastReceiver

In my app, I register a BroadcastReceiver in the onCreate() method of a Service.
registerReceiver(receiver, newIntentFilter(myAction));
Now I need to start an activity from the newly registered BroadcastReceiver each time onReceive(Context context, Intent intent) happens:
Intent i = new Intent(context,MyClass.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
The "context" is the Context which has been passed to my BroadcastReceiver. That successfully worked and started the Activity. Is that the correct and reliable way of starting an Activity inside a BraodcastReceiver from a Service? Because there are lots of was for getting the Context, like getApplicationContext() orgetApplication(), etc.
In my situation, is using the Context which has been passed to my BroadcastReceiver the correct way?
It's possible to start the activity from the service using the "startActivity()" function.
Try something like this:
public void startAct() {
Intent i = new Intent();
i.setClass(this, MyActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
and call the function inside your BroadcastReceiver.
android.app.Service is descendant of android.app.Context so you can use the startActivity method directly. However since you start this outside any activity you need to set FLAG_ACTIVITY_NEW_TASK flag on the intent.
Hope it helps.
The answer is "yes". You can use the Context that is passed as a parameter to onReceive() to start an activity. You can also use the application's context which you can get like this:
context.getApplicationContext().startActivity(i);
It makes no difference. Both will work.

How to bring an Activity to foreground (or create if not existing)?

I am intercepting sms messages with some information in them. Then in my SmsListener I'm creating notification to show in statusbar.
Then, when user clicks on a notification I want
Bring MainActivity to foreground (If such activity does not exist yet it should be created)
Pass to it data from the sms
Perform some ui changes basing on this data in this MainActivity
My activity is defined as
<activity
android:name=".MainActivity"
android:screenOrientation="sensor"
android:label="#string/app_name"
android:launchMode="singleTask"/>
Activity is launched as
Intent i = new Intent();
i.setClass(context, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
Also in my activity I have overridden method onNewActivity
#Override
public void onNewIntent(Intent intent){
super.onNewIntent(intent);
// I have data from broadcast in intent variable passed to this activity
processDataFromBroadcast(intent);
}
It works fine if the MainActivity already exists but if MainActivity does not exist it is started however onNewIntent was not called
Then I tried to invoke processDataFromBroadcast from onCreate: processDataFromBroadcast(getIntent()).
First time data is passed correctly from my broadcast to the activity.
However if MainActivity is sent to background and then again brought to foreground either onCreate or onNewIntent is called and processDataFromBroadcast is executed again with intent sent by broadcast and thus my MainActivity is updated with data from broadcast every-time the app is bringing to foreground - the latter is unwanted, how can I make my activity to forget this intent after first handling.
Here is sample application.
For an activity to launch only one instance of itself, have a look at the <activity> manifest element, and particularly android:launchMode. You want to configure it with either singleTask or singleInstance.
To pass data to your activity, you add data to the Intent you use to open it. To pass data with the intent, use the putExtra() methods of the intent before sending it off, and getExtra() methods to retrieve them in your receiving activity.
I'm assuming that you know roughly how intents work, but if not you could learn more about intents by taking a look at this Android developers article.
in case your problem is still unresolved, as I was just running into the same issue, here's how I solved it:
I am putting a timestamp as intentId as an extra upon the intent during it's creation. the first time, I am handling the intent in onCreate() or onNewIntent() I am reading the intentId and store it as the last intent handled. so the next time onCreate() or onNewIntet() is invoked I can check the intentId and if it equals the id of the last intent handled, I ignore it! It don't know if this helps in your case, maybe you can adopt it.
To keep intentId independent from activity lifecycles you could persist it in the userdefaults.
I agree that one would expect calling setIntent(new Intent()) in onNewIntent should do the trick.
It it late to answer, but it might be helpful to others looking for the solution.
Just add below lines of code :
Intent mIntent = new Intent(this, SplashActivity.class);
mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // You need this if starting the activity from a service
mIntent.setAction(Intent.ACTION_MAIN);
mIntent.addCategory(Intent.CATEGORY_LAUNCHER);
Where SplashActivity is the name of initial application that is the first screen of your application.
Hope it helps. :)

Calling a method instead of an activity using an Intent - android developers

How can I fire a method instead of an Activity in my code?
I want to use the AddProximityAlert() method from the LocationManager but it needs an Intent to work and I don't want to call another activity since the method I want to fire is in the same Activity from where I'm using AddProximityAlert()
Goes like this:
public clase onCreate()
{
......
LocationManager LM; // already initialized
LM.addProximityAlert(lat,long,radio,expiration,INTENT) <--- This INTENT needs to call myMethod()
}
public void MyMethod()
{
.......
}
I have several hours trying to find a solution for this, and all I find is for calling another activity, please be as much specific, even if I have to do something with the manifest.xml because I haven't used intents before.
Thanks
What if you create a android service (or broadcast receiver might be more appropriate) within the same application that handles the intent.
You don't leave the same pid, it's a non-visual service and you never leave your activity?
You can call your service directly by creating a intent the references it's class name directly.
intent = new Intent(context, my_service.class);
It then will hit the services "onStartCommand()" function and you can do your intent processing from there.

Categories

Resources