1

I created a service to swap out the default keyboard with my custom keyboard...the code for my custom keyboard works (i tested in a app). i wrapped the code in a service and deployed it to the android device. When i try to enable my custom keyboard from the device, it just keeps crashing...i used log cat to grab the exception. here is the exception:

Time Device Name Type PID Tag Message 06-03 00:03:38.287 Samsung SM-J327P Error 3044 AndroidRuntime java.lang.RuntimeException: Unable to instantiate service SimpleKeyboard.SimpleKeyboard.Activity1: java.lang.ClassNotFoundException: Didn't find class "SimpleKeyboard.SimpleKeyboard.Activity1" on path: DexPathList[[zip file "/data/app/SimpleKeyboard.SimpleKeyboard-1/base.apk"],nativeLibraryDirectories=[/data/app/SimpleKeyboard.SimpleKeyboard-1/lib/arm, /data/app/SimpleKeyboard.SimpleKeyboard-1/base.apk!/lib/armeabi-v7a, /vendor/lib, /system/lib]] at android.app.ActivityThread.handleCreateService(ActivityThread.java:3844) at android.app.ActivityThread.access$2100(ActivityThread.java:231) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1911) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:7422) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

posted below is my manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="SimpleKeyboard.SimpleKeyboard" android:versionCode="1" android:versionName="1.0" android:installLocation="auto">
    <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="23" />
    <uses-permission android:name="android.permission.READ_LOGS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <application>
        <service android:name=".Activity1" android:label="@string/app_name" android:permission="android.permission.BIND_INPUT_METHOD" android:exported="true">
            <intent-filter>
                <action android:name="android.view.InputMethod" />
            </intent-filter>
            <meta-data android:name="android.view.im" android:resource="@xml/method" />
        </service>
    </application>
</manifest>

here is the service:

public class Activity1 : InputMethodService
    {
        private KeyboardView kv;
        private Keyboard keyboard;
        private bool isCaps = false;

        public Activity1()
        {

        }
        public override void OnInitializeInterface()
        {
            if (IsExternalStorageWritable())
            {

                File appDirectory = new File(Android.OS.Environment.DirectoryDownloads + "/MyPersonalAppFolder");
                File logDirectory = new File(appDirectory + "/log");
                File logFile = new File(logDirectory, "logcat" + Guid.NewGuid() + ".txt");

                // create app folder
                if (!appDirectory.Exists())
                {
                    appDirectory.Mkdirs();
                }

                // create log folder
                if (!logDirectory.Exists())
                {
                    logDirectory.Mkdirs();
                }

                // clear the previous logcat and then write the new one to the file
                try
                {
                    Java.Lang.Process process = Runtime.GetRuntime().Exec("logcat -c");
                    process = Runtime.GetRuntime().Exec("logcat -f " + logFile);
                }
                catch (IOException e)
                {
                    e.PrintStackTrace();
                }

            }
            else if (isExternalStorageReadable())
            {
                // only readable
            }
            else
            {
                // not accessible
            }
            base.OnInitializeInterface();
        }
        public override void OnCreate()
        {
            if (IsExternalStorageWritable())
            {

                File appDirectory = new File(Android.OS.Environment.DirectoryDownloads + "/MyPersonalAppFolder");
                File logDirectory = new File(appDirectory + "/log");
                File logFile = new File(logDirectory, "logcat" + Guid.NewGuid() + ".txt");

                // create app folder
                if (!appDirectory.Exists())
                {
                    appDirectory.Mkdirs();
                }

                // create log folder
                if (!logDirectory.Exists())
                {
                    logDirectory.Mkdirs();
                }

                // clear the previous logcat and then write the new one to the file
                try
                {
                    Java.Lang.Process process = Runtime.GetRuntime().Exec("logcat -c");
                    process = Runtime.GetRuntime().Exec("logcat -f " + logFile);
                }
                catch (IOException e)
                {
                    e.PrintStackTrace();
                }

            }
            else if (isExternalStorageReadable())
            {
                // only readable
            }
            else
            {
                // not accessible
            }
            base.OnCreate();
        }
        public override View OnCreateInputView()
        {


            keyboard = new Keyboard(this, Resource.Xml.Qwerty);
            View kvl = (View)LayoutInflater.Inflate(Resource.Layout.Keyboard, null);
            kv = kvl.FindViewById<KeyboardView>(Resource.Id.keyboard);
            kv.Keyboard = keyboard;
            kv.OnKeyboardActionListener = new MyKeyboardListener(this); 
            return kv;
            // return null;
        }
        /* Checks if external storage is available for read and write */
        public bool IsExternalStorageWritable()
        {
            string state = Android.OS.Environment.ExternalStorageState;
            if (Android.OS.Environment.MediaMounted.Equals(state))
            {
                return true;
            }
            return false;
        }

        /* Checks if external storage is available to at least read */
        public bool isExternalStorageReadable()
        {
            string state = Android.OS.Environment.ExternalStorageState;
            if (Android.OS.Environment.MediaMounted.Equals(state) ||
                    Android.OS.Environment.MediaMountedReadOnly.Equals(state))
            {
                return true;
            }
            return false;
        }
    }

What i am i doing wrong?

Daron
  • 113
  • 2
  • 13

2 Answers2

0

java.lang.ClassNotFoundException: Didn't find class

Refer to @SushiHangover's answer:

Workaround:

You can clean/rebuild as a workaround on Windows.

York Shen
  • 9,014
  • 1
  • 16
  • 40
  • I have tried clean/rebuild multiple times...still getting the same error...if this is a problem in 8.1, would downgrading the project help? Also, you said it is an issue on windows...in theory, this should work on mac? – Daron Jun 05 '18 at 13:12
  • @Daron, that's weird, it should be work. If possible, would you mind sharing a basic demo that can reproduce the problem through online repo? Just to make sure we are verifying the exact same thing you are using. – York Shen Jun 05 '18 at 13:40
  • here is a link to my dropdox, there project is zipped.. https://www.dropbox.com/s/x32wqikzkiftg4n/SimpleKeyboard.rar?dl=0 – Daron Jun 06 '18 at 01:23
  • Just realized I'm at 15.2 ... I'm going to install 15.7.3, and see if I am still having this issue – Daron Jun 09 '18 at 14:47
  • @Daron, when you install VS 15.7.3 you will have an issue about [AXML-Designer](https://github.com/xamarin/xamarin-android/issues/1777), but don't worry about it, you could find some workaround there. And this issue should be resolved in VS 15.7.4. – York Shen Jun 10 '18 at 07:10
  • I did find this line interesting though: "/data/app/SimpleKeyboard.SimpleKeyboard-1/base.apk"]...the class is named SimpleKeyboard.SimpleKeyboard...where do the "-1" come from...(I got that from the logs posted above)...i can't even add dash 1 because dashes are special characters...maybe this has something to do with why it can't find the service name. – Daron Jun 15 '18 at 04:55
0

Still not 100% what the problem was but I download a sample project form Xamarin and seen I few key difference...added and addition file and two lines in that manifest that was missing...it works now...for anyone have this problem, check out xamarin service projects example and you should be able to fix your issue as well.

Daron
  • 113
  • 2
  • 13