java - 使用Java Script从URL打开 Intent 不适用于生产-DeepLink

标签 java android android-studio deep-linking

我在这里有一个谜,我的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";


因此,有趣的是,如果我插入手机,然后在Android Studio中,单击“播放”或“调试”按钮,然后转到“邮件”应用,然后点击超链接,该超链接会将我带到Chrome中的网页具有JS指令的应用程序,它将打开我的应用程序,并使用onCreate和onStart方法打开意图,如我期望的那样,并将其添加到我的应用程序中的意图堆栈中,这意味着如果我对我的应用程序有任何意图,并且我执行JS,应用程序位于最前面,它创建意图并执行应做的事情,并向用户显示警报。

但是,如果我拔掉插头或使用Beta版Play商店中的.apk,则此功能将无法正常工作,而且我也无法理解两者之间的区别,因为对我而言,它们是相同的代码,所以当我没有连接到Android Studio:


如果该应用程序关闭,则单击链接,它会打开Chrome并启动该应用程序,并且该应用程序的第一个意图与我要调用的意图相同,执行应做的事情并显示警报。
打开应用程序后,如果我重复上述步骤,它就永远不会显示意图,而无论我处于初始意图还是另一个意图都没关系。


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


如果该应用程序关闭,则单击链接,它会打开Chrome并启动该应用程序,并且该应用程序的主要意图与我所调用的相同,执行应做的事情并显示警报。
一旦打开应用程序(如果我重复上述步骤),它只会在我处于主要意图时(与我所说的一样)显示警报,如果我处于另一个意图中,则它永远不会显示意图,但是如果我导航出于意图,每次调用它都会显示该警报。 (在每个onStart上,都可以通过bool对其进行控制)。


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

也许是我丢失了一些权限,或者我必须配置某些权限,但我迷路了。

任何帮助将不胜感激。

谢谢。

更新1:

我检测到此:


如果我插上电话并按Play键,并保持插上电源,一切都将像灵符一样运作。
如果我插上电话并按Play键,然后拔下插头,则一切都将像灵符一样运作。
如果我插入电话并按Play键并关闭应用程序(可以插入插头或不插入插头),则当我启动带有链接的应用程序时,它就像一个超级按钮,但是如果该应用程序启动,它就无法按任何意图工作。


Android Studio正在执行某项操作以使其正常运行,我认为它必须具有权限,但我真的迷路了。

更新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>


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

<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/"


但是,如果我打开另一个意图并再次通过链接打开应用程序,那么结果就是我叫的最后一个动作,即:

"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,而我的Main Activity从Base Activity扩展了。

public class BaseActivity extends Activity {

}

public class vcMainScreen extends BaseActivity {

}


然后,在基本活动的onStart()上,我添加了以下代码来处理来自浏览器的调用:

@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();
    }
}


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

@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>


重要的是,基本活动必须具有launchMode =“ singleTask”,最后我必须使用如下网址:

<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

我敢肯定这不是正确的方法,但是我希望这对将来的人有所帮助。

祝大家编码愉快。

关于java - 使用Java Script从URL打开 Intent 不适用于生产-DeepLink,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33756910/

相关文章:

java - 在 Qpid 上调用的 RabbitMQ Java API queuePurge() 方法返回消息计数为零的 PurgeOK 响应

java - 线段之间的相交问题

java - 在抽屉导航中更改特定菜单项的文本大小

android-studio - Android Studio - 无法解析符号 'Glide'

java - 将 4D 数组保存到文件时出现问题

java - 为什么 setHeader 不在流程功能内工作而是在功能之外工作

java - 混淆 Android 库项目/apklib

android - 当我尝试创建 apk 时,Flutter 卡在 "Running Gradle task ' bundleRelease'...”

android - 手机休眠时播放声音

Android Studio 调试和 DDMS