Some questions about android broadcastReceiver && context.startActivity() - android

#Override
public void onReceive(Context context, Intent intent) {
Log.i("TEST", "user is present");
Intent i = new Intent(context, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
I want to start my app's MainActivity at once after receiving the intent , but the MainActivity starts about 3 seconds later after I see the log "user is present" , not start at once.
And I need it to start at once for better user experiences.
I wonder wether there is a way can let the MainActivity starts faster ?
PS: when I use a button in another activity to start the MainActivity, it starts immediately, could it be that the method "context.startActivity(i)" in BroadcastReceiver is more slowly ?

There are flags that you can add to the Intent object that can help you achieve your goal. Also when the user is present, this is only after the device has been unlocked (hint).
UPDATE
Apparently the Intent Flag is no longer in the API, bummer. However; Using the KeyguardManager you can achieve this as part of the solution to your problem.

Related

Android - launch app from broadcast receiver

I want the broadcast receiver to launch my app this way:
If the app is not in the foreground or background, launch it as if it is launched from launcher.
If the app is in the background, bring it to the foreground with the state it was last in.
If the app is in the foreground, do nothing.
Here is my code:
#Override
public void onReceive(Context context, Intent intent) {
Intent launch_intent = new Intent("android.intent.action.MAIN");
launch_intent.setComponent(new ComponentName("com.example.helloworld","com.example.helloworld.MainActivity"));
launch_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
launch_intent.addCategory(Intent.CATEGORY_LAUNCHER);
launch_intent.putExtra("some_data", "value");
context.startActivity(launch_intent);
}
MainActivity is my root activity. Like I said, if the app is already running, I just want it brought to the front without changing its state. If there is some activity on top of MainActivity, leave it as it is.
Most of the time the above code worked fine, but sometimes I noticed that the app was restarted (or the state was reset --- the root was back on top) when it was brought from the background.
What code should I be using? Any help is appreciated!
You don't need to write all that code. You can use a "launch Intent", as follows:
PackageManager pm = context.getPackageManager();
Intent launchIntent = pm.getLaunchIntentForPackage("com.example.helloworld");
launchIntent.putExtra("some_data", "value");
context.startActivity(launchIntent);
However, your code should also work.
If you say this works most of the time, you might be seeing a nasty old Android bug in those cases. This occurs when you launch your app for the first time either directly from the installer, or via an IDE (Eclipse, Android Studio, etc.). You should always launch your app for the first time directly from the HOME screen or list of installed apps. For more information about this frustrating Android bug see https://stackoverflow.com/a/16447508/769265
Since you need behaviour like
1) If the app is not in the foreground or background, launch it as if it is launched from the launcher.
2) If the app is in the background, bring it to the foreground with the state it was last in.
3) If the app is in the foreground, do nothing.
Consider:
#Override
public void onReceive(Context context, Intent intent) {
Intent startIntent = context
.getPackageManager()
.getLaunchIntentForPackage(context.getPackageName());
startIntent.setFlags(
Intent.FLAG_ACTIVITY_REORDER_TO_FRONT |
Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
);
context.startActivity(startIntent);
}
#Override
public void onReceive(Context context, Intent intent) {
Intent launch_intent = new Intent(context, MainActivity.class);
launch_intent.setComponent(new ComponentName("com.example.helloworld","com.example.helloworld.MainActivity");
launch_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP |INTENT.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
launch_intent.putExtra("some_data", "value");
launch_intent.addCategory(Intent.CATEGORY_LAUNCHER);
context.startActivity(launch_intent);
}
It's this simple but unless you know the proper way when you try to get the extra data from your intent you will usually get a java null pointer exception.
Use the onNewIntent() method to receive the extra data. If you want to know how comment below.
Edit:
Try the following. But what I don't understand is the first code which I gave you should work on its own. It has always worked for me. Have you made sure that you have copied the first code I gave you and pasted it without making any changes?
Edit2:
If that doesn't work try setting the flag to clearTaskOnLaunch instead of INTENT.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
Assuming you already know BroadcastReceiver, you just have to do the launching like you usually do on onReceive : Therefore it will look like this
#Override
public void onReceive(Context context, Intent intent) {
Intent launch_intent = new Intent("android.intent.action.MAIN");
launch_intent.putExtra("some_data", "value");
tiapp.startActivity(launch_intent);
}
If it is launched before, it will just resume that Activity, if not, it will start a new

How do I bring my activity to the front using broadcastReceiver onReceive()?

All of this has to do with my own app.
I have two cases. First, my activity is on top, and everything works fine. My service broadcasts info and my activity updates its GUI.
My problem is that I don't know how to bring my activity to the front if its not already there. Ideally, all the activities in front of it would be closed and this one be brought to the front. How do i do this?
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//what code do I put here to bring this activity to the front and close all other activities on top of it?
}
};
Here is how I solved the problem with the help of the post bellow.
Intent i = new Intent();
i.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.setClass(MyClass.this, MyClass.class);
startActivity(i);
First of all there isn't a direct command to bring an activity to front such as myActivity.bringToFront. Instead you will have to let android do it for you through the intents mechanism.
So if you want to bring an activity to front you will have to call startActivity and pass an intent with the correct flags. For example the flag FLAG_ACTIVITY_CLEAR_TOP will do your job. However there is a catch, you cannot set this flag if you use startActivity from within a broadcast receiver or a service. So in your case I think that you should use the flag FLAG_ACTIVITY_NEW_TASK.
Here is an example:
Intent i = null;
i = new Intent(context, My_activity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
Hope this helps...

Application crashing when starting an activity from a broadcast receiver, sent from a service

First of all, I have already tried adding flag_activity_new_task, still its not working.
Here is the flow:
I have a service running that does http request on a background thread and fetches data. Whenever certain data is received, I need to display it to user(for example, an update to the app is available). For this, I use broadcast, and have setup a receiver. Everything works fine till here.
But, when I tru starting an activity from this receiver, app crashes saying:
"01-15 17:03:30.129: E/AndroidRuntime(28014): Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
"
Even though I have added this flag. Here are the codes:
Service part:
try
{
JSONObject mAdDetails = mResult.getJSONObject(Tags.TAG_RPC_SMALL_AD_DETAILS);
Intent mI = new Intent();
mI.setAction(ReceiverAdvertSmall.INTENT_ACTION);
mI.putExtra(AppMapKeys.KEY_AD_HEADING, mAdDetails.getString(Tags.TAG_RPC_AD_HEADING));
mI.putExtra(AppMapKeys.KEY_AD_DESCRIPTION, mAdDetails.getString(Tags.TAG_RPC_AD_DESCRIPTION));
mI.putExtra(AppMapKeys.KEY_AD_LINK, mAdDetails.getString(Tags.TAG_RPC_AD_LINK));
sendBroadcast(mI);
}
catch(JSONException e)
{
}
The receiver part:
#Override
public void onReceive(Context mContext, Intent data)
{
Intent mI = new Intent(mContext, ActivityAdvertSmall.class);
mI.putExtras(data.getExtras());
mI.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(data);
}
What Am I Doing Wrong? Iam unable to figure it out for last one hour.!!
Thanx in advance...
use
mContext.startActivity(mI);
instead of
mContext.startActivity(data);
for start Activity from onReceive because you are adding FLAG_ACTIVITY_NEW_TASK flag to mI intent but trying to start Activity using data intent
You should pass the intent you created to startActivity()
mContext.startActivity(mI);
Ok....here was the stupidiest mistake I made. I wrongly used startActivity(data) instead of startActivity(mI). Closing the question.
Just pass the intent you created to startActivity()
mContext.startActivity(mI);

Is there any way to close android app from last activity?

Is there any way to close android app ? I cannot use finish because it shows previous activity and I have lot off activities behind ( for example from 1st to 2nd .. to 10th and on 10th I want to exit from app ). How to achieve this ?
How about using android:noHistory
Whether or not the activity should be removed from the activity stack and finished (its finish() method called) when the user navigates away from it and it's no longer visible on screen — "true" if it should be finished, and "false" if not. The default value is "false".
A value of "true" means that the activity will not leave a historical trace. It will not remain in the activity stack for the task, so the user will not be able to return to it.
Intent intent1 = new Intent(context, Activity.class);
intent1.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent1);
CLEAR TOP clear your stack of activity and can finish the last activity you redirect
if your activity stack is proper clear top will work for you
OPTION 2:
using Borad cast receiver chk link
I also had the same question and did not find a way to definitelly KILL an app. But later I discovered it is due to the intrinsic nature which the system was designed of.
If you want to close an app, you just have to clear the Activity stack and free the usage resources. It seems strange, right? You should have the power to close your own app. But it is really not recommended on Android apps and it does not follow the Android guidelines. And also, do not provide exit options to users. For Android applications which needs to provide an "exit option" to user (for example, due to security reasons), we should provide a "logout option", clear the Activity stack, free resources and other stuff you want to do, but never kill the Main Activity.
The solutions to clear the Activity stack have been shown for other answers here: (1) to use Intent with flag FLAG_ACTIVITY_CLEAR_TOP or (2) to use Broadcast.
With FLAG_ACTIVITY_CLEAR_TOP, you put an Intent on the current Activity:
Intent intent = new Intent(getApplicationContext(), YourMainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
And the option with Broadcast, is to send a broadcast from the current Activity to all Activities you want to close.
For this, you have to SEND the broadcast (on the current Activity):
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.package.ACTION_SPECIFICNAME");
sendBroadcast(broadcastIntent);
finish();
And RECEIVE this broadcast on the others Activities (on each one you want to close):
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.package.ACTION_SPECIFICNAME");
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("onReceive","Logout in progress");
finish();
}
}, intentFilter);
And that is it! I hope this answer helps you. Sorry for my english.
I know that it is not the answer you were waiting for, but I think that is the current (and the "correct") solution.
You can use (but it's not recommended)
System.exit(0);
or you can move your app in background (that is the way Android manages multitasking)
moveTaskToBack(true);
Place this code on exit button press
Intent intent = new Intent(ExitConfirmationActivity.this, FirstActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
And override the onResume of initial activity with a finish();

Send application to back & bring to front

I want to develop an application where it will start on particular time & close on particular time. Similar like Alarm but not alarm application.
As per my thinking I will start an service when application first started service will check current time & particular timing to match the condition & when condition is to close application it will simply send application to background so that service will be running & when condition for wake up occurs service will bring application front.
Is this possible? If yes please give an example links or anything helpful.
Also I am trying to understand the service but it's little bit complex for me so if you have link which will help me to understand the service it will be very helpful. Thank You.
Problem Solved:
/*To close the activity/
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(intent);
MainActivity.this.finish();
OR Just finish activity;
MainActivity.this.finish();
/** To start the activity*/
Intent i = new Intent();
i.setAction(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_LAUNCHER);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ComponentName cn = new ComponentName(this, MainActivity.class);
i.setComponent(cn);
startActivity(i);
It worked for me still I if any one have better solution please post below.
Thank You
You can create a BroadcastReceiver to listen for time changes, and at your specified times, create an Intent to launch or to close your main Activity.

Categories

Resources