user2999943
user2999943

Reputation: 2519

How to resume Android Activity programmatically from background

Situation:

  1. Let's say I have currently working launched application Activity A.
  2. After some time I am pressing "Home" button. Application A goes to background.
  3. At this time, I am starting to use another app B - youtube for example or etc.
  4. Something happens (doesn't matter what in this context, let's say timer finished calculating time) in the application A which currently is minimized to background.
  5. On the event occurrence, application A activity automatically resumes from background.

Question:

How to accomplish step 5? Basically I need to know how to resume application from background programmatically.

I tried to launch intent to "restart" my application activity but it didn't worked:

Intent intent = new Intent(context, MainActivity.class);
            intent.setAction(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_LAUNCHER);
            context.startActivity(intent);

My manifest file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.taxti"
    android:versionCode="43"
    android:versionName="1.5.3" >     

    <uses-sdk
        android:minSdkVersion="13"
        android:targetSdkVersion="21" />

    <permission
        android:name="com.example.taxti.permission.MAPS_RECEIVE"
        android:protectionLevel="signature" />

    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true" />

    <uses-permission android:name="com.example.taxti.permission.MAPS_RECEIVE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />       
    <permission android:name="com.taxti.permission.C2D_MESSAGE"
                android:protectionLevel="signature" />
    <uses-permission android:name="com.taxti.permission.C2D_MESSAGE" />     
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />   
    <uses-permission android:name="android.permission.CALL_PHONE" />  
    <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
    <uses-permission android:name="android.permission.CLEAR_APP_CACHE" />

    <application
        android:allowBackup="true"        
        android:icon="@drawable/ic_launcher"
        android:hardwareAccelerated="true"
        android:label="@string/app_name"
        android:name="com.taxti.Globals"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.taxti.InitialActivity"
            android:label="@string/app_name"
            android:windowSoftInputMode="adjustPan"
            android:screenOrientation="sensorLandscape"
            android:theme="@style/MyTheme" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.taxti.MainActivity"
            android:label="@string/app_name"
            android:launchMode="singleTop"
            android:windowSoftInputMode="adjustPan"
            android:screenOrientation="sensorLandscape"
            android:theme="@style/MyTheme">
        </activity>

        <service android:name=".MainActivityForegroundService" />

        <intent-filter>
                <action android:name="android.net`enter code here`.conn.CONNECTIVITY_CHANGE" />                
        </intent-filter>

       <intent-filter>
            <action android:name="android.intent.action.CALL_PRIVILEGED" />
            <category android:name="android.intent.category.DEFAULT" />     
            <action android:name="android.intent.action.DIAL" />
            <action android:name="android.intent.action.CALL_BUTTON" />     
            <category android:name="android.intent.category.BROWSABLE" />           
            <data android:scheme="tel" />
       </intent-filter>

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="xxxx" />             
        <uses-library android:name="com.google.android.maps" />

        <receiver
            android:name=".GcmBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >   
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />               
                <category android:name="com.taxti" />
            </intent-filter>

        </receiver>

    </application>

</manifest>

Upvotes: 5

Views: 20047

Answers (6)

VSim
VSim

Reputation: 161

The best way to do it I think is via an IntentService. It works this way too, and it's probably the easiest way. So the sequence is: register a receiver in the Activity (in onCreate) to listen for the event you want, then when the receiver gets the event, it launches an IntentService the standard way and this in turn starts the Activity.
This way it will put the app in front of other apps, both active and hidden ones. (But this should be used with caution. Normally the user won't like another app popping up in front of the one he's working with, except if there's a very good reason for it.)
On my KitKat device (4.4.x), I tested it and I can bring the app to front by calling startActivity from a receiver in the Activity only if there is no other app open, that is my app is hidden under the home screen. Then it will come on top. If another app is open, even if it's also hidden (but in front of my app; I actually didn't test to see what happens if both apps are hidden and mine is in front, but that's not very important), then it won't come on top if started from within the same Activity. So to make it always pop up you need to use an IntentService (or another way but this is as far as I know the simplest one).

Upvotes: 0

Alexey Ozerov
Alexey Ozerov

Reputation: 1542

If your activities are on different tasks, you can use this to bring the activity's task to foreground:

ActivityManager activityManager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); 
activityManager.moveTaskToFront(getTaskId(), ActivityManager.MOVE_TASK_NO_USER_ACTION);

You would need android.permission.REORDER_TASKS in order to do so. It works even in Android M, however getting an intent from a service works better in some cases.

Upvotes: 3

user2999943
user2999943

Reputation: 2519

David Wasser answer helped to solve my problem.

My Activity is running in a foreground Service so I had to call startActivity() method from that Service context.

Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mServiceContext.startActivity(intent);

Upvotes: 2

David Wasser
David Wasser

Reputation: 95578

In order to bring your app to the foreground, you must call startActivity() from another context (either a Service or a BroadcastReceiver). Just calling startActivity() from within an Activity won't bring your app to the foreground.

You don't need the ACTION and CATEGORY in your Intent, but you do need to set Intent.FLAG_ACTIVITY_NEW_TASK.

Upvotes: 7

tritop
tritop

Reputation: 1745

Just establish a Service, doing whatever you want it to in the background. Or even better: Do something in the background, listen to it with a listener, bind a Service as soon as the event you waited for occurs (timer etc). Now that you are in the Service, you just call the Activity that should be on foreground like you would from anywhere else:

Intent i = new Intent(MyService.this, MyActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MyService.this.startActivity(i);

Upvotes: 1

Kushal
Kushal

Reputation: 8478

To Resume application from background programmatically will

Make your activity FOREGROUND, User's current activity in BACKGROUND. User's work is GONE

This is not right behavior from user perspective. Additionally, if we resume activity programmatically, the activity lifecycle will be broken. The activity states will be lost.

Alternative :

You can provide NOTIFICATION when your timer, task (anything) is complete in background. If user is interested in checking your activity then he/she can check from NOTIFICATION without interrupting current work

Upvotes: 1

Related Questions