这个问题是How to close or stop an external app that I started in Android中提出的建议的衍生产品。
我正在编写一个Android应用程序,它是工业流程的远程控制 - 该过程在PC上运行,该PC与我的Android应用程序保持持续通信,有时PC会向Android发送PDF文件并启动AdobeReader.apk来显示它。当PC解散图像时,我想在Android上将其解雇。
在上面的链接中,我被告知,一旦我启动AdobeReader,就无法从我的代码中关闭它。 然而我可能会将我的应用程序带回到前端,这对我的目的来说同样好。但是我无法让它发挥作用。我的应用程序的主要活动是RemoteControlActivity,我尝试了:
try {
Intent i = new Intent(ctx, RemoteControlActivity.class);
ctx.startActivity(i);
}
catch (ActivityNotFoundException e) {
Log.d("ShowButtons(normal)", "Hide");
}
我还尝试在 startActivity()调用之前使用 Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |的各种组合添加 intent.setFlags(...)。 Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_FROM_BACKGROUND 没有运气。
在清单中,remoteControlActivity的启动模式为 singleTask
在调试器中调用 StartActivity()而不在Catch子句中登陆,但是我没有在RemoteControlActivity的onRestart或onResume处理程序中遇到断点。
提前致谢!
编辑:下面的答案提示了一个不同的标志,所以我试了一下:
try {
Intent i = new Intent(ctx, RemoteControlActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK );
ctx.startActivity(i);
}
catch (ActivityNotFoundException e) {
Log.d("ShowButtons(normal)", "Hide");
}
...但没有运气 - 在调试器中它调用startActivity,没有落在catch块中,但没有任何反应。
进一步编辑:我被要求提供清单;这是主要活动的部分:
<activity android:launchMode="singleTask"
android:label="@string/app_name"
android:windowNoTitle="false"
android:configChanges="orientation"
android:screenOrientation="landscape"
android:name="RemoteControlActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
答案 0 :(得分:5)
标记Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT
仅由Android设置,当它将活动带到前端时。自己设置什么都不做。
标记Intent.FLAG_FROM_BACKGROUND
不执行任何操作,仅用于提供信息(表示活动是由后台任务启动的)。
您需要设置Intent.FLAG_ACTIVITY_NEW_TASK
。来自FLAG_ACTIVITY_NEW_TASK
的文档:
使用此标志时,如果某个任务已在运行该活动 你现在开始,然后一个新的活动将不会开始; 相反,当前的任务将被简单地带到前面 屏幕显示它最后的状态。
答案 1 :(得分:2)
你可以试试这个:
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
答案 2 :(得分:2)
您的应用程序无法杀死其他第三方外部应用程序,无论外部应用程序如何启动,除非它与您的应用程序共享相同的processId,或者您的设备已植根。
然而,即使在使用应用程序上下文而不是活动上下文启动外部第三方应用程序之后,您也可以将应用程序的活动带回到顶层(或前台)。这可以通过以下方法完成:
private void bringMyAppToForeground(Context context) {
Intent it = new Intent("intent.my.action");
it.setComponent(new ComponentName(getPackageName(), SplashScreenActivity.class.getName()));
it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.getApplicationContext().startActivity(it);
}
其中"intent.my.action"
在清单中定义如下:
<activity
android:name="com.example.SplashScreenActivity" >
<intent-filter>
<action android:name="intent.my.action" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
请注意,调用intent以启动外部应用程序的活动不应该是调用bringMyAppToForeground()的活动;相反,应该从另一个活动(或服务)调用此方法,否则这意味着活动正在尝试启动自身,这将导致活动生命周期复杂化。
答案 3 :(得分:1)
如果活动可能已在运行,请使用FLAG_ACTIVITY_REORDER_TO_FRONT
。或者,同时使用FLAG_ACTIVITY_CLEAR_TOP
和FLAG_ACTIVITY_SINGLE_TOP
。
答案 4 :(得分:1)
请使用 -
FLAG_ACTIVITY_REORDER_TO_FRONT
例如,如果当前任务类似于 - A,B,C,D。如果,D调用带有FLAG_ACTIVITY_REORDER_TO_FRONT
的B的startActivity(),则B将被带到前面,新的任务桩将是喜欢 - A,C,D,B。
答案 5 :(得分:0)
在这种情况下,最好的选择是杀死“adobe reader”(或任何app)进程。 在这种情况下使用android Intent 类是没用的,因为我们不处理同一个应用程序中的活动。
可以在 rooted Android设备的2个步骤中执行某个流程:
1- 获取“adobe reader”pid:我们假设 adobe_reader_package_name 是一个包含adobe reader包名称的字符串
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> pids = am.getRunningAppProcesses();
int processid = 0;
for (int i = 0; i < pids.size(); i++) {
ActivityManager.RunningAppProcessInfo info = pids.get(i);
if (info.processName.equalsIgnoreCase(adobe_reader_package_name)) {
processid = info.pid;
}
}
2- 使用pid杀死进程:这可以使用这样的方法完成
public static void doCmds(List<String> cmds) throws Exception {
Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
for (String tmpCmd : cmds) {
os.writeBytes(tmpCmd+"\n");
}
os.writeBytes("exit\n");
os.flush();
os.close();
process.waitFor();
}
并将其称为:
List<String> cmdList = new ArrayList<String>();
cmdList.add("kill -9 "+processid);
try {
doCmds(cmdList);
Log.d("A3", "kill process completed ...");
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
希望这会有所帮助,欢呼!
source-1:android : how to run a shell command from within code
source-2:How to get pid of android application with out using adb shell?