Подтвердить что ты не робот

Глубокая привязка и несколько экземпляров приложений

В моем приложении реализована глубокая привязка. Я добавил этот фильтр намерений в файл манифеста, и работает глубокая привязка.

<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). Как я могу это сделать?

4b9b3361

Ответ 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) является важным