<< Android-Note

他アプリの起動の監視

自アプリ以外で他のアプリが起動したかどうかを知りたいときはそれ用のAPIが用意されていないのでその代わりをここを参考にして自作してみました。

これ以外にも方法があるかもしれませんが、ここではタイマーを使って次の手順でアプリの起動を監視し続けてみます。

  1. 起動中のアプリを調べる
  2. その中で最前面のアプリを見つける

アプリは必ずしもアクティビティなどを持っているとは限らないのでアプリがUIを持つ時(つまりサービス以外)だけアプリが起動したとみなします。

サービスの実装

上の手順でアプリの起動を監視し続けるサービスを作ります。

ここではMonitorLaunchServiceという名前で次のサービスを作ってみました。

public class MonitorLaunchService extends Service 
{
    private Timer timer;

    public int onStartCommand(Intent intent, int flags, int startId)
    {
        timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask()
        {
            @Override
            public void run() 
            {
                RunningAppProcessInfo appInfo = getForegroundAppInfo();
                if(appInfo == null)
                    return;
                    
                if(appInfo.processName.equals("パッケージ名")){
                
                }else{

                }
            }
            
        },0, 5000);
        return START_STICKY;
    }
    
    /**現在画面に表示されているアプリの情報を返す。*/
    public RunningAppProcessInfo getForegroundAppInfo()
    {
        final ActivityManager activityManager  
            = (ActivityManager)getSystemService(ACTIVITY_SERVICE);

        List <RunningAppProcessInfo> appInfoList 
            = activityManager.getRunningAppProcesses();
        for(RunningAppProcessInfo appInfo : appInfoList){
            if(appInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND
                    && !isRunningService(appInfo.processName)) {
                return appInfo;
            }
        }
        return null;
    }
    
    /**もしプロセスがサービスならtrueを返す。*/
    private boolean isRunningService(String processName) {
        if(processName == null)
            return false;

        final ActivityManager activityManager 
        = (ActivityManager)getSystemService(ACTIVITY_SERVICE);

        List <RunningServiceInfo> serviceInfoList 
            = activityManager.getRunningServices(Integer.MAX_VALUE);
        for(RunningServiceInfo serviceInfo : serviceInfoList){
            if(serviceInfo.process.equals(processName))
                return true;
        }
        
        return false;
    }   
    
    @Override
    public IBinder onBind(Intent arg0)
    {
        return null;
    }

    @Override
    public void onDestroy()
    {
        if(timer != null){
            timer.cancel();
            timer = null;
        }
    }
}

この例では5秒おきに画面に表示されているアプリを調べています。

また、アクティビティなどを持たないサービスだけのアプリもあるかもしれないので、そうだったときの処理もしています。

最後にAndroidManifest.xmlに自作したServiceを追加して完成です。

        <service android:name="com.xxx.myapp.FilterTouchService"/>
    </application>

この方法の欠点は起動を感知するまで多少ラグが生じてしまう所です。

でも他になかなかいい方法がなかったのでこれを使うことにしました。

関連項目
プライバシーポリシー