Search code examples
android.netxamarinmauideep-linking

Deep Linking Issue in a MAUI Android Application: ClassNotFoundException


I’m trying to implement Deep Linking in my MAUI Android application to handle ed2k links. However, when I click on an ed2k link and select my application to open it, I get the following error:

Java.Lang.RuntimeException: 'Unable to instantiate activity ComponentInfo{com.mycompany.test_maui/com.mycompany.test_maui.test_maui.MainActivity}: java.lang.ClassNotFoundException: Didn't find class "com.mycompany.test_maui.test_maui.MainActivity" on path: DexPathList[[zip file "/data/app/com.mycompany.test_maui-xpJaFrKRoLluech0atEfZQ==/base.apk"], nativeLibraryDirectories=[/data/app/com.mycompany.test_maui-xpJaFrKRoLluech0atEfZQ==/lib/arm64, /data/app/com.mycompany.test_maui-xpJaFrKRoLluech0atEfZQ==/base.apk!/lib/arm64-v8a, /system/lib64, /hw_product/lib64, /system/product/lib64, /prets/lib64]]

I’ve tried several solutions, including making sure the namespace in MainActivity.cs matches what’s specified in AndroidManifest.xml. Here’s the relevant code from my AndroidManifest.xml file and my MainActivity.cs file:

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mycompany.test_maui">
  <application android:allowBackup="true" android:icon="@mipmap/appicon" android:supportsRtl="true" android:usesCleartextTraffic="true">
    <activity android:name=".MainActivity" android:exported="true">
      <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="ed2k" />
      </intent-filter>
    </activity>
  </application>
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission android:name="android.permission.INTERNET" />
</manifest>

MainActivity.cs:

using Android.App;
using Android.Content.PM;
using Android.OS;
using Android.Widget;

namespace test_maui
{
    [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
    public class MainActivity : MauiAppCompatActivity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            // Check if the activity was started from a link
            if (Android.Content.Intent.ActionView.Equals(Intent.Action))
            {
                // Get the link
                var elink = Intent.DataString;

                // Display a message on screen with the link
                Toast.MakeText(this, "ed2k Link: " + elink, ToastLength.Long).Show();
            }
        }
    }
}

I was expecting that, upon clicking an ed2k link, my application would open and display a message on screen with the link. However, instead, I get the aforementioned error.

I hope this helps you answer the questions.


Solution

  • Java.Lang.RuntimeException: 'Unable to instantiate activity ComponentInfo{com.mycompany.test_maui/com.mycompany.test_maui.test_maui.MainActivity}: java.lang.ClassNotFoundException: Didn't find class "com.mycompany.test_maui.test_maui.MainActivity"

    On Xamarin.Android, by default, generates the Java wrappers using MD5-based class names to avoid Java class name clashing, such as:

     md579731053346ff64fcf21847b09163ce1.MainActivity 
    

    You have hard-coded a activity android:name=".MainActivity" in your manifest but the generated class will be MD5-based by default.

    You should avoid to mix up declarative attributes and manually writing the AndroidManifest.xml.

    [Activity (Label = "MyApp", MainLauncher = true, Icon = "@mipmap/ic_launcher")] is generating a piece of code in the actual used (generated) AndroidManifest.xml that looks like:

      <activity android:icon="@drawable/icon" android:label="AndroidApp1" android:name="md5c178831cd46fc53bebc42cf953f78ced.MainActivity">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
    

    and your code will be somewhere else. You can find the generated AndroidManifest.xml in the output folder .\obj\Debug\android.

    So,try to remove the manual edits from your manifest file and add your stuff via attributes if you need.

    For example:

    [Activity(Label = "Demos", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true,Exported =true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)] 
        [
        IntentFilter
        (
            new[] { Android.Content.Intent.ActionView },
            Categories = new[]
                {
                    Android.Content.Intent.CategoryDefault,
                    Android.Content.Intent.CategoryBrowsable
                },
            DataSchemes = new[] { "myapp" }
        )
    ]
        public class MainActivity:Activity
     {
    
     }