Запуск приложения Android из браузера

Я просмотрел несколько вопросов о переполнении стека с похожими заголовками. Каждому ответили, и оригинальный автор кажется удовлетворенным, но когда я пытаюсь воспроизвести их результаты, я прихожу с пустыми руками. Очевидно, я делаю что-то ужасно неправильно, но я не могу понять это.

Для справки, это те вопросы, на которые я смотрел:

В конечном счете, я хочу использовать это для перезапуска моего приложения, как только пользователь выполнил запрос аутентификации OAuth. Однако мое реальное приложение слишком велико, чтобы публиковать здесь. По этому вопросу я собрал простое приложение, чтобы показать вам, что я сделал. У меня есть два вида деятельности. Это происходит главным образом потому, что каждый пример, который я видел, использует действие, использующее действие VIEW. Я бы предпочел использовать MAIN-действие, но я использовал оба здесь, чтобы показать, что я попробовал оба.

AndroidManifest.xml(оригинал, см. отредактированную версию ниже)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="org.example" android:versionCode="1" android:versionName="1.0-SNAPSHOT">
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
    <activity android:name=".HelloAndroidActivity">
        <intent-filter>
            <data android:scheme="ex1"/>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
    <activity android:name=".CallbackActivity">
        <intent-filter>
            <data android:scheme="ex2"/>
            <action android:name="android.intent.action.VIEW"/>
        </intent-filter>
    </activity>
</application>

AndroidManifest.xml(Отредактировано в ответ на комментарий)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="org.example" android:versionCode="1" android:versionName="1.0-SNAPSHOT">
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
    <activity android:name=".HelloAndroidActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
    <activity android:name=".CallbackActivity">
        <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:host="www.this-so-does-not-exist.com" android:scheme="http" />
        </intent-filter>
    </activity>
</application>

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>

HelloAndroidActivity.java

package org.example;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.widget.TextView;

public class HelloAndroidActivity extends Activity {

    private TextView textView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        textView = (TextView) findViewById(R.id.textView);
    }

    @Override
    public void onResume() {
        super.onResume();
        Intent intent = getIntent();
        Uri data = intent.getData();
        if (data != null) {
            textView.setText("Hello Web!");
        }
    }

}

CallbackActivity.java

package org.example;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.widget.TextView;

public class CallbackActivity extends Activity {

    private TextView textView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        textView = (TextView) findViewById(R.id.textView);
    }

    @Override
    public void onResume() {
        super.onResume();
        Intent intent = getIntent();
        Uri data = intent.getData();
        if (data != null) {
            textView.setText("Hello Web!");
        }
    }

}

Это происходит достаточно успешно. Затем внутри браузера, если я введу ex1://helloworld или ex2://helloworld, я получаю разные результаты в зависимости от того, как это делается. Если я ввожу его в строку url, я получаю поиск google для ex1://helloworld. Если я сделаю это через перенаправление, я получаю "веб-страницу недоступна". Если я попытаюсь начать прямо с чего-то похожего на:

    Intent intent = new Intent(Intent.ACTION_MAIN);
    ComponentName componentName = new ComponentName(
            "org.example",
            "org.example.HelloAndroidActivity");
    intent.setComponent(componentName);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setData(Uri.parse("ex1://helloworld"));
    intent.addCategory(Intent.CATEGORY_BROWSABLE);
    startActivity(intent);

Я получаю по умолчанию "Hello my-example!". Я не уверен, что я делаю неправильно. Любые идеи?

Ответ 1

Вы не можете использовать MAIN - URL-адреса в Android только VIEW ed из браузера или WebView.

Кроме того, ни один из ваших фильтров Intent не включает категорию BROWSABLE, поэтому они никогда не будут работать с браузером.

Не рекомендуется придумывать свои собственные схемы. Вы можете использовать обычную схему HTTP для определенного домена, который вы контролируете. Этот пример проекта демонстрирует это. В частности, вы можете следовать шаблону, показанному этим фильтром:

<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:host="www.this-so-does-not-exist.com" android:scheme="http" />
</intent-filter>

заменив www.this-so-does-not-exist.com тем, что у вас есть, и, возможно, добавив в path, чтобы сузить область фильтра. Вы также можете увидеть эту технику, используемую приложением сканера штрих-кода от ZXing.

Ответ 2

Попробуйте, если вы хотите запустить приложение из браузера Я сделал это вчера

1) На localhost сделайте страницу html

<html>
<head>
</head>
<body>
<a href="yourownscheme://example.com/">Test link</a>
</body>
</html>

2) сделать класс

   import org.xml.sax.Parser;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

public class URLHandler extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);



    TextView uri=(TextView)findViewById(R.id.uri);
    TextView uri2=(TextView)findViewById(R.id.uri);


    if (Intent.ACTION_MAIN.equals(getIntent().getAction())) {
      String intentUri=(new Intent("yourownscheme://example.com/")).toUri(Intent.URI_INTENT_SCHEME).toString();



      uri.setText(intentUri);

    }
   }
  }

3) манифест ниже

<?xml version="1.0" encoding="utf-8"?>
<manifest android:versionCode="1"
          android:versionName="1.0"
          package="yourpackage name"
          xmlns:android="http://schemas.android.com/apk/res/android">

  <supports-screens android:largeScreens="true"
                    android:normalScreens="true"
                    android:smallScreens="false" />
  <application android:icon="@drawable/cw"
               android:label="@string/app_name">



      <activity
        android:name=".URLHandler"
        android:label="@string/app_name" 
        android:exported="true">
        <intent-filter>

            <data  android:scheme="yourownscheme://example.com/" />

            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.BROWSABLE" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>


  </application>
</manifest>

4) Когда вы установили свое приложение на эмулятор, откройте браузер и перейдите на localhost коснитесь ссылки и вашего приложения, если оно будет запущено, другое будет ошибкой