Неявное усиление ссылок в Android: пустые дополнения в Intent

Я хочу создать неявный deeplink с помощью компонентов навигации.

Но когда я запускаю свое приложение со следующим URL-адресом:

https://my-app.com/cars/ef123-aaf33/parts

Я получаю следующую ошибку:

java.lang.RuntimeException: Unable to start activity ComponentInfo{myapp/screens.car.CarActivity}: java.lang.IllegalStateException: 

Activity screens.car.CarActivity@3b8d354 has null extras in Intent { act=android.intent.action.VIEW cat=[android.intent.category.BROWSABLE] dat=https://my-app.com/... flg=0x13008000 cmp=myapp/screens.car.CarActivity }

У намерения нет дополнительных функций, но он должен содержать carUuid, определенный как заполнитель URL-адреса в deeplink. Ошибка выдается, как только оценивается navArgs().

Это моя установка:

nav_graph.xml

<fragment
    android:id="@+id/fragment_parts"
    android:name="myapp.screens.parts.PartsFragment"
    android:label="@string/parts"
    tools:layout="@layout/fragment_parts">
    <deepLink
        android:id="@+id/deepLink"
        app:uri="my-app.com/cars/{carUuid}/parts" />
    <argument
        android:name="carUuid"
        app:argType="string" />
</fragment>

AndroidManifest

<activity android:name=".screens.car.CarActivity" >
    <nav-graph android:value="@navigation/nav_graph" />
</activity>

CarActivity

class CarActivity : AppCompatActivity() {


    private val carViewModel: CarViewModel by viewModel { parametersOf(args.carUuid) }

    private val args: CarActivityArgs by navArgs()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        DataBindingUtil.setContentView<ActivityCarBinding>(this, R.layout.activity_car).also { binding ->
        binding.lifecycleOwner = this
        binding.carViewModel = carViewModel
    }

}

Полезные ссылки:

документация Android для неявных DeepLinks

на DeepLinks от RayWenderlich

---- ОБНОВЛЕНИЕ ----

Я создал минимальный образец проекта и нашел подсказки о том, что происходит / идет не так. Я разместил все в официальном трекере проблем: https://issuetracker.google.com/issues/155690730




Ответы (2)


Я получил ответ от команды навигации и решение / обходной путь, который подходит для моего случая. Более подробную информацию, включая образец проекта, можно найти здесь.

https://issuetracker.google.com/issues/155690730

ПОЧЕМУ ЭТО ПРОИСХОДИТ (ответ от системы отслеживания проблем Google)

Переход к месту назначения глубинной ссылки внутри SubActivity определенно возможен, но во время handleDeepLink() мы не создали объект NavDeepLink, чтобы иметь возможность идентифицировать переменные глубинной ссылки. Кроме того, если бы мы каким-то образом смогли проанализировать шаблон URL и поместить его в качестве дополнительного намерения, для приведенного вами примера вызов by navArgs() в SubActivity вернул бы значение «alice», которое предназначено для назначения глубинной ссылки. , а не активность.

Причина, по которой by navArgs() работает в Activity, когда вы вызываете navigate () с NavDirections, заключается в том, что ActivityNavigator добавляет дополнительные функции к Intent, который используется для запуска нового Activity. Когда вы используете глубокую ссылку от adb, вы обходите всю эту логику, а это означает, что намерение, запускающее действие, не имеет дополнительных функций, поэтому оно терпит неудачу, как должно.

Вероятно, есть лучший подход, чем вложенные Activity, для любого вашего варианта использования. При этом вы можете сделать эту работу, добавив дополнительную информацию с именем ключа к команде adb, используемой для запуска приложения по глубокой ссылке: --es "name" ‹" your string ">.

ЧТО Я ДЕЛАЮ СЕЙЧАС

Что я делаю сейчас, поскольку у меня есть полный контроль над URL-адресами deeplink, я устанавливаю deeplink для самой SubActivity. Кроме того, я даю URL-адрес deeplink также информацию о том, какое назначение SubActivity должно быть установлено как startDestination.

Этот подход мне подходит. Единственным недостатком является то, что MainActivity также создается в backstack, так что пользователь сначала возвращается к этому MainActivty при нажатии кнопки возврата. Но я могу с этим жить :)

person muetzenflo    schedule 19.05.2020
comment
Я не совсем понимаю ваше окончательное решение. Вы устанавливаете deeplink в Activity в nav_graph.xml, используя новый механизм компонентов навигации, или просто удаляете все это и устанавливаете deeplink старым способом? - person Rui; 27.10.2020
comment
Вкратце: я использую компоненты навигации. Я отправляю deeplink на ближайшее возможное действие и передаю этому действию достаточно информации, чтобы оно продолжило переход к желаемому фрагменту. - person muetzenflo; 27.10.2020
comment
Хорошо, теперь я понимаю. Я также проделал эту работу, установив deeplink в другом навигационном графе, который имеет место назначения для желаемой активности конечного места назначения фрагмента. Я пытался поместить deeplink в график назначения, но это не сработало. Это решение очень далекое от желаемого поведения. Где-то в документации должно быть предупреждение о том, что deeplink не работает должным образом с несколькими направлениями активности. Должна быть возможность передать аргумент назначения в намерение действия. - person Rui; 28.10.2020

Попробуйте вместо этого в своей deepLink:

<fragment
    android:id="@+id/fragment_parts"
    android:name="myapp.screens.parts.PartsFragment"
    android:label="@string/parts"
    tools:layout="@layout/fragment_parts">
    <argument
        android:name="carUuid"
        app:argType="string" />
    <deepLink
        android:id="@+id/deepLink"
        app:uri="my-app.com/cars/{carUuid}/parts" >
    </deepLink>
</fragment>
person Lucho    schedule 08.05.2020
comment
да, я тоже пробовал, но уже в крайнем случае, потому что в этом нет смысла. Делегаты оцениваются лениво, поэтому порядок не имеет значения. Я просто попробовал еще раз, чтобы убедиться: та же ошибка - person muetzenflo; 09.05.2020
comment
Ах да, вы правы! Обновил пост, обратите внимание, как размещен аргумент, вы можете попробовать? - person Lucho; 09.05.2020
comment
хорошая идея, но тоже не работает, извините. Lint уже предупреждает меня, что тег argument не может быть дочерним для deepLink. Все равно пробовал: та же ошибка. - person muetzenflo; 09.05.2020
comment
Как вы на самом деле делегируете carUuid? Вы отладили, что args.carUuid из CarActivityArgs не равно нулю? - person Lucho; 09.05.2020
comment
1. порядок определений xml: та же ошибка 2. Я отлаживал navArgs (), и это довольно просто: intent.extras всегда имеет значение null, поэтому nagArgs () не может даже запустить свою магию. 3. Просто попробуйте образец AAC [github.com/android/ архитектура-компоненты-образцы / дерево / мастер / и даже это не работает должным образом ... 4. Я также только что узнал об атрибуте <argument app:defaultName="carUuid" />, но тоже не помог. 5. Если это поможет: в моем приложении больше 1 Activity, но ни одно из других не создается при использовании глубинной ссылки (что нормально и ожидается ...) - person muetzenflo; 09.05.2020
comment
обнаружил ту же ошибку в системе отслеживания проблем Google: issueetracker.google.com/issues/155690730 Создадим минимальный образец и разместим его там - person muetzenflo; 09.05.2020
comment
Вы пробовали с версией 2.2.2, чтобы проблема не исчезла? - person Lucho; 09.05.2020
comment
Просто для пояснения, как делегировать args строковое свойство carUuid? Можете ли вы обновить свой пост с его помощью. - person Lucho; 09.05.2020
comment
Кстати, спасибо за помощь! Я не совсем понимаю, что вы имеете в виду, задавая последний вопрос. Сам я ничего не делегирую. Согласно документации по навигации, код, который я использую, - это все необходимое для работы. - person muetzenflo; 09.05.2020
comment
Позвольте нам продолжить это обсуждение в чате. - person Lucho; 09.05.2020