Android外部喚起アプリケーションジャンプ指定ページ

6408 ワード

通常、微信のモーメンツなどにコンテンツを共有し、コンテンツのボタンをクリックすると自分のアプリケーションを呼び起こすシーンがあります.
ここではschemeを用いてジャンプを実現し、まず考えを整理し、まず外部がAppを呼び覚ますことができるようにするには、Appは必ずグローバルなイベントリスニングを登録しなければならないだろう.次に、受信イベントを処理して特定のパラメータを解析し、特定のページにジャンプするページがあるはずです.こんなに簡単です.
考えがうまくいったら、一つ一つ実現しましょう.
イベントリスニングの登録
ここではAndroid Activityを使用する必要があります.ここでは、Activityという名前の解析ジャンプを作成できます.名前は任意に付けられ、Manifestファイルに特定のを構成する必要があります.

    
    

    
    



以上のように構成すると、このActivityは外部から起動する能力を備えているので、注意してください.の関連構成は、上記のように構成すると、外部のリンク形式はこのようになるはずです.test://lovejjfg.com/xxxです.には他の内容も定義できますが、ここでは展開しません.
ページジャンプ
咳咳、ここで注意してください.例えば、起動ページAがあります.ホームページはBです.今、指定したCページにジャンプします.では、外部からAppを呼び起こすとき、実はいくつかの状況があります.これは私たちが考えなければなりません.
まず、これは製品のニーズによって決まります.それは、具体的なページを開くことです.そのページだけを起動し、ロールバックしてブラウザに戻るか、Appを起動する必要がありますか.ページを開くだけなら簡単で、新しいタスクスタックの状況を考慮する必要はありません.ロールバックしてターゲットAppを起動する場合、ユーザーが直接ブラウザに戻る場合は、いくつかの状況を区別します.
1つ目は、現在の携帯電話でターゲットアプリが起動されていないことです.簡単に言えば、ブラウザが直接Cページにジャンプし、ロールバックするときは、Aページを表示してBページに入ります.ここでは、自分でスタックを作成し、A、Cを順番に入れる必要があるので、CはAに戻り、AはBを起動することができます.知識点はTaskStackBuilderで、それに合わせてManifestでParentの属性を指定することができます.
Activity論理親のクラス名.ここでの名前は、対応する要素のandroid:nameプロパティに指定されたクラス名と一致する必要があります.ユーザーが操作バーの「上へ」ボタンを押したときにどのActivityを起動すべきかを決定するために、このプロパティが読み込まれます.システムはまた、これらの情報を利用してTaskStackBuilderを介してActivityの戻りスタックを合成することもできる.APIレベル4~16をサポートするには、「android.support.PARENT_ACTIVITY」の値を指定する要素を使用して、親Activityを宣言することもできます.
だからここはあなたの相性次第です.次にこのTaskStackBuilderの使用を見てみると、実は難しくなく、写し取ることができます.ははは.詳細は公式ドキュメントを参照してください.ここではPendingIntentの開き方を説明していますが、ここでは実際にstartActivity()の方法を直接説明しています.これはどのように操作しますか.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(resultIntent.getComponent());
stackBuilder.addNextIntent(resultIntent);
stackBuilder.startActivities();

実は私は最初はActivityを直接開くにはどのように操作する必要があるか分かりませんでした.写したところにはそう書いていないので、写していないものは自分で方法を見に行きます.最初はstackBuilder.getIntents()の方法を見て、機知に富んだ私は急いで試して、context.startActivities()を呼び出すのはやはり効果があって、後でやっと人のbuilderが直接Activityの方法を開くことがあることを発見して、間違いなく上の書き方です.
待って、Builderはどうして私にこのように書かれたのですか?これはBuilder を侮辱しているのではないでしょうか.
TaskStackBuilder.create(this)
        .addParentStack(resultIntent.getComponent())
        .addNextIntent(resultIntent)
        .startActivities();

これが一番正しい操作ですね.次に2つ目のケースでは、ターゲットAppが起動し、バックグラウンドで実行され、指定されたCページが開いていません.上記の方法では、Appが起動しても起動してもいなくても、再起動します.これは少し不快ですが、なぜ毎回再起動するのでしょうか.起動方法を見ればわかりますよ.
public void startActivities(Bundle options) {
    if (mIntents.isEmpty()) {
        throw new IllegalStateException(
                "No intents added to TaskStackBuilder; cannot startActivities");
    }

    Intent[] intents = mIntents.toArray(new Intent[mIntents.size()]);
    intents[0] = new Intent(intents[0]).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
            IntentCompat.FLAG_ACTIVITY_CLEAR_TASK |
            IntentCompat.FLAG_ACTIVITY_TASK_ON_HOME);
    if (!ContextCompat.startActivities(mSourceContext, intents, options)) {
        Intent topIntent = new Intent(intents[intents.length - 1]);
        topIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        mSourceContext.startActivity(topIntent);
    }
}

ポイントを見て、この方法は毎回1つ目のIntentにIntent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK | IntentCompat.FLAG_ACTIVITY_TASK_ON_HOMEという3つのFlagを追加して、IntentCompat.FLAG_ACTIVITY_CLEAR_TASKがあるのでこのようになりますが、どうやって解決しますか?実はとても简単で、私达はジャンプする时まず今のAppがすでに开いたかどうかを判断して、、、なければ、それでは直接上のコードで、あれば、それではスタックを作成する必要はありませんて、直接开けばいいです.直接開くときはIntent.FLAG_ACTIVITY_NEW_TASKのFlagを加えてください.そうしないと、ブラウザがあるスタックの中にあります.
if (ViewUtils.isLaunchedActivity(this, HomeActivity.class)) {
    resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(resultIntent);
} else {
    TaskStackBuilder.create(this)
            .addParentStack(resultIntent.getComponent())
            .addNextIntent(resultIntent)
            .startActivities();
}

public static boolean isLaunchedActivity(@NonNull Context context, Class> clazz) {
    Intent intent = new Intent(context, clazz);
    ComponentName cmpName = intent.resolveActivity(context.getPackageManager());
    boolean flag = false;
    if (cmpName != null) { 
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List taskInfoList = am.getRunningTasks(10);
        for (ActivityManager.RunningTaskInfo taskInfo : taskInfoList) {
            if (taskInfo.baseActivity.equals(cmpName)) { 
                flag = true;
                break;
            }
        }
    }
    return flag;
}

3つ目は、ターゲットAppが起動し、バックグラウンドで実行され、指定されたCページが開いています.
これは実は起動モードの問題で、Cはすでに開いて、また一回開いて、もしまともな起動モードならば、ここはきっと複数のCページが繰り返し現れて、だから、1つのSingleTopを設定して問題を解決することができます.もちろん、このモードが設定されている場合は、onNewIntent()の方法を処理する必要があります.
パラメータ解析
パラメータは自分がどのように定義したかを見てみましょう.例えば、私が定義したのはtest://lovejjfg.com/C?10086です.
Uri data = getIntent().getData();
String host = data.getHost();
String path = data.getPath();
String id = data.getQueryParameter("id")
String scheme = data.getScheme();
Log.i(TAG, "host: " + host);//lovejjfg.com
Log.i(TAG, "path: " + path);//C
Log.i(TAG, "scheme: " + scheme);//test
Log.i(TAG, "id: " + id);//'10086'

上記の考え方はschemeジャンプアプリケーションの使用に限らず、Notificationの方式も同様である.またstartActivities()のポーズはかっこいいのではないでしょうか.
PS:用事がなければ公式文書をたくさん見てください.多くはもう漢化しています.
-2017-12 28更新-
多くの若者が似たようなニーズを持っているため、一部の問題はコメントの返事で解決されている.テストDemoとテストリンクを追加し、通知ジャンプを追加し、みんなのテストを便利にします.
アドレス:https://github.com/lovejjfg/EasyJump