如何检测用户何时启动另一个应用程序? (Android)

问题描述:

我正在试图构建一个应用程序,其中我的应用程序在后台运行,并检测用户何时启动另一个应用程序,以便可以控制其上的流程。 为了说明我的查询,我想指定一个例子。 我的应用程序在后台运行(称为服务),并且用户刚刚点击应用程序'XYZ'。我的应用有可能检测到应用“XYZ”已启动? 不仅仅是检测'XYZ的活动是否已经到达前台,我想要检测'XYZ'是否已经启动。说有人推出'Whatsapp Messenger',我想知道我的应用程序是否可以知道'Whatsapp Messenger'已经启动。如何检测用户何时启动另一个应用程序? (Android)

编辑:很多人认为我试图构建恶意软件,但我不是。我正在尝试为高中项目构建一个应用程序。我想要一个统计数据来看看我的相机多长时间用作心理项目的一部分。 :/

在此先感谢, Sumit。

+0

你为什么要这么做实现的?引用“**,以便我可以控制其上的流量**”这听起来可能。 – t0mm13b 2012-07-05 14:43:42

+0

我正在尝试构建一个高中项目的应用程序。没有恶意软件。 :( – 2012-07-05 14:54:37

+0

http://*.com/questions/3290936/android-detect-when-other-apps-are-launched – SMR 2014-05-17 05:14:39

我想你应该看看Google Play中的“应用程序保护器”应用程序。他们发现用户启动了另一个应用程序这是通过读取系统日志完成的。尝试在设备上启动任何应用程序后打开LogCat并阅读日志。你会感到惊讶。

你应该去哪里?我想你应该尝试aLogCat的应用程序。它是绿色和开源的。这将帮助您实际读取日志。尽管如此,所有这些都被认为是Android中的安全漏洞。

+0

可能的副本是否属实Google会阻止API级别16以上的日志读取? – gonzobrains 2013-05-01 00:09:23

+1

@gonzobrains我已经猜到了,你可以阅读只有你自己的pid发布的日志 – 2013-05-01 13:50:07

+0

@gonzobrains是的,我阻止了api 16以上。m也可以找到应用午餐的sorce代码,你能帮我吗 – 2013-06-27 12:54:12

是的,您可以通过跟踪Logcat找到启动的应用程序。正在追踪ActivityManager标记与info -I日志。

从adb shell命令是,

adb logcat ActivityManager:I *:S 

从应用程序代码,

logcat ActivityManager:I *:S 

而且在logcat中,你可以找到一个线类似,

I/ActivityManager( 585): Starting activity: Intent { action=android.intent.action...} 

当任何应用程序将推出。

这是logcat的输出,显示该消息涉及到优先级“I”和标签“ActivityManager”:

更新:

只是在你的应用程序的清单文件中添加权限,

android.permission.READ_LOGS 
+2

一般警告:这种方法(我在GS3上见证过的)中的一些更新的手机不再将包/活动放到这个日志语句中,如果你对性能没有兴趣,你可以继续轮询ActivityManager.getRecentTasts()以知道何时 – FoamyGuy 2012-07-05 15:55:25

+0

将无法​​在JellyBean +中使用。READ_LOGS权限现仅保留给系统应用程序使用。 – 2016-08-04 08:56:00

在我的书中,通过您提出问题的方式,这听起来像是以某种方式让您的服务以恶意软件jinx为边界控制的应用程序。但它在Android中不起作用 - 由于每个应用程序的权限不同,它很简单和简单。从而,每个应用程序都相互隔离。因此,直接回答你的问题,其号码

正如其他答案建议 - 你可以监视logcat,但..然后再...为什么?

+0

就这一部分而言的公共API,我没有理由不这样做。 – 2012-07-05 14:48:08

+0

@Mighter询问OP为什么要控制服务中的应用程序?确定它是公共API的一部分,并且“你看不到没有理由不这样做”,对,如果我发现那个应用程序正在这样做 - 一个字 - 卸载*。 – t0mm13b 2012-07-05 14:49:50

+0

当然,他想建立一个恶意软件。 – 2012-07-05 14:50:34

不知道这是为了做到这一点,最好的方式,但它的工作原理,你可以使用logcat,并期待在其输出端,您可以使用此权限

android.permission.READ_LOGS 

,并使用下面的代码:

try 
{ 
    Process mLogcatProc = null; 
    BufferedReader reader = null; 
    mLogcatProc = Runtime.getRuntime().exec(new String[]{"logcat", "-d"}); 

    reader = new BufferedReader(new InputStreamReader(mLogcatProc.getInputStream())); 

    String line; 
    final StringBuilder log = new StringBuilder(); 
    String separator = System.getProperty("line.separator"); 

    while ((line = reader.readLine()) != null) 
    { 
     log.append(line); 
     log.append(separator); 
    } 
    String w = log.toString(); 
    Toast.makeText(getApplicationContext(),w, Toast.LENGTH_LONG).show(); 
} 
catch (Exception e) 
{ 
    Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show(); 
} 

,不要忘记它的Android清单许可,您可以将此代码添加到一个线程,它的工作

+0

非常感谢您的帮助。我不太了解代码,但我会弄清楚,但是最后一部分是什么意思:“将此代码添加到线程中”?你的意思是一个ASyncTask或类似的东西吗?我希望我的应用程序能够作为服务工作,因此,在任何给定的时间,如果应用程序启动,它都可以检测到。 – 2012-07-05 15:05:54

+0

你可以使用一个普通的线程来做到这一点,如果你想让你的应用程序作为一个服务来运行,只需要将该线程放入服务中,然后将上面的代码放入线程中...将线程添加到服务中的一个示例可以在这里看到:http://*.com/questions/4178682/how-to-start-a-new-thread-in-a-service – 2012-07-05 15:09:44

+0

谢谢一吨。我会尽力实施它并让你知道结果。 – 2012-07-10 13:18:31

我已经可以检测,如果服务其他应用程序启动。我为拨号程序制作了它。同样可以被任何包名取代。

@Override 
public int onStartCommand(Intent intent, int flags, int startId){ 
    Toast.makeText(this,"Service Started", Toast.LENGTH_LONG).show(); 

    final String str = ""; 
    Timer timer = new Timer(); 
    timer.scheduleAtFixedRate(new TimerTask() { 
     int phonelaunched = 0,phoneclosed =0; 
     int phonelaunches = 1; 
     @Override 
     public void run() { 
      ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 
      List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfo = am.getRunningAppProcesses(); 

      for (ActivityManager.RunningAppProcessInfo appProcess: runningAppProcessInfo) { 
       Log.d(appProcess.processName.toString(),"is running"); 
       if (appProcess.processName.equals("com.android.dialer")) { 
        if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND /*isForeground(getApplicationContext(),runningAppProcessInfo.get(i).processName)*/){ 
         if (phonelaunched == 0){ 
          phonelaunched = 1; 
          Log.d(str,"dude phone has been launched"); 
         } 
         else if (phoneclosed == 1){ 
          phonelaunches++; 
          phoneclosed = 0; 
          Log.d(String.valueOf(phonelaunches),"dude that was counter"); 
         } 
        } 
        else { 
         phoneclosed = 1; 
         Log.d(str,"dude phone has been closed"); 

        } 
       } 
      } 
     } 
    },2000,3000); 

    return START_STICKY; 
} 

这里我会经历所有正在运行的任务,并检查它是否是我们的预期应用程序。如果是这样,我检查应用程序是否为前景,并且应用程序永远不会使用'phonelaunched'变量启动。当预期的应用程序在后台并且相应地设置变量时使用phoneclosed。

这一切都是服务

+1

这段代码不会在android L上运行了。改为使用'android.app.usage'包。 https://developer.android.com/reference/android/app/usage/package-summary.html – 2015-09-06 13:33:21

+0

但我不得不把它写在下面运行棒棒糖设备。我们可以在下面的棒棒糖设备中直接使用android.app.usage吗? – 2015-09-06 16:54:41