使用 Java 脚本从 URL 打开意图在生产环境中不起作用 - DeepLink

Open intent from URL using Java Script is not working on production - DeepLink

这里有点神秘,我的 onCreate 方法中有这段代码:

    Intent intent = getIntent();

    if (Intent.ACTION_VIEW.equals(intent.getAction())) {
        Log.i(TAG, "ACTION_VIEW START");
        Uri uri = intent.getData();

        SharedPreferences.Editor tEditor = getSharedPreferences("UserFormPreferences", MODE_PRIVATE).edit();

        tEditor.putString("GuestRoomNumber", uri.getQueryParameter("h"));
        tEditor.putString("GuestSurname", uri.getQueryParameter("a"));
        tEditor.apply();
        //it shows an alert to the user
        GuestLogin(uri.getQueryParameter("h"), uri.getQueryParameter("a")); 
        Log.i(TAG, "ACTION_VIEW END");
    }

我的清单中有这段代码:

    <activity
        android:name="epinom.jm.smarthotel.vcMainScreen"
        android:label="@string/title_activity_home"
        android:launchMode="standard"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="epinom.jm.smarthotel.vcMainScreen" />

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

我正在从一个网页执行这个 JS:

window.location = "com.guestperience://?h=x&a=x";

所以有趣的部分来了,如果我插入 phone,然后在 Android Studio 中,我单击“播放”或“调试”按钮,然后转到“邮件应用程序”并点击一个 hyperlink,它将我带到我在 Chrome 中的具有 JS 指令的网页,它打开我的应用程序并像我期望的那样使用 onCreate 和 onStart 方法打开意图并将其添加到我的应用程序中的意图堆栈,这意味着如果我在我的应用程序的任何意图上并且我执行了 JS,该应用程序就会出现在前面并创建意图并执行它应该做的事情并显示警报用户。

但是,如果我拔下插头或使用 Beta 版 Play 商店中的 .apk,此功能将不起作用,而且我不明白其中的区别,因为对我来说是相同的代码,所以这是我未连接到 Android Studio 时发生的情况:

我尝试将代码更改为 onStart,但它几乎是相同的行为:

最后,我不明白为什么当我插入 Android Studio 时行为会有所不同。

也许是我缺少某些权限或我必须配置的东西,但我迷路了。

我们将不胜感激。

谢谢。

更新 1:

我检测到这个:

AndroidStudio 正在做一些事情让它发挥作用,我认为它必须有权限,但我真的迷路了。

更新 2:

我已经尝试了这个例子的所有选项,我仍然得到相同的结果,如果应用程序打开我无法达到目的,但如果应用程序已关闭或已插入 Android Studio 工作起来很有魅力。

  <!-- Allow web apps to launch Barcode Scanner by linking to http://zxing.appspot.com/scan. -->
  <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" android:host="guestperience.com" android:path="/Main"/>
  </intent-filter>
  <!-- Support zxing://scan/?... like iPhone app -->
  <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="com.guestperience" android:host="Main" android:path="/"/>
  </intent-filter>

我已尝试将其附加到启动器 Intent,但似乎没有任何效果。

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

我已尝试从 href 启动应用程序,以查看是否需要用户操作,但结果仍然相同。

<a href="intent://Main/#Intent;scheme=com.guestperience;package=epinom.jm.smarthotel;end"> CLICK HERE TO LOGIN </a>

https://developer.chrome.com/multidevice/android/intents

https://github.com/zxing/zxing/blob/master/android/AndroidManifest.xml

更新 3:

我添加了这个来跟踪应用程序打开后调用的操作:

Log.i(TAG, intent.getAction().toString()); 

如果我第一次打开我的应用程序,该值为:

"com.guestperience://Main/"

但是如果我打开另一个意图并再次通过 link 打开应用程序,结果就是我调用的最后一个操作,即:

"epinom.jm.smarthotel.vcMainScreen"

当然,如果我使用 Android Studio 打开应用程序,我总是会得到这个值:

"com.guestperience://Main/"

因为所有应用程序都可以通过 JSON 文件进行配置,所以我的所有活动都有意图过滤器,所以我的所有调用都像:

Intent tIntent = new Intent("epinom.jm.smarthotel.vcMainScreen"); //replacing this "epinom.jm.smarthotel.vcMainScreen" with the JSON string var of course
startActivity(tIntent);
finish();

我也读过这个,据我所知我没有遗漏任何东西:

http://developer.android.com/intl/es/training/app-indexing/deep-linking.html

经过大量测试和大量阅读后,我已经完成了一个扩展 Activity 的基础 class 并且我的 Main Activity 扩展自基础 Activity.

public class BaseActivity extends Activity {

}

public class vcMainScreen extends BaseActivity {

}

然后在 Base 的 onStart() 上 Activity 我添加了这段代码来处理来自浏览器的调用:

@Override
protected void onStart() {
    super.onStart();
    Intent intent = getIntent();

    if (Intent.ACTION_VIEW.equals(intent.getAction())) {
        Uri uri = intent.getData();

        SharedPreferences.Editor tEditor = getSharedPreferences("UserFormPreferences", MODE_PRIVATE).edit();

        tEditor.putString("GuestRoomNumber", uri.getQueryParameter("h"));
        tEditor.putString("GuestSurname", uri.getQueryParameter("a").replace("/",""));
        tEditor.apply();

        Intent tIntent = new Intent("epinom.jm.smarthotel.vcMainScreen");
        tIntent.putExtra("Login", "true");
        startActivity(tIntent);
        finish();
    }
}

如您所见,它调用 Main Activity 并在 onStart() 中添加了以下行以调用我的登录方法:

@Override
protected void onStart() {
    super.onStart();

    if (getIntent().getExtras() != null && getIntent().getExtras().getString("Login") != null && getIntent().getExtras().getString("Login").equals("true")) {
        SharedPreferences tPrefs = getSharedPreferences("UserFormPreferences", MODE_PRIVATE);

        GuestLogin(tPrefs.getString("GuestRoomNumber", ""), tPrefs.getString("GuestSurname", ""));
        getIntent().putExtra("Login", "false");
    }
}

并且在清单中我添加了这段代码:

<activity
    android:name="epinom.jm.smarthotel.BaseActivity"
    android:label="@string/title_activity_home"
    android:launchMode="singleTask"
    android:screenOrientation="portrait">
    <intent-filter>
        <data android:scheme="com.guestperience" android:host="Main" android:path="/"/>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.BROWSABLE" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

<activity
    android:name="epinom.jm.smarthotel.vcMainScreen"
    android:label="@string/title_activity_home"
    android:launchMode="standard"
    android:screenOrientation="portrait">
    <intent-filter>
        <action android:name="epinom.jm.smarthotel.vcMainScreen" />

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

Base Activity 有一个 launchMode="singleTask" 很重要,最后我必须像这样使用 URL:

<a href="intent://Main/?h=1&a=surname/#Intent;scheme=com.guestperience;package=epinom.jm.smarthotel;end"> CLICK HERE TO LOGIN </a>

我正在使用这个 GIT 来处理我的 DeepLink 并进行一些更改:

https://github.com/hampusohlsson/browser-deeplink

我确定这不是正确的做法,但我希望这对以后的人有所帮助。

祝大家编码愉快。