Start Activity from Service in Android
Asked Answered
L

12

173

Android:

public class LocationService extends Service {

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        startActivity(new Intent(this, activity.class));
    }
}

I launched this service from Activity

In Activity if condition satisfies start

startService(new Intent(WozzonActivity.this, LocationService.class));

from my LocationService mentioned above could not launch Activity, how can I get context of current running Activity in service class?

Logorrhea answered 31/8, 2010 at 6:44 Comment(0)
L
380

From inside the Service class:

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

But, this does not work from Android 10+ due to battery optimisation restrictions

Logorrhea answered 31/8, 2010 at 9:57 Comment(12)
Only the FLAG_ACTIVITY_NEW_TASK is needed since only activities may start activities without it. 'this' can be used in place of getBaseContext and getApplication since the service has its own context.Phosphate
How to programmatically remove that activity from recent screen list?Psych
Does not work if the service is on background. Any fix for this?Jeremiahjeremias
Please help me for open application from background service I have use Firebase (FCM) service. I want to open My Calling UI screen from My App So please help me for thatTransparency
Appears to only be needed for Marshmallow and below.Bunnybunow
You only need to add a flag for android v9 +Dora
Have you got any solution for this @DipankiJadavGynecologist
Have you got any solution for this @Rick Royd AbanGynecologist
I have write your code inside my service when the app is in background, and I see that the service worked on xiaomi mi a2, but not working on xiaomi redmi note 7, can you help my why it's working one device and one is not?Expert
Seems like starting from Android 10, it is not possible to start an activity from inside a background or a foreground service. It might be useful to update this answer since it is the accepted one.Short
@JohnL. I have edited his answer. You can check It nowSloe
this will create a new instance of activity..Zara
V
27

UPDATE ANDROID 10 AND HIGHER

Start an activity from service (foreground or background) is no longer allowed.

There are still some restrictions that can be seen in the documentation

https://developer.android.com/guide/components/activities/background-starts

Virility answered 31/7, 2020 at 13:15 Comment(4)
@RahulBhobe I found this answer helpful, because adding the SYSTEM_ALERT_WINDOW (and enabling it in the settings) solved my issue on Android 10.Footloose
SYSTEM_ALERT_WINDOW can not be granted in Go Edition devices.Sordino
@Shrdi, so, do you have any solutions for AndroidGo?Fanion
@Fanion I don't think this can work on Android 10+Go because this is the system limitation. Any feature about this should offer another alternative way or hint, user might not agree this permission as well.Sordino
I
21

I had the same problem, and want to let you know that none of the above worked for me. What worked for me was:

 Intent dialogIntent = new Intent(this, myActivity.class);
 dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 this.startActivity(dialogIntent);

and in one my subclasses, stored in a separate file I had to:

public static Service myService;

myService = this;

new SubService(myService);

Intent dialogIntent = new Intent(myService, myActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
myService.startActivity(dialogIntent);

All the other answers gave me a nullpointerexception.

Inculpable answered 20/12, 2012 at 0:8 Comment(2)
you are storing the Service in a static field, which could lead to memory leakageGrof
startActivity is same this.startActivity! you create an useless instance from your service with is equal normal startActivity, why?Griswold
J
10

Another thing worth mentioning: while the answer above works just fine when our task is in the background, the only way I could make it work if our task (made of service + some activities) was in the foreground (i.e. one of our activities visible to user) was like this:

    Intent intent = new Intent(storedActivity, MyActivity.class);
    intent.setAction(Intent.ACTION_VIEW);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
    storedActivity.startActivity(intent);

I do not know whether ACTION_VIEW or FLAG_ACTIVITY_NEW_TASK are of any actual use here. The key to succeeding was

storedActivity.startActivity(intent);

and of course FLAG_ACTIVITY_REORDER_TO_FRONT for not instantiating the activity again. Best of luck!

Jablon answered 8/8, 2011 at 7:45 Comment(4)
This does not work. All this gives me is the error "Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?"Melanism
This is because the second call to setFlags overrides the first one. This solution should use addFlags, or a single call to set flags that passes Intent.FLAG_ACTIVITY_NEW_TASK && Intent.FLAG_ACTIVITY_REORDER_TO_FRONT.Mainland
You don't want to combine flags with &&; you want to use | (a single bar for bitwise or)Venetic
Intent intent = new Intent(storedActivity, MyActivity.class); intent.setAction(Intent.ACTION_VIEW); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); storedActivity.startActivity(intent);Swedish
L
5

The new way from android 10 and greater is SYSTEM_ALERT_WINDOW permission. Here is how you do it: Within AndroidManifiest.xml file declare this permission

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

Within onCreate method on button click, call a helper method to show a dialog that way if a user opted in to allow permission, device settings for overlay permission will open. Note that this on Click button is just for you to get an idea on how to invoke permission. You can invoke it which ever way you like per your app requirements.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);      
    Button button = (Button) findViewById(R.id.button1);

    button.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            showMessageForFloatingPermission("To use this feature requires over lay permission");
        }
    });
}

Below are helper methods declared?

//Helper method to show a dialog window
private void showMessageForFloatingPermission(String message) {
    new android.app.AlertDialog.Builder(MainActivity.this)
            .setMessage(message)
            .setPositiveButton("OK",  new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {

                    checkFloatingPermission();

                }
            })
            .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {

                    //User opted not to use this feature
                    //finish();

                }
            })
            .create()
            .show();
}





//Helper method for checking over lay floating permission
public void checkFloatingPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (!Settings.canDrawOverlays(this)) {
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:" + getPackageName()));
            startActivityFloatingPermission.launch(intent);//this will open device settings for over lay permission window

        }
    }
}





//Initialize ActivityResultLauncher. Note here that no need custom request code
ActivityResultLauncher<Intent> startActivityFloatingPermission = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult result) {
                if (result.getResultCode() == Activity.RESULT_OK) {
                    //Permission granted
                }else{
                    //If there is no permission allowed yet, still a dialog window will open unless a user opted not to use the feature. 
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                        if (!Settings.canDrawOverlays(MainActivity.this)) {
                            // You don't have permission yet, show a dialog reasoning
                            showMessageForFloatingPermission("To use this feature requires over lay permission");

                        }
                    }
                }
            }
        });

Once you implemented above codes accordingly, you can start any activity from service class. Your activity will be launched programmatically.

Intent intent = new Intent(this, MyActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);

Basically, this is how you can do it. It works good. BTW, you can manipulate this code as you like per your desires. Hopefully, this will help!!

Loup answered 26/4, 2023 at 14:20 Comment(1)
None of the answers worked, but this worked! Thanks for posting!Lanam
O
1

one cannot use the Context of the Service; was able to get the (package) Context alike:

Intent intent = new Intent(getApplicationContext(), SomeActivity.class);
Osteitis answered 12/2, 2017 at 15:17 Comment(1)
I think this works only with FLAG_ACTIVITY_NEW_TASK flagMarkmarkdown
W
1

You can also use getApplicationContext() method in your Service to run the startActivity() method as written below:

Intent myIntent = new Intent();
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(myIntent);
Width answered 24/12, 2021 at 15:41 Comment(0)
P
1

Inside the Service class, we can use the this keyword to refer to the context.

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {

        val mIntent = Intent(this, YourActivity::class.java).apply {
            setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) // set flags if you needed
            putExtra("yourKey", "yourValue")
        }

        startActivity(mIntent)

    }
Paddlefish answered 14/12, 2023 at 7:46 Comment(1)
it well destroy current instance of activityZara
F
0

If you need to recal an Activity that is in bacgrounde, from your service, I suggest the following link. Intent.FLAG_ACTIVITY_NEW_TASK is not the solution.

https://mcmap.net/q/144677/-how-to-call-an-activity-from-service-with-notification-bar

Flemming answered 24/7, 2014 at 13:2 Comment(1)
Thanks! For Redmi 4A, Android 7, MIUI 10 this is the only that helped me.Dropper
R
0

Alternately,

You can use your own Application class and call from wherever you needs (especially non-activities).

public class App extends Application {

    protected static Context context = null;

    @Override
    public void onCreate() {
        super.onCreate();
        context = getApplicationContext();
    }

    public static Context getContext() {
        return context;
    }

}

And register your Application class :

<application android:name="yourpackage.App" ...

Then call :

App.getContext();
Rexfourd answered 14/8, 2014 at 13:16 Comment(3)
Take care of using a static instance of the context, it can lead severals memor leaksRouse
@Rouse Nope. This is Application context which is Singleton by its nature and it won't lead to memory leaksBoston
I would change the line context = getApplicationContext(); to context = this;Boston
F
0
SYSTEM_ALERT_WINDOW.requrid permission in manifest and enable from from mobile seting manully its works from android 10+.
Fetiparous answered 1/8, 2022 at 7:40 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Bog
D
0

Xiaomi Redmi 4A, Android 7, MIUI 10.2.3. Main activity for app in debug version could not start to foreground from service. There was MIUILOG- Permission Denied Activity error in logcat. Rebuilding this app in release version fixed the problem.

Dropper answered 26/11, 2022 at 0:25 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.