アプリにディープリンクを実装しました。このインテントフィルターをマニフェストファイルに追加しましたが、ディープリンクは機能しています。
<intent-filter>
<action Android:name="Android.intent.action.VIEW" />
<category Android:name="Android.intent.category.DEFAULT" />
<category Android:name="Android.intent.category.BROWSABLE" />
<category Android:name="Android.intent.category.VIEW" />
<data
Android:Host="www.mywebsite.com"
Android:pathPrefix="/something"
Android:scheme="http" />
</intent-filter>
問題は、ディープリンクを通じて、私のアプリが現在のアプリの上で起動することです。 Gmailでリンクをクリックすると、Gmailの上でアプリが起動します。アプリを別の方法で起動したい。
アプリが既にバックグラウンドで実行されている場合、Gmailで自分のアプリにリダイレクトするリンクをクリックすると、アプリの2つのインスタンスが同時に実行されます。 1つはバックグラウンドで、もう1つはGmailの上にあります。アプリのインスタンスを一度に1つだけ実行したいので、現在のアプリ(Gmail)の上にもありません。どうやってやるの?
受け入れられた答えは私にとってはうまくいきませんでした、ここに何があったのですか:
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
公式ドキュメントから:
設定されていて、起動されるアクティビティが現在のタスクで既に実行されている場合、そのアクティビティの新しいインスタンスを起動する代わりに、そのアクティビティの他のすべてのアクティビティが閉じられ、このインテントが(現在top)新しいインテントとしての古いアクティビティ。
マニフェストでアクティビティを追跡する必要があります。
Android:launchMode="singleTask"
これにより、システムは、アクティビティの既存のインスタンスが既に作成されている場合は常に起動するように指示します。
そして、メソッドをオーバーライドすることで、インテントを処理できます
onNewIntent
詳細については、 http://developer.Android.com/guide/topics/manifest/activity-element.html をご覧ください。
私はこれとまったく同じ問題を抱えていました。ただし、ユーザーがアプリに移動するためにアプリスイッチャーを使用したかのように、ユーザーがフルバックスタックでメインタスクに戻ることを望んでいました。これを実現するには、タスクを並べ替える必要がありました。
1)アプリにタスクを並べ替える許可を与える
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="com.company.app">
<uses-permission Android:name="Android.permission.REORDER_TASKS"/>
</manifest>
2)mainタスクIDが何であるかを追跡する
public class MainActivity {
public static int mainTaskId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super(savedInstanceState);
//set the main task ID
taskId = getTaskId();
}
}
3)ディープリンクアクティビティを起動すると、後で使用するためにデータが保存され、メインタスクが前面に表示されます
public class DeepLinkActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super(savedInstanceState);
//persist deep link data
Uri uri = intent.getData();
String action = intent.getAction();
saveForLater(uri, action);
if(isTaskRoot()){
//I'm in my own task and not the main task
final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
activityManager.moveTaskToFront(MainActivity.taskId, ActivityManager.MOVE_TASK_NO_USER_ACTION);
}
}
}
}
4)メインタスクのバックスタックの一番上にあるアクティビティが開始されると、作業する保存データがあるかどうかを確認し、作業します。
ディープリンクにはいくつかの問題がありました。のような:
したがって、以下は、私たちが抱えていたいくつかの問題に対する包括的な解決策という質問に対する明確な答えではありません。
当社のソリューション:
a)新しいFragmentActivityを作成しました
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2); //well can be anything some "loading screen"
Intent intent = getIntent();
String intentUrl = intent.getDataString();
Intent newIntent = new Intent(this, MainActivity.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
newIntent.putExtra("intentUrl",intentUrl);
newIntent.setAction(Long.toString(System.currentTimeMillis()));
startActivity(newIntent);
finish();
}
b)マニフェスト:
<activity
Android:name="YOUR.NEW.FRAGMENT.ACTIVITY"
Android:label="@string/app_name"
Android:launchMode="singleTop">
<intent-filter>
<action Android:name="Android.intent.action.VIEW" />
<category Android:name="Android.intent.category.DEFAULT" />
<category Android:name="Android.intent.category.BROWSABLE" />
<data Android:scheme="http" />
<data Android:scheme="https" />
<data Android:scheme="scheme1" /> <!-- sheme1://-->
<data Android:Host="yourdomain.com" />
<data Android:Host="www.yourdomain.com" />
</intent-filter>
</activity>
c)次のサンプル関数を呼び出すことにより、アクティビティonCreate()およびonResume()で渡された新しいインテントを処理します。
private void handleUrl(Intent i){
String intentUrl = null;
if (i != null) {
intentUrl = i.getStringExtra("intentUrl");
if (intentUrl == null){
//hmm intent is damaged somehow
} else {
//because of onResume()
if ( i.getBooleanExtra("used",false) ) {
return;
}
i.putExtra("used", true);
//DO SOMETHING WITH YOUR URL HERE
}
}
1つのインスタンスについてのみこの問題を解決します
Android:launchMode = "singleInstance"
<activity
Android:name=".SplashScreen"
Android:screenOrientation="portrait"
Android:launchMode="singleInstance"
Android:theme="@style/Theme.AppCompat.Light.NoActionBar.FullScreen">
<intent-filter>
<action Android:name="Android.intent.action.MAIN" />
<category Android:name="Android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter Android:autoVerify="true">
<action Android:name="Android.intent.action.VIEW" />
<category Android:name="Android.intent.category.DEFAULT" />
<category Android:name="Android.intent.category.BROWSABLE" />
<data Android:scheme="nvd.abc" />
</intent-filter>
</activity>
マニフェストファイルにAndroid:launchMode = "singleTask"を追加するだけでこれらの問題を解決します