使用自定义 URL 方案通过浏览器启动 Xamarin Android 应用程序
Launch Xamarin Android App Via a Browser Using Custom URL Scheme
程序
我有一个需要 URL 方案的跨平台 Xamarin 项目。为了在 Xamarin Android 上启用此功能,我在 AndroidManifest.xml
文件中添加了以下代码,参考 launch custom android application post.
<activity android:name=".MainActivity">
<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="urlschemetest" android:host="testurl" />
</intent-filter>
</activity>
在 Android 中直接在浏览器中输入 urlschemetest://testurl
会转到 Google 搜索而不是启动应用程序。因此,我有一个简单的 html
页面,其中包含一个用于打开应用程序的超链接,。
<a href="urlschemetest://testurl">open app</a>
问题
点击上面的超链接,应用程序没有启动。 Visual Studio 在输出
中显示 Unhandled Exception
错误
Java.Lang.RuntimeException: Unable to instantiate activity
ComponentInfo{com.companyname.UrlSchemeTest/com.companyname.UrlSchemeTest.MainActivity}:
java.lang.ClassNotFoundException: Didn't find class
"com.companyname.UrlSchemeTest.MainActivity" on path: DexPathList[[zip
file
"/data/app/com.companyname.UrlSchemeTest-1/base.apk"],nativeLibraryDirectories=[/data/app/com.companyname.UrlSchemeTest-1/lib/arm,
/data/app/com.companyname.UrlSchemeTest-1/base.apk!/lib/armeabi-v7a,
/vendor/lib, /system/lib]]
尝试的解决方案
1)我查看了AndroidManifest.xml
中的attributes,可能是因为package属性与[=不匹配51=]namespace 在 MainActivity.cs
中使用。所以我改了。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="UrlSchemeTest.Droid"
android:installLocation="auto">
MainActivity.cs
namespace UrlSchemeTest.Droid
{
[Activity(Label = "UrlSchemeTest", Icon = "@mipmap/icon",
Theme = "@style/MainTheme", MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity :global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
//body here
}
}
2) 在 <activity>
标签中使用绝对类名
<activity android:name="UrlSchemeTest.Droid.MainActivity">
3) 为了查看这是否是模拟器错误,我已经在 Android 模拟器和真实 Android 设备上测试了该应用程序。
注意: 这个问题是关于如何让它在 Android 平台上运行的,尽管我已经在 Android 上创建了这个 Xamarin simple demo 并且 iOS.
说明
最初,我认为activity 名称是名称空间(或包名称)和class 名称的组合。本机 Android 和 Xamarin Android 5.1 之前的版本都是如此。 Xamarin Android 5.1 及更高版本并非如此,如 docs
中所述
Beginning with Xamarin.Android 5.1, the type name of an activity is based on the MD5SUM of the assembly-qualified name of the type being exported.
使用我的 Xamarin simple demo 应用程序,如果您构建它并打开 UrlSchemeTest.Android/obj/Debug/android 文件夹中的 AndroidManifest.xml
文件,您会看到如下内容
<activity
android:configChanges="orientation|screenSize"
android:icon="@mipmap/icon" android:label="UrlSchemeTest"
android:theme="@style/MainTheme"
android:name="md56cd34387ec86a2e1e9ba0754e1c30e2c.MainActivity">
如您所见,activity名称是md5和class名称的组合。
因此,当我在 AndroidManifest.xml
中创建 activity 时,我在构建时遇到了冲突
解决方案
首先,我需要删除AndroidManifest.xml
中的activity。 demo中需要删除以下代码
<activity android:name=".MainActivity">
<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="urlschemetest" android:host="testurl" />
</intent-filter>
</activity>
然后,在MainActivity.cs
中添加一个IntentFilter
属性
using Android.App;
using Android.Content;
[IntentFilter(new[] { Intent.ActionView },
Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
DataScheme = "urlschemetest",
DataHost = "testurl")]
public class MainActivity :global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
//code here
}
}
Url 方案现在应该可以工作了。
作为一个建议,我认为我们应该尽可能不修改AndroidManifest.xml
。
Xamarin.Android helps to minimize this difficulty by allowing you to add custom attributes to your classes, which will then be used to automatically generate the manifest for you. Our goal is that 99% of our users should never need to manually modify AndroidManifest.xml.
程序
我有一个需要 URL 方案的跨平台 Xamarin 项目。为了在 Xamarin Android 上启用此功能,我在 AndroidManifest.xml
文件中添加了以下代码,参考 launch custom android application post.
<activity android:name=".MainActivity">
<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="urlschemetest" android:host="testurl" />
</intent-filter>
</activity>
在 Android 中直接在浏览器中输入 urlschemetest://testurl
会转到 Google 搜索而不是启动应用程序。因此,我有一个简单的 html
页面,其中包含一个用于打开应用程序的超链接,
<a href="urlschemetest://testurl">open app</a>
问题
点击上面的超链接,应用程序没有启动。 Visual Studio 在输出
中显示Unhandled Exception
错误
Java.Lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.companyname.UrlSchemeTest/com.companyname.UrlSchemeTest.MainActivity}: java.lang.ClassNotFoundException: Didn't find class "com.companyname.UrlSchemeTest.MainActivity" on path: DexPathList[[zip file "/data/app/com.companyname.UrlSchemeTest-1/base.apk"],nativeLibraryDirectories=[/data/app/com.companyname.UrlSchemeTest-1/lib/arm, /data/app/com.companyname.UrlSchemeTest-1/base.apk!/lib/armeabi-v7a, /vendor/lib, /system/lib]]
尝试的解决方案
1)我查看了AndroidManifest.xml
中的attributes,可能是因为package属性与[=不匹配51=]namespace 在 MainActivity.cs
中使用。所以我改了。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="UrlSchemeTest.Droid"
android:installLocation="auto">
MainActivity.cs
namespace UrlSchemeTest.Droid
{
[Activity(Label = "UrlSchemeTest", Icon = "@mipmap/icon",
Theme = "@style/MainTheme", MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity :global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
//body here
}
}
2) 在 <activity>
标签中使用绝对类名
<activity android:name="UrlSchemeTest.Droid.MainActivity">
3) 为了查看这是否是模拟器错误,我已经在 Android 模拟器和真实 Android 设备上测试了该应用程序。
注意: 这个问题是关于如何让它在 Android 平台上运行的,尽管我已经在 Android 上创建了这个 Xamarin simple demo 并且 iOS.
说明
最初,我认为activity 名称是名称空间(或包名称)和class 名称的组合。本机 Android 和 Xamarin Android 5.1 之前的版本都是如此。 Xamarin Android 5.1 及更高版本并非如此,如 docs
中所述Beginning with Xamarin.Android 5.1, the type name of an activity is based on the MD5SUM of the assembly-qualified name of the type being exported.
使用我的 Xamarin simple demo 应用程序,如果您构建它并打开 UrlSchemeTest.Android/obj/Debug/android 文件夹中的 AndroidManifest.xml
文件,您会看到如下内容
<activity
android:configChanges="orientation|screenSize"
android:icon="@mipmap/icon" android:label="UrlSchemeTest"
android:theme="@style/MainTheme"
android:name="md56cd34387ec86a2e1e9ba0754e1c30e2c.MainActivity">
如您所见,activity名称是md5和class名称的组合。
因此,当我在 AndroidManifest.xml
解决方案
首先,我需要删除AndroidManifest.xml
中的activity。 demo中需要删除以下代码
<activity android:name=".MainActivity">
<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="urlschemetest" android:host="testurl" />
</intent-filter>
</activity>
然后,在MainActivity.cs
IntentFilter
属性
using Android.App;
using Android.Content;
[IntentFilter(new[] { Intent.ActionView },
Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
DataScheme = "urlschemetest",
DataHost = "testurl")]
public class MainActivity :global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
//code here
}
}
Url 方案现在应该可以工作了。
作为一个建议,我认为我们应该尽可能不修改AndroidManifest.xml
。
Xamarin.Android helps to minimize this difficulty by allowing you to add custom attributes to your classes, which will then be used to automatically generate the manifest for you. Our goal is that 99% of our users should never need to manually modify AndroidManifest.xml.