安卓:
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
的上下文?
从服务类内部:
Intent dialogIntent = new Intent(this, MyActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(dialogIntent);
但是,由于电池优化限制,这在
Android 10
+ 上不起作用
更新 Android 10 及更高版本
不再允许从服务(前台或后台)启动活动。
还有一些限制可以在文档中看到
https://developer.android.com/guide/components/activities/background-starts
我遇到了同样的问题,想让你知道以上方法都不适合我。 对我有用的是:
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
。
另一件事值得一提:虽然当我们的任务在后台时上面的答案工作得很好,但如果我们的任务(由服务+一些活动组成)在前台(即我们的活动之一),我可以使它工作的唯一方法对用户可见)是这样的:
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,用于不再次实例化活动。祝你好运!
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);
基本上,这就是你可以做到的。效果很好。顺便说一句,您可以按照自己的意愿操作此代码。希望这会有所帮助!!
不能使用
Context
的Service
;能够得到(包裹)Context
一样:
Intent intent = new Intent(getApplicationContext(), SomeActivity.class);
您还可以在 Service 中使用 getApplicationContext() 方法来运行 startActivity() 方法,如下所示:
Intent myIntent = new Intent();
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(myIntent);
如果您需要从您的服务中重新调用 bacgrounde 中的活动,我建议您使用以下链接。 Intent.FLAG_ACTIVITY_NEW_TASK 不是解决方案。
或者,
您可以使用自己的应用程序类,并从您需要的任何地方(尤其是非活动)进行调用。
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();
小米红米4A,Android 7,MIUI 10.2.3。
debug
版本中应用程序的主要活动无法从服务启动到前台。 MIUILOG- Permission Denied Activity
中有 logcat
错误。在 release
版本中重建此应用程序解决了问题。
在 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)
}