Как запустить существующий экземпляр действия из статического ярлыка

У меня есть Activity (MainActivity) в моем приложении и один статический ярлык (указанный на TempActivity).

Поскольку статические ярлыки всегда будут иметь установленные FLAG_ACTIVITY_NEW_TASK и FLAG_ACTIVITY_CLEAR_TASK, я создал TempActivity, который является невидимым действием, т.е. он запустит MainActivity, а затем вызовет finish(). А также, как предлагается в документации для разработчиков, SecondActivity имеет android:taskAffinity="" в файле AndroidManifest.xml приложения.

MainActivity имеет android:launchMode="singleTop"

Даже после этого MainActivity по-прежнему запускается в новой задаче вместо существующей задачи (создается при запуске с главного экрана).

AndroidManifest.xml

<activity
            android:name=".MainActivity"
            android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="android.app.shortcuts"
                android:resource="@xml/shortcuts" />
        </activity>
        <activity android:name=".TempActivity" android:taskAffinity=""></activity>

Ярлык

<shortcut
        android:enabled="true"
        android:icon="@drawable/icon"
        android:shortcutDisabledMessage="@string/app_name"
        android:shortcutId="static"
        android:shortcutLongLabel="@string/app_name"
        android:shortcutShortLabel="@string/app_name">
    <intent
        android:action="custom"
        android:targetClass="com.example.mobile.appshortcut.TempActivity"
        android:targetPackage="com.example.mobile.appshortcut" />
    </shortcut>

TempActivity.java

public class TempActivity extends AppCompatActivity {

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //setContentView(R.layout.activity_main2);
    //Intent intent = getIntent(); // From Shortcut
    Intent intent = new Intent(); // For Testing
    intent.setClass(this,MainActivity.class);
    startActivity(intent);
    finish();
}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
}

}

Ссылка на документацию для разработчиков https://developer.android.com/reference/android/content/pm/ShortcutManager.html


person Sankar    schedule 03.03.2017    source источник
comment
Пожалуйста, дайте минимальный, полный пример, который иллюстрирует то, что вы пытаетесь сделать.   -  person Code-Apprentice    schedule 03.03.2017
comment
@Code-Apprentice Добавлен пример кода. Надеюсь это поможет   -  person Sankar    schedule 03.03.2017
comment
вы должны включить фактический класс, который имеет метод onCreate().   -  person Code-Apprentice    schedule 03.03.2017
comment
Какова цель действия, которое только что запустило другое действие и закрылось?   -  person Code-Apprentice    schedule 03.03.2017
comment
Это подход, предложенный в документации разработчика, перейдите по ссылке, которую я упомянул.   -  person Sankar    schedule 03.03.2017
comment
Вы показали имя файла, но не класс. Вы расширяете Activity или AppCompatActivity? Если просто показать public class TempActivity extends ..., то эта информация очевидна. Это может быть не важно для вашего вопроса, но сделает ваш код более полным.   -  person Code-Apprentice    schedule 03.03.2017
comment
Я имел в виду TempActiviy, который кажется бесполезным.   -  person Code-Apprentice    schedule 03.03.2017
comment
Я добавил полный класс TempActivity. TempActivity — это тот, который запускает MainActivity, он не бесполезен.   -  person Sankar    schedule 03.03.2017
comment
Почему бы не запустить MainActivity напрямую?   -  person Code-Apprentice    schedule 03.03.2017
comment
Давайте продолжим обсуждение в чате.   -  person Sankar    schedule 03.03.2017
comment
Если я запущу MainActivity напрямую, то очевидно, что он запустится в новой задаче.   -  person Sankar    schedule 03.03.2017


Ответы (2)


android:taskAffinity="" должен быть на MainActivity, а не на TempActivity.

Итак, ваш AndroidManifest должен выглядеть примерно так:

    <activity
        android:launchMode="singleTask"
        android:taskAffinity=""
        android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>

            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>

        <meta-data
            android:name="android.app.shortcuts"
            android:resource="@xml/shortcut"/>
    </activity>
    <activity
        android:name=".TempActivity"/>

И TempActivity

public class TempActivity extends AppCompatActivity {

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        startActivity(new Intent(this, MainActivity.class));
        finish();
    }

}

И на всякий случай опубликую мой файл shortcut.xml.

<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
    <shortcut
        android:enabled="true"
        android:shortcutDisabledMessage="@string/app_name"
        android:shortcutId="compose"
        android:shortcutLongLabel="@string/app_name"
        android:shortcutShortLabel="@string/app_name">
        <intent
            android:action="android.intent.action.VIEW"
            android:targetClass="kidinov.org.test.TempActivity"
            android:targetPackage="kidinov.org.test"/>
        <categories android:name="android.shortcut.conversation"/>
    </shortcut>
</shortcuts>

Я создал пример проекта - он отлично работает. Не стесняйтесь проверить это.

person Divers    schedule 06.03.2017
comment
Спасибо, это работает. Я пытался добавить taskAffinity в MainActivity, но я думаю, что здесь и SingleTask, и taskAffinity вместе делают свое дело. Но в документах для разработчиков упоминается, что первое действие должно включать настройку атрибута android:taskAffinity= в файле приложения AndroidManifest.xml, а намерение в статическом ярлыке должно указывать на это первое действие. Если мы посмотрим на этот момент, taskAffinity должен быть там для TempActivity, не так ли? - person Sankar; 07.03.2017

Предположительно, вы используете FLAG_ACTIVITY_NEW_TASK, потому что вам нужна чистая, новая версия активности при запуске с этого ярлыка.

Вы можете переключить режим запуска MainActivity на singleInstance. Затем у вас есть возможность использовать onStart/onRestart или onNewIntent(Intent) для очистки (и сбросить активность, и взлом TempActivity больше не потребуется).

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    if (intent.getAction().equals("custom")) {
        //reset
    }
}
person Nick Cardoso    schedule 13.03.2017