android从服务开始活动

d-m*_*man 139 android android-service android-activity

安卓:

public class LocationService extends Service {

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

我推出了这项服务 Activity

Activity如果条件满足启动

startService(new Intent(WozzonActivity.this, LocationService.class));
Run Code Online (Sandbox Code Playgroud)

从我LocationService上面提到的无法启动Activity,我怎样才能获得当前Activity在服务类中运行的上下文?

d-m*_*man 325

从Service类内部:

Intent dialogIntent = new Intent(this, MyActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(dialogIntent);
Run Code Online (Sandbox Code Playgroud)

  • 只需要FLAG_ACTIVITY_NEW_TASK,因为只有活动可以在没有它的情况下开始活动.'this'可用于代替getBaseContext和getApplication,因为服务有自己的上下文. (15认同)
  • 请帮助我从后台服务打开应用程序,我使用 Firebase (FCM) 服务。我想从我的应用程序打开我的呼叫 UI 屏幕所以请帮我 (4认同)
  • 如果服务在后台,则不起作用。有什么解决办法吗? (2认同)
  • 当应用程序处于后台时,我已在我的服务中编写了您的代码,并且我看到该服务在小米米a2上运行,但在小米红米Note 7上不起作用,你能帮我解释一下为什么它可以在一台设备上运行而另一台设备不能运行吗? (2认同)

And*_*ndy 18

我遇到了同样的问题,并且想让你知道以上都不适用于我.对我有用的是:

 Intent dialogIntent = new Intent(this, myActivity.class);
 dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 this.startActivity(dialogIntent);
Run Code Online (Sandbox Code Playgroud)

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

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);
Run Code Online (Sandbox Code Playgroud)

所有其他答案都给了我一个nullpointerexception.

  • 您将服务存储在静态字段中,这可能导致内存泄漏 (5认同)
  • startActivity 与 this.startActivity 相同!您从服务中创建了一个无用的实例,其与正常的 startActivity 相同,为什么? (3认同)

Jos*_*raz 15

更新 Android 10 及更高版本

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

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

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

  • @RahulBhobe 我发现这个答案很有帮助,因为添加“SYSTEM_ALERT_WINDOW”(并在设置中启用它)解决了我在 Android 10 上的问题。 (2认同)

kel*_*ogs 8

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

    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);
Run Code Online (Sandbox Code Playgroud)

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

storedActivity.startActivity(intent);
Run Code Online (Sandbox Code Playgroud)

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

  • 您不希望将标志与&&结合使用; 你想用| (按位的单个栏或) (8认同)
  • 这是因为对setFlags的第二次调用会覆盖第一次调用.此解决方案应使用addFlags或单个调用来设置传递Intent.FLAG_ACTIVITY_NEW_TASK && Intent.FLAG_ACTIVITY_REORDER_TO_FRONT的标志. (2认同)

Jos*_*osi 5

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

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
Run Code Online (Sandbox Code Playgroud)

在单击按钮时的 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");
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

下面声明了辅助方法吗?

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

                        }
                    }
                }
            }
        });
Run Code Online (Sandbox Code Playgroud)

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

Intent intent = new Intent(this, MyActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
Run Code Online (Sandbox Code Playgroud)

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