【问题标题】:Start Activity from Service in Android在 Android 中从服务启动 Activity
【发布时间】:2017-11-23 12:53:58
【问题描述】:

安卓:

public class LocationService extends Service {

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

我从Activity启动了这项服务

Activity如果条件满足开始

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

从我上面提到的LocationService 无法启动Activity,我如何在服务类中获取当前正在运行的Activity 的上下文?

【问题讨论】:

    标签: android android-intent android-activity android-service


    【解决方案1】:

    从服务类内部:

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

    【讨论】:

    • 只需要 FLAG_ACTIVITY_NEW_TASK 因为只有活动才能在没有它的情况下启动活动。 'this' 可以用来代替 getBaseContext 和 getApplication,因为服务有自己的上下文。
    • 如何以编程方式从最近的屏幕列表中删除该活动?
    • 如果服务在后台,则不起作用。有什么解决办法吗?
    • 请帮助我从后台服务打开应用程序我使用 Firebase (FCM) 服务。我想从我的应用程序打开我的呼叫 UI 屏幕所以请帮助我
    • 当应用程序处于后台时,我已经在我的服务中编写了您的代码,我看到该服务在小米米 a2 上工作,但在小米红米 note 7 上不工作,你能帮我解释为什么一台设备工作而另一台不工作?
    【解决方案2】:

    我遇到了同样的问题,并且想让您知道以上方法都不适合我。 对我有用的是:

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

    在我的一个子类中,存储在一个单独的文件中,我必须:

    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);
    

    所有其他答案都给了我nullpointerexception

    【讨论】:

    • 您将服务存储在静态字段中,这可能导致内存泄漏
    • startActivity 和 this.startActivity 一样!你从你的服务中创建了一个无用的实例,它等于正常的 startActivity,为什么?
    【解决方案3】:

    更新 ANDROID 10 及更高版本

    不再允许从服务(前台或后台)启动活动。

    还有一些限制可以在文档中看到

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

    【讨论】:

    • @RahulBhobe 我发现这个答案很有帮助,因为添加 SYSTEM_ALERT_WINDOW(并在设置中启用它)解决了我在 Android 10 上的问题。
    • SYSTEM_ALERT_WINDOW 不能在 Go 版设备中授予。
    • @Shrdi,那么,你们有针对 AndroidGo 的解决方案吗?
    • @AlexS 我不认为这可以在 Android 10+Go 上运行,因为这是系统限制。任何与此相关的功能都应提供另一种替代方式或提示,用户也可能不同意此权限。
    【解决方案4】:

    另一件事值得一提:虽然上面的答案在我们的任务在后台时工作得很好,但如果我们的任务(由服务 + 一些活动组成)在前台(即我们的活动对用户可见)是这样的:

        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);
    

    我不知道 ACTION_VIEW 或 FLAG_ACTIVITY_NEW_TASK 是否在这里有任何实际用途。成功的关键是

    storedActivity.startActivity(intent);
    

    当然还有 FLAG_ACTIVITY_REORDER_TO_FRONT 用于不再实例化活动。祝你好运!

    【讨论】:

    • 这不起作用。所有这些给我的都是错误“从 Activity 上下文之外调用 startActivity() 需要 FLAG_ACTIVITY_NEW_TASK 标志。这真的是你想要的吗?”
    • 这是因为第二次调用 setFlags 覆盖了第一次。此解决方案应使用 addFlags,或单个调用来设置传递 Intent.FLAG_ACTIVITY_NEW_TASK && Intent.FLAG_ACTIVITY_REORDER_TO_FRONT 的标志。
    • 您不想将标志与 &&;你想使用 | (按位或的单条)
    • Intent intent = new Intent(storedActivity, MyActivity.class);意图.setAction(意图.ACTION_VIEW);意图.addFlags(意图.FLAG_ACTIVITY_NEW_TASK);意图.addFlags(意图.FLAG_ACTIVITY_REORDER_TO_FRONT); storedActivity.startActivity(intent);
    【解决方案5】:

    不能使用ServiceContext;能够得到(包)Context alike:

    Intent intent = new Intent(getApplicationContext(), SomeActivity.class);
    

    【讨论】:

    • 我认为这只适用于FLAG_ACTIVITY_NEW_TASK标志
    【解决方案6】:

    或者,

    您可以使用自己的应用程序类并从您需要的任何地方(尤其是非活动)调用。

    public class App extends Application {
    
        protected static Context context = null;
    
        @Override
        public void onCreate() {
            super.onCreate();
            context = getApplicationContext();
        }
    
        public static Context getContext() {
            return context;
        }
    
    }
    

    并注册您的应用程序类:

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

    然后调用:

    App.getContext();
    

    【讨论】:

    • 注意使用上下文的静态实例,它会导致多次内存泄漏
    • @crgarridos 不。这是应用程序上下文,本质上是单例,不会导致内存泄漏
    • 我会将context = getApplicationContext(); 改为context = this;
    【解决方案7】:

    您也可以在 Service 中使用 getApplicationContext() 方法来运行 startActivity() 方法如下:

    Intent myIntent = new Intent();
    myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    getApplicationContext().startActivity(myIntent);
    

    【讨论】:

      【解决方案8】:

      如果您需要从您的服务中重新调用一个在 bacgrounde 中的 Activity,我建议您使用以下链接。 Intent.FLAG_ACTIVITY_NEW_TASK 不是解决方案。

      https://stackoverflow.com/a/8759867/1127429

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-21
        • 1970-01-01
        相关资源
        最近更新 更多