Starting An Activity From BroadCast Receiver - android

My app is consisted of many activities and a BraodcastReceiver. I want to restart an activity if it is on foreground when my app receives the broadcast Intent.How can I implement it?

use Intent.FLAG_ACTIVITY_REORDER_TO_FRONT to launch activity to be brought to the front of its task's history stack if it is already running and if not then start as new one. to make confirm if Activity is running or not use ActivityManager
#Override
public void onReceive(Context context, Intent intent) {
//start activity
if(isRunning(context)){
Intent i = new Intent(context,Your_Activity_Name.class);
i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
context.startActivity(i);
}
else{
// Activity not available in activity stack
}
}
public boolean isRunning(Context ctx) {
ActivityManager activityManager = (ActivityManager)
ctx.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks =
activityManager.getRunningTasks(Integer.MAX_VALUE);
for (RunningTaskInfo task : tasks) {
if (ctx.getPackageName().equalsIgnoreCase(
task.baseActivity.getPackageName()))
return true;
}
return false;
}
and also set android:noHistory AndroidManifest.xml to store Activity in activity stack no longer visible on screen :
<activity
android:noHistory="false"
android:name=".Your_Activity" />

Make the activity singleTop and just send the intent.

Related

OnCreate in Application class called twice

I didn't use android:process in my AndroidManifest. When I launch app oncreate in Application class get called twice. I would like to know what could cause such behaviour.
Probably you call your service when you run your app.
Use this to prevent recalling the service several times:
Intent intent = new Intent(YourActivity.this, YourService.class);
if (!IsServiceRunning(YourService.class)) {
startService(intent);
}
Use this function to check whether the service is running or not:
public boolean IsServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(getApplicationContext().ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}

How to find whether activity is last activity in stack

I am opening a link in my app and once back is pressed I want to show HomePage to retain user for some more time. I have been trying to acheive this but unable to do so. I get homeLauncher activity as my top as well as baseActivity.
DeepLink Tap > Open desired Activity > user presses back button > Check if its last activity but not homeActivity > If yes, Navigate user to homeActivity.
Tried following code:
#Override
public void onBackPressed() {
ActivityManager mngr = (ActivityManager) getSystemService( ACTIVITY_SERVICE );
List<ActivityManager.RunningTaskInfo> taskList = mngr.getRunningTasks(10);
if(taskList.get(0).numActivities == 1 && taskList.get(0).topActivity.getClassName().equals(this.getClass().getName())){
//// This is last activity
}
else{
//// There are more activities in stack
}
super.onBackPressed();
}
I have also tried isTaskRoot but result is same. It doesn't give right answer.Please help
Use isTaskRoot() method. (From a h9kdroid comment - here)
#Override
public void onBackPressed() {
ActivityManager mngr = (ActivityManager) getSystemService( ACTIVITY_SERVICE );
List<ActivityManager.RunningTaskInfo> taskList = mngr.getRunningTasks(10);
if(isTaskRoot()){
//// This is last activity
} else{
//// There are more activities in stack
}
super.onBackPressed();
}
You could simply use the ActivityManager it keeps track of which activity is and is not here is a piece of code I stumbled on that I use always:
ActivityManager mngr = (ActivityManager) getSystemService( ACTIVITY_SERVICE );
List<ActivityManager.RunningTaskInfo> taskList = mngr.getRunningTasks(10);
if(taskList.get(0).numActivities == 1 &&
taskList.get(0).topActivity.getClassName().equals(this.getClass().getName())) {
Log.i(TAG, "This is last activity in the stack");
}
Quoting From ActivityManager.RunningTaskInfo
Information you can retrieve about a particular task that is currently
"running" in the system. Note that a running task does not mean the
given task actually has a process it is actively running in; it simply
means that the user has gone to it and never closed it, but currently
the system may have killed its process and is only holding on to its
last state in order to restart it when the user returns.
String getLastOpenClass ;// Global
ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List< ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
componentInfo.getPackageName();
getLastOpenClass=taskInfo.get(0).topActivity.getClassName();
if(getLastOpenClass.equals("Your_Class_Name"))
{
}else{
}
Give permission
<uses-permission android:name="android.permission.GET_TASKS" />
The ActivityManager keeps a record of the runnings task and the topmost task .
ActivityManager mngr = (ActivityManager) getSystemService( ACTIVITY_SERVICE );
List<ActivityManager.RunningTaskInfo> taskList = mngr.getRunningTasks(10);
if(taskList.get(0).numActivities == 1 && taskList.get(0).topActivity.getClassName().equals(this.getClass().getName()))
{
Log.i(TAG, "This is Last activity in the stack");
}
Courtesy How to check if an activity is the last one in the activity stack for an application?
Please Check How can I get the current foreground activity package name
http://developer.android.com/intl/es/reference/android/app/ActivityManager.html#getRunningTasks%28int%29
Please note that the below solution will only work on API14+.
Create a custom application class;
public class App extends Application {
private int created;
#Override
public void onCreate() {
registerActivityLifecycleCallbacks(new Callbacks());
}
public int getCreated() {
return created;
}
private class Callbacks implements ActivityLifecycleCallbacks {
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
created++;
}
#Override
public void onActivityDestroyed(Activity activity) {
created--;
}
}
}
Register it in your AndroidManifest.xml in the application element;
<application name=".App"/>
And in your activity opened through a deep link use the following piece of code;
#Override
public void onBackPressed() {
if (((App) getApplicationContext()).getCreated() == 1) {
// start your home activity
}
super.onBackPressed();
}
I wrote this off the top of my head so I haven't had a chance to test it, but theoretically it should work.
Specify parent activity for desired Activity, like :
<activity
android:name=".DesiredActivity"
android:parentActivityName="com.packagename.HomePage" >
<!-- The meta-data element is needed for versions lower than 4.1 -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.packagename.HomePage" />
</activity>
With the parent activity declared, you can use the NavUtils APIs to
synthesize a new back stack by identifying which activity is the
appropriate parent for each activity.
override onBackPressed as :
#Override
public void onBackPressed() {
Intent intent = NavUtils.getParentActivityIntent(this);
startActivity(intent);
super.onBackPressed();
}
Android developer's site has a very good resource for same problem. Please refer to link http://developer.android.com/training/implementing-navigation/temporal.html#SynthesizeBackStack

start activity if application is visible

I am implementing session timeouts in my application.
here what i want to do is launch the login activity if and only if the application is visible (i.e. shown) else i don't want to do anything as when the application is laucnced again it will automatically start off with login Activity itself..
final List<RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
for (RunningTaskInfo runningTaskInfo : tasks) {
runningactivities.add(0,runningTaskInfo.topActivity.toString());
}
But this doesn't work for me as it launches the Login Activity in both cases..
Please Help!!
Thanks
One solution is to use intent receivers in your activity. You can register a receiver in the Activity(or activities) that you only want the new activity to be launched from. Then you can launch the new activity with sendBroadcast(intent). You should register and unregister you reciever in each activity as shown below:
#Override
protected void onResume() {
IntentFilter filter = new IntentFilter(CONSTANT_FOR_INTENT);
registerReceiver(receiver, filter);
}
#Override
protected void onDestroy() {
unregisterReceiver(receiver);
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//handle the intent here - launch activity, etc
}
};
Now you can launch your activity with this:
Intent intent=new Intent(CONSTANT_FOR_INTENT);
sendBroadcast(intent);
You can also use sendOrderedBroadcast to set a priority and do something else with the intent if your activity is not running.

Stopping service explicitly

I have an app, which contains two activities and a service and a reciever, service is used to get the location updates all the time, i will start the service in the reciever for the first time, my requirement is, i need to stop the service when my application is in foreground (running), and i need to start the service when i application is stopped. among two activities initActivity is the first activity that get launched when application starts, and the homegridActivity id the second activity, i am giving the option in homegridactivity to exit from the application. below is the code where i am starting the service and stoping the service.
class initActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.app);
System.out.println("VANDROID service status inside oncreate of init" );
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if ("com.vaayoo.android.service.VLocationFetchService".equals(service.service.getClassName())) {
Intent intent = new Intent( VUiHelper.getInstance().getApplicationContext(), VLocationFetchService.class);
boolean result = ((Vandroid)VUiHelper.getInstance().getApplicationContext()).stopService(intent);
System.out.println("VANDROID service status" + result);
manager = null;
}
}
}
}
//second Activity
Class HomeGridActivity extends Activity
{
protected void onDestroy() {
super.onDestroy();
System.out.println("Homegrid activity onDestroy called");
VUiHelper.getInstance().clearControlCache();
ActivityManager manager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if ("com.vaayoo.android.service.VLocationFetchService".equals(service.service.getClassName())) {
Intent intent = new Intent( VUiHelper.getInstance().getApplicationContext(), VLocationFetchService.class);
ComponentName compname =((Vandroid) VUiHelper.getInstance().getApplicationContext()).startService(intent);
System.out.println("COMPONENT NAME" + compname.toString() );
manager = null;
}
}
}
}
I am stoping the service in oncreate on the initactivity and starting the same service in ondestroy of homegridActivity, the problem i am facing is, this is working only for the first time, if i close and launch the app multiple times, service is not stoping and starting, i found that, the service is running all the time. i have made that service as start_sticky so that is should not be killed by android runtime at any point of time, i should have full control on that service to stop and start. not able to find out why it is not working all the time, why it is working only for the first time. what i am doing wrong ? how to troubleshoot this? is it because of making service as start_sticky?
This method is return true or false means.when service is ruuning than reture true otherwise false. so you can use this method when r you use just like this.
private boolean isMyServiceRunning() {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager
.getRunningServices(Integer.MAX_VALUE)) {
if ("packagename".equals(service.service
.getClassName())) {
return true;
}
}
return false;
}
and check like that.
if (isMyServiceRunning()) {
stopService(new Intent(A.this, MusicService.class));
}

Broadcast receiver opens up activity in foreground when application is in background?

I have a broadcast receiver which receives for internet connectivity..and as soon as it doesn't find any connection it opens up my splash activity saying "NO INTERNET CONNECTION"....till now everything is ok but when user put the application into background using device home button and then off the internet connection the splash activity comes to foreground while the app was running in background. I don't want this to happen the splash activity should open but in the background only.
#Override
public void onReceive(Context context, Intent intent) {
// SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean isNetworkDown = intent.getBooleanExtra(
ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
if (isNetworkDown) {
Log.d(TAG, "onReceive: NOT connected, stopping UpdaterService");
Intent myintent=new Intent(context,NoConnectivity.class);
myintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myintent);
} else
{
Log.d(TAG, "onReceive: connected, starting UpdaterService");
NoConnectivity.h.sendEmptyMessage(0);
}
}
startActivity will automatically bring the activity to the foreground on top of whicever activity you are viewing. User can go back to the previous one using back button. That's the usual way things work.
However, you can use moveTaskToBack(true) to send your activity to background.
Here is the function description.
EDIT
Check out this question and use the solution to see if your activity is in the background. If yes, then use the method I advised above to send the new activity to the background.
if (isNetworkDown) {
Log.d(TAG, "onReceive: NOT connected, stopping UpdaterService");
// Check the foreground package
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> runningTasks = activityManager.getRunningTasks(1);
ComponentName topActivity = runningTasks.get(0).topActivity;
String foregroundPackageName = topActivity.getPackageName();
if(foregroundPackageName.equals(context.getPackageName()) {
Intent myintent = new Intent(context,NoConnectivity.class);
myintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myintent);
}
}

Categories

Resources