Глубокая ссылка из Chrome в нативное приложение

Я работаю с Uber API, который использует uber://?... URL-адреса для прямой ссылки на собственное приложение Uber. Я создаю мобильный веб-сайт и создаю один из этих URL, как описано здесь ;

На iOS все работает нормально, а на Android приложение Uber открывается и получает только один из параметров product_id. Поэтому я думаю, что есть некоторая проблема с тем, как я кодирую URL-адрес и как его открывает система Android. Вот мой JS для создания URL:

uber.createURL = function() {

    var params = {
        "client_id": uber.CLIENT_ID,
        "product_id": maps.product_id,
        "pickup[latitude]": maps.noSurgeMarker.getPosition().lat(),
        "pickup[longitude]": maps.noSurgeMarker.getPosition().lng(),
        "dropoff[latitude]": maps.destMarker.getPosition().lat(),
        "dropoff[longitude]": maps.destMarker.getPosition().lng(),
        "pickup[formatted_address]": $('#pickup').val(),
        "dropoff[formatted_address]": $('#destination').val()
    };

    var url = 'uber://?action=setPickup';

    for (var key in params) {
        if (params.hasOwnProperty(key)) {
            url += ('&' + key + '=' + encodeURIComponent(params[key]));
        }
    }

    return url;
};

Затем я вызываю следующий код, чтобы открыть ссылку:

var url = uber.createURL();
window.location.href = url;

Я упускаю что-то очевидное? Опять же, это работает на iOS, но не на Android. Также странно то, что если я создаю URL-адрес с помощью createURL на компьютере, отправляю его на свое устройство Android с помощью PushBullet, открытие работает отлично. Но если я получу URL-адрес через Chrome для Android, приложение Uber откроется и будет иметь только product_id правильное значение, а не какие-либо части получения или высадки.

Примечание. Я уже использовал функцию jQuery params, но это не сработало лучше, поэтому я перешел к ручному циклу for (var key in params) {...}.


person Sam Stern    schedule 30.12.2014    source источник
comment
Попробуйте url += ('&' + encodeURIComponent(key) + '=' + encodeURIComponent(params[key]));. Я думаю, что квадратные скобки неприятны.   -  person Eugen Pechanec    schedule 09.01.2015
comment
Это был ответ @GregEnnis ниже. Это не работает...   -  person Sam Stern    schedule 09.01.2015
comment
Теперь наступает момент, когда вы ждете, пока Uber исправит свои вещи (расшифрует uri с их стороны)... Еще одна вещь, которую вы можете попробовать. В исходнике есть другое обозначение (для веб-службы в конце документа), в котором вместо квадратных скобок используется символ подчеркивания, т. е. pickup_latitude вместо pickup[latitude]. Если это не сработает, у меня нет идей.   -  person Eugen Pechanec    schedule 09.01.2015
comment
@hatboysam Помогает ли вам использовать Intent Intercept, чтобы увидеть, как именно выглядит намерение, которое получает Uber?   -  person aluxian    schedule 10.01.2015
comment
@AlexandruRosianu, это отличная идея, к сожалению, это не перехватит. Я буду часто использовать это приложение для будущих разработок, это полезно.   -  person Sam Stern    schedule 11.01.2015


Ответы (2)


Хорошо, я понял, что проблема не в кодировке, а в том, как Chrome запускает намерения для приложений. Вот намерение от Pushbullet, оно отлично работает:

I/ActivityManager(  942): START u0 
{act=android.intent.action.VIEW 
dat=uber://?
client_id=REDACTED&
action=setPickup&
product_id=a1111c8c-c720-46c3-8534-2fcdd730040d&
pickup[latitude]=37.780654&
pickup[longitude]=-122.405599&
dropoff[latitude]=37.7970558&
dropoff[longitude]=-122.43199099999998
flg=0x10000000 cmp=com.ubercab/.client.feature.launch.LauncherActivity} from pid 19023

Вот намерение от Chrome, оно запускает приложение Uber, но ни одно из данных не анализируется приложением (оно просто открывается, как если бы я щелкнул значок запуска):

I/ActivityManager(  942): START u0 
{act=android.intent.action.VIEW 
cat=[android.intent.category.BROWSABLE] 
dat=uber://?
client_id=REDACTED&
action=setPickup&
product_id=a1111c8c-c720-46c3-8534-2fcdd730040d&
pickup[latitude]=37.780654&
pickup[longitude]=-122.405599&
dropoff[latitude]=37.7970558&
dropoff[longitude]=-122.43199099999998
flg=0x10000000 cmp=com.ubercab/.client.feature.launch.LauncherActivity (has extras)} from pid 26446

Вы можете видеть, что единственное отличие состоит в добавлении cat=[android.intent.category.BROWSABLE], которое требуется для намерений, запускаемых из Chrome для Android (ссылка).

Так что в целом я думаю, что это то, что Uber придется решить. На данный момент похоже, что мне придется упаковать свой веб-сайт в WebView в приложении для Android, если я хочу, чтобы он работал.

person Sam Stern    schedule 11.01.2015
comment
Они добавили <category android:name="android.intent.category.BROWSABLE" /> в фильтр намерений, соответствующий схеме uber:// gist.github.com/mnemonicflow/ - person Alex Bitek; 26.01.2016

Вам нужно вызвать encodeUriComponent как для ключа, так и для params[key].

person Greg Ennis    schedule 30.12.2014
comment
Это даже как-то ухудшило ситуацию. Теперь даже не работает, когда копирую на телефон вручную. - person Sam Stern; 31.12.2014
comment
Хммм, может быть, это случайное кодирование = или & или ? - person Greg Ennis; 31.12.2014