Глубокая привязка и несколько экземпляров приложений
В моем приложении реализована глубокая привязка. Я добавил этот фильтр намерений в файл манифеста, и работает глубокая привязка.
<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, которая перенаправляет на мое приложение, у меня будет два экземпляра моего приложения, работающих одновременно; один в фоновом режиме, а другой поверх Gmail. Я хочу запускать только один экземпляр моего приложения за раз, поэтому он также не находится поверх текущего приложения (Gmail). Как я могу это сделать?
Ответы
Ответ 1
принятый ответ не сработал у меня, вот что:
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
из официального документа:
Если установлено, и запущенная деятельность уже запущена в текущей задаче, вместо того, чтобы запускать новый экземпляр этого действия, все остальные действия поверх него будут закрыты, и это намерение будет доставлено в (сейчас на вершине) старую деятельность как новое намерение.
Ответ 2
Вам нужно сделать следующие действия для своей деятельности в вашем манифесте.
android:launchMode="singleTask"
Это означает, что система всегда запускает существующий экземпляр Activity, если он уже создан.
И вы можете обработать Intent, переопределив метод
onNewIntent
Подробнее см. http://developer.android.com/guide/topics/manifest/activity-element.html.
Ответ 3
У меня была такая же проблема, за исключением того, что я хотел, чтобы пользователь вернулся в основную задачу с полным задним стеком, как будто они только что использовали переключатель приложения для перехода в мое приложение. Для этого мне пришлось переупорядочить задачи.
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) Следите за тем, какой идентификатор основной задачи
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) Когда начинается какая-либо работа вверху начального стека основной задачи, он проверяет, есть ли какие-либо сохраненные данные для работы и работает на нем.
Ответ 4
Ну, у нас было несколько проблем с депиптиками.
Как:
- дважды нажмите на одну и ту же ссылку, сначала щелкните по правильному представлению
- открыл несколько экземпляров
- Ссылки в whatsapp или facebook открыли представление в самом whatsapp из-за их веб-браузера.
- на android 6 открылся только один экземпляр, но он обрабатывал только первый
намерение, второе и третье открывают приложение, но не действуют, потому что намерения не изменились каким-то образом.
Итак, следующий вопрос не является четким ответом на вопрос о более широком решении для нескольких вопросов, которые у нас были.
Наше решение:
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
}
}
Ответ 5
просто решить эту проблему только для одного экземпляра
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>
Ответ 6
Я решаю эту проблему, просто добавив android: launchMode = "singleTask" в файле манифеста
Ответ 7
(инициализировать в начале урока)
String itemInfo == "";
В основном сравните название пакета.
if(!itemInfo.equals(getItem(position).activityInfo.packageName))
{
intent.setComponent(new ComponentName(getItem(position).activityInfo.packageName,
getItem(position).activityInfo.name));
itemInfo = getItem(position).activityInfo.packageName;
((AxisUpiActivtiy) context).startActivityForResult(intent, RequestCodes.START_INTENT_RESPONSE);
}
это условие itemInfo.equals(getItem(position).activityInfo.packageName)
является важным