6

这个问题是从如何关闭或停止我在 Android 中启动的外部应用程序中提出的建议衍生而来的。

我正在编写一个 Android 应用程序,它是工业过程的远程控制 - 该过程在与我的 Android 应用程序持续通信的 PC 上运行,有时 PC 会向 Android 发送 PDF 文件,然后我启动 Adob​​eReader。 apk 来显示它。当 PC 关闭图像时,我想在 Android 上关闭它。

在上面的链接中,有人告诉我,一旦启动 Adob​​eReader,就无法从我的代码中将其关闭。 但是,我也许可以将我的应用程序重新放在前面,这对我的目的同样有益。但我无法让它工作。我的应用程序的主要活动是 RemoteControlActivity,我尝试过:

try {
   Intent i = new Intent(ctx, RemoteControlActivity.class);
   ctx.startActivity(i);    
}   
   catch (ActivityNotFoundException e)   {
   Log.d("ShowButtons(normal)", "Hide");
}

我还尝试使用Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |的各种组合在startActivity( ) 调用之前添加一个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>
4

6 回答 6

5

Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT只有当 Android 将活动带到最前面时,它才会设置标志。自己设置没有任何作用。

FlagIntent.FLAG_FROM_BACKGROUND不做任何事情,它仅用于信息目的(表明活动是由后台任务启动的)。

你需要设置Intent.FLAG_ACTIVITY_NEW_TASK. 从文档中FLAG_ACTIVITY_NEW_TASK

使用此标志时,如果您现在正在启动的 Activity 已经在运行任务,则不会启动新的 Activity;相反,当前任务将简单地以其上次所处的状态被带到屏幕的前面。

于 2012-07-12T14:20:50.287 回答
2

你可以试试这个:

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
于 2014-10-23T02:21:48.677 回答
2

无论该外部应用程序如何启动,您的应用程序都无法杀死另一个第三方外部应用程序,除非它与您的应用程序共享相同的 processId,或者您已植根您的设备。

但是,即使在使用应用程序上下文而不是活动上下文启动外部 3rd 方应用程序之后,您也可以将应用程序的活动带回顶部(或前台)。这是通过以下方法完成的:

    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>

请注意,调用意图启动外部应用程序的活动不应该是调用bringMyAppToForeground();的活动。相反,应该从另一个活动(或服务)调用此方法,因为否则这意味着活动正在尝试自行启动,这将导致活动生命周期复杂化。

于 2015-03-14T19:39:32.457 回答
1

如果活动可能已经在运行,请使用FLAG_ACTIVITY_REORDER_TO_FRONT. 或者,同时使用FLAG_ACTIVITY_CLEAR_TOPFLAG_ACTIVITY_SINGLE_TOP

于 2012-07-12T16:17:35.227 回答
1

请用 -

 FLAG_ACTIVITY_REORDER_TO_FRONT

例如,如果当前任务是 - A,B,C,D。如果,D 为 B 调用 startActivity() FLAG_ACTIVITY_REORDER_TO_FRONT,那么 B 将被带到前面,新的任务赌注将是 - A,C,D, B.

于 2016-08-31T06:43:53.757 回答
0

在这种情况下,最好的选择是终止“adobe reader”(或任何应用程序)进程。在这种情况下使用 android Intent类是没有用的,因为我们不处理同一个应用程序中的活动。

杀死一个进程可以在有的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 : 如何在代码中运行 shell 命令

source-2:如何在不使用 adb shell 的情况下获取 android 应用程序的 pid?

于 2014-05-30T20:25:51.780 回答