在Android中从Service启动Activity

问题描述 投票:0回答:12

安卓:

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
12个回答
379
投票

从服务类内部:

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

但是,由于电池优化限制,这在

Android 10
+ 上不起作用


26
投票

更新 Android 10 及更高版本

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

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

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


20
投票

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

 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


10
投票

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

    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,用于不再次实例化活动。祝你好运!


4
投票

Android 10 及更高版本的新方式是 SYSTEM_ALERT_WINDOW 权限。操作方法如下: 在 AndroidManizest.xml 文件中声明此权限

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

在单击按钮时的 onCreate 方法中,调用辅助方法来显示一个对话框,这样如果用户选择允许权限,将打开覆盖权限的设备设置。请注意,单击按钮上的这个只是为了让您了解如何调用权限。您可以根据您的应用程序要求以您喜欢的方式调用它。

@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");
        }
    });
}

下面声明了辅助方法?

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

                        }
                    }
                }
            }
        });

一旦您相应地实现了上述代码,您就可以从服务类启动任何活动。您的活动将以编程方式启动。

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

基本上,这就是你可以做到的。效果很好。顺便说一句,您可以按照自己的意愿操作此代码。希望这会有所帮助!!


1
投票

不能使用

Context
Service
;能够得到(包裹)
Context
一样:

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

1
投票

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

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

0
投票

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

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


0
投票

或者,

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

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

0
投票
SYSTEM_ALERT_WINDOW.requrid 清单中的权限,并从移动设置手动启用它从 Android 10+ 开始工作。

0
投票

小米红米4A,Android 7,MIUI 10.2.3。

debug
版本中应用程序的主要活动无法从服务启动到前台。
MIUILOG- Permission Denied Activity
中有
logcat
错误。在
release
版本中重建此应用程序解决了问题。


0
投票

在 Service 类中,我们可以使用 this 关键字来引用上下文。

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)

    }
© www.soinside.com 2019 - 2024. All rights reserved.