Android、他のアプリの起動を検出


92

ユーザーがパスワードなしで指定したアプリにアクセスできないようにするアプリを開発しようとしています。シナリオは...

  1. ユーザーが「メール」アプリをクリックする(例)
  2. アプリがアプリの起動を検出した
  3. 私のアプリはそれが「メール」アプリであることを確認します
  4. 私のアプリは、パスワードを要求する上部のビューを開きます
  5. ユーザーがパスワードを入力すると、正しい場合、アプリが消え、「メール」アプリが上部に残ります

残りの部分は大丈夫です。パート2だけが私を困惑させています。数日後にBroadcast Intentsなどを読んで、試用プロジェクトで「android.intent.action.MAIN」などをリッスンしようとしましたが、できません。自分以外のアプリが起動したことを検知しているようです。

誰か助けてもらえますか?私はそれを正しい方法で行っていますか?開始するインテントをブロードキャストする新しいアプリを探していますか、それともシステムログを読んで新しいインテントがあるか、またはネイティブコードで何かをしているのですか?

あなたがそれを完全に答えることができない場合でも、私はいくつかのより多くの研究を行うことができるでしょう、どんなポインタも助けになります。どうもありがとう。イアン


彼らがどのようにそれを行ったかはわかりませんが、App Protectorのようなアプリはあなたが望んでいることを正確に実行するので、それは確かに技術的に可能です。
Hanspeide、2010

@lan問題をどのように解決したか、知識を教えてください
nida

こんにちはあなたは解決策を手に入れましたか?
ask4solutions 2016

回答:


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();
    }

また、マニフェストファイルにその権限を追加することを忘れないでください。


このコードをどこに配置する必要がありますか?サービス中?onStartCommand()?
Haythem souissi

56
JellyBean以降では機能しません。READ_LOGS権限は、システムアプリ専用に予約されています。
2012

5
これについて本当に確信がありますか?Smart AppLockはJBデバイスでもこれを実行できるように見えるためです。アプリケーションがデバイス管理者ステータスに昇格したためですか?play.google.com/store/apps/…–
Karthik Balakrishnan

1
@Torcellite、そのアプリには「Get running tasks」権限があるため、代わりにその手法を使用している可能性があります。
サム、

1
@Ranだから、今それを使用するために何をすべきか...私はジェリービーンズの上にいる必要があるので質問で述べられた問題を解決するために現在利用可能な解決策はあります...できるだけ早くフィードバックを与えてください...
Shreyan Mehta

19

それを行うギミックな方法は、チェックするタイミングループを備えたサービスを持っていることです

ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfo = am.getRunningAppProcesses();

そのリストを実行して、電話で何が実行されているかを確認します。idとprocessNameでそれらを識別できるようになったので、標準的なアクティビティの場合、識別が困難なものをすべて停止しない限り、これはカスタムアクティビティにとっても簡単です...

注:これは実際に画面に表示されているもののリストではなく、実行されているもののリストです...目標を無効化しているようなものですが、少なくとも何かが実行され始めたときはわかります...ただし、バックグラウンドの場合でもリストに表示されます。

パスワードに関しては、保護されているアプリなどを見つけたときに、アクティビティを開始できます。


アプリが起動/再開された時刻を取得することはできますか?
0LLiena 2014

4
Android L android.app.usageでは、代わりにパッケージを使用してください。developer.android.com/reference/android/app/usage/...
Plo_Koon

12

これは不可能だと思います。このような機能が悪意のあるソフトウェアによっていかに簡単に悪用される可能性があるか考えてみてください。自分に向けられたインテントとブロードキャストされたインテントを聞くことができますが、アプリケーションの起動はブロードキャストイベントであってはなりません。

あなたができるかもしれないことはランチャーを交換することです。ユーザーが同意した場合。


1
なぜそれが可能ではないのですか?それは私のデバイスであり、私はその上で何を実行するかを決定します。これは、私たちが日常的に許可する他の許可よりもどのように問題ですか?代わりのランチャーは、すべてのアプリの起動をキャッチするわけではなく、直接起動されたアプリのみを起動します。このことと、同様のスレッドについて、インテントが通り過ぎるのを簡単に確認できることは大きな問題になるだろうと主張する多くのコメントがありますが、誰が問題が何であるか、そしてなぜ既存の特権システムでは不愉快であると見なされるべきなのかを説明しません何が起こっているかをユーザーに明確にするために使用されます。
Kevin Whitefoot、2014

将来の許可が進むにつれて、これはおかしなことです。セキュリティモデルを持つことのポイントは、ほとんど(理想的にはすべて)の悪用を防ぎながら、ほとんどの正当なユースケースを有効にすることです。保護する必要があるのはあなた(おそらく知識のあるユーザー)だけでなく、アプリをインストールするナイーブユーザーや、さらに別の攻撃方法を考慮する必要がないアプリライターです。すべてのセキュリティはトレードオフです。この場合、ユーティリティとパワー、および大規模な悪用可能性の間のトレードオフです。自分でその自由度が本当に必要な場合は、Androidスタックのクローンを作成して独自のシステムをコーディングできます。
Pontus Gagge、2015年

12
class CheckRunningActivity extends Thread{
    ActivityManager am = null;
    Context context = null;

    public CheckRunningActivity(Context con){
        context = con;
        am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    }

    public void run(){
        Looper.prepare();

        while(true){
            // Return a list of the tasks that are currently running,
            // with the most recent being first and older ones after in order.
            // Taken 1 inside getRunningTasks method means want to take only
            // top activity from stack and forgot the olders.
            List< ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(1);

            String currentRunningActivityName = taskInfo.get(0).topActivity.getClassName();

            if (currentRunningActivityName.equals("PACKAGE_NAME.ACTIVITY_NAME")) {
                // show your activity here on top of PACKAGE_NAME.ACTIVITY_NAME
            }
        }
        Looper.loop();
    }
}

あなたは現在の実行Activityを取得し、これActivityEmail アプリケーションに対応しているかどうかを確認できます。

起動時に(またはデバイスの起動時に)実行CheckRunningActivity ThreadApplicationます。

new CheckRunningActivity().start();

更新: このクラスにはandroid.permission.GET_TASKS権限が必要なので、マニフェストに次の行を追加します。

<uses-permission android:name="android.permission.GET_TASKS" />

私はこのアプローチを使用していますが、これにより、ループのために「//ここにPACKAGE_NAME.ACTIVITY_NAMEの上にアクティビティを表示」が開きます。そのための回避策はありますか?
Anuj Sharma 14

目的の結果が得られたらCheckRunningActivityスレッドを停止する
Veaceslav Gaidarji '18

返信ありがとうございます。その後、このスレッドをいつ、どのように再起動しますか?スティッキサービスを使用しています。
Anuj Sharma 14

問題の状況に応じて、何を取得したいかを詳しく説明してください。
Veaceslav Gaidarji 2014

2
ここのコードではLooper.loop()while(true)ループが終了しないため、ステートメントは実行されないように見えます。これは間違いですか?
サム

11

主な問題は、Launcher(ホーム画面)が通常明示的なインテントを使用しているときに、暗黙的なインテントをリッスンしようとしていることです。

暗黙のインテントは、「誰かがこのビデオを再生します」と言いたいときに、Androidがそのインテントを処理できるアプリを選択します。

明示的な意図は、ホーム画面の「メール」アイコンをクリックするとどうなるかです。具体的には、完全修飾名(com.android.mailなど)で特定のアプリを開くようにAndroidに指示しています。

AFAIKがそのような明示的な意図を傍受する方法はありません。これはAndroidに組み込まれたセキュリティ対策であり、2つのアクティビティが同じ完全修飾パッケージ名を持つことはできません。これにより、サードパーティがアプリを複製して、そのアプリになりすますのを防ぎます。やりたいことが可能であれば、理論的には、競合するすべてのアプリの動作をブロックする可能性のあるアプリをインストールできます。

あなたがしようとしていることは、Androidセキュリティモデルに反しています。

あなたができることの1つは、特定のアプリ開発者とパートナーを組んでインテントをセキュリティシステムに転送することですが、それはおそらくあなたが対処したいことではありません。


7

getRunningTasks() Android Lでは非推奨です。

アプリの使用統計を取得するには、android.app.usageパッケージのUsageStatsクラスを使用できます。

新しいアプリ使用統計APIを使用すると、アプリ開発者はアプリケーションの使用に関する統計を収集できます。このAPIは、非推奨のgetRecentTasks()メソッドよりも詳細な使用情報を提供します。

このAPIを使用するには、最初にandroid.permission.PACKAGE_USAGE_STATSマニフェストで権限を宣言する必要があります。また、ユーザーはを介してこのアプリへのアクセスを有効にする必要がありますSettings > Security > Apps with usage access

ここでは、ユーザーがアプリケーションの使用方法に関連する統計情報を収集できるようにするアプリの使用状況の統計のAPIを使用する方法を示す基本的なアプリケーションの一例です。


どのアプリがフォアグラウンドにあるかを知るために使用統計がどのように役立つか?
Ajay

3

おそらく、バックグラウンドで常に実行されるサービスが必要です。あなたのサービスにあなたが言ったことをしてもらうよりも。カテゴリandroid.intent.category.LAUNCHERでもandroid.intent.action.MAINをリッスンします。次に、そのブロードキャストレシーバーでonReceiveメソッドをオーバーライドし、アプリケーションの名前などを確認します。


2
これは私が考えていた方法のように聞こえますが、基本的なBroadcastReceiverでMAIN(cat。LAUNCHER)ブロードキャストを受信するのに苦労しています。誰かが以前にこれを何とかやってのけたことがありますか?この段階では、アプリケーションが起動または再開されたことを検出しようとしています。次に、パッケージ名を、探し​​ている名前を保持する文字列と比較できます。
2010
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.