Recent

Author Topic: Android Module Wizard  (Read 704801 times)

jmpessoa

  • Hero Member
  • *****
  • Posts: 2296
Re: Android Module Wizard
« Reply #1200 on: November 22, 2019, 07:32:41 am »
Ok, kordal!

I will try your solution!

Thank you!

[Edited]
    Commited!!!
« Last Edit: November 23, 2019, 03:57:44 am by jmpessoa »
Lamw: Lazarus Android Module Wizard
https://github.com/jmpessoa/lazandroidmodulewizard

m4u_hoahoctro

  • Full Member
  • ***
  • Posts: 160
Re: Android Module Wizard
« Reply #1201 on: January 06, 2020, 11:48:00 am »
@jmpessoa

Can you write a guide on how to make an own component into lamw ?

I have a while on using flutter and its experience on app seem be more native than lamw's, but making an app with lamw still be easier, hope we can have more components for use :) (May i will contribute for some examples of IoT/Arduino/ARM/AVR :) )

kordal

  • New Member
  • *
  • Posts: 20
Re: Android Module Wizard
« Reply #1202 on: January 09, 2020, 01:26:31 am »
Directories & Files:
...\lazandroidmodulewizard\android_bridges\  - directory to Pascal components realization
register_ ... .pas - component registration files (if uses LAMW wizard, edited automaticly)
*.lrs - icon files of components

..\lazandroidmodulewizard\android_wizard\smartdesigner\java\ - directory to Java components realization
*.create - component initialization code
*.java - component main code
*.native - component event procedures
*.relational - list of *.java files (dependencies), if used in the main module java component

How to start?
  • Lazarus IDE -> Tools -> [LAMW] Android Module Wizard -> New jComponent Create
  • Click right mouse button

Note: When you write bridge functions in Pascal, pay attention to the names of functions in Java code and how they are called in JNI. A prerequisite is the presence of signatures for functions that change depending on the input / output parameters (arguments).

Example (the example is not complete):
jMyComponent.java
Code: Java  [Select][+][-]
  1. // package org.lamw...; // changes automatically  
  2. //
  3. // skip two lines
  4.  
  5. import android.os.Bundle;
  6. // other imports
  7. // see https://developer.android.com/reference
  8.  
  9. public class jMyComponent {
  10.     // Java-Pascal Interface
  11.     private long     pascalObj   = 0;    // Pascal Object
  12.     private Controls controls    = null; // Java/Pascal [events] Interface ...
  13.     private Context  context     = null;
  14.  
  15.     // constructor
  16.    public jMyComponent(Controls _Ctrls, long _Self /*, other parameters*/ ) {
  17.                 context   = _Ctrls.activity;
  18.                 controls  = _Ctrls;
  19.                 pascalObj = _Self;
  20.                
  21.    }
  22.  
  23.   // destructor
  24.   public void jFree() {
  25.      // free local objects...
  26.   }
  27.  
  28.   public int Sum(int a, int b) {
  29.      return a + b;
  30.   }
  31.  
  32. }
  33.  

MyComponent.pas
Code: Pascal  [Select][+][-]
  1.   // ...
  2. type  
  3.   jMyComponent = class(...)
  4.     // initialization code
  5.     // ...
  6.     function Sum(a, b: Integer): Integer;
  7.   end;
  8.  
  9.   function jMyComponent.Sum(a, b: Integer): Integer;
  10.   begin
  11.     if FInitialized then
  12.       Result := jMyComponent_Sum(FjEnv, FjObject, a, b);
  13.   end;
  14.  
  15.   // JNI implementation
  16.   function jMyComponent_Sum(env: PJNIEnv; _jmycomponent: JObject; _a, _b: Integer): Integer;
  17.   var
  18.     jParams: array[0..1] of JValue;
  19.     jMethod: JMethodID = nil;
  20.     jCls   : JClass = nil;      
  21.   begin
  22.     jParams[0].i := _a;
  23.     jParams[1].i := _b;
  24.     jCls := env^.GetObjectClass(env, _jmycomponent);
  25.     jMethod := env^.GetMethodID(env, jCls, 'Sum', '(II)I'); // function name 'Sum', signature (I - integer, I - integer) result Integer  
  26.     Result := env^.CallIntMethodA(env, _jmycomponent, jMethod, @jParams);
  27.     // env^.CallVoidMethodA(env, _jmycomponent, jMethod, @jParams);  // no result
  28.     // env^.CallVoidMethod(env, _jmycomponent, jMethod);  // no result, no params
  29.     // env^.CallFloatMethodA(env, _jmycomponent, jMethod, @jParams);  // result float, with params
  30.    
  31.    // See more And_jni.pas & other components
  32.     env^.DeleteLocalRef(env, jCls);                                  
  33.   end;
  34.  
  35.   // signatures
  36. (*  
  37.  
  38.   Z - Boolean
  39.   B - Byte
  40.   I - Integer
  41.   F - Float (Single)
  42.   V - Void (no result)
  43.   L - java Object
  44.   [ - array, ex [I - integer array, [F - float array, etc.
  45.  
  46. *)
  47.  

To view signatures of compiled java files, you can use, for example, JCSign tool.

Official help:

Quote
"LAMW: Lazarus Android Module Wizard"

   Author: Jose Marques Pessoa

      https://github.com/jmpessoa/lazandroidmodulewizard

:: How to Create JNI Bridge Component code::
 
1. LAMW Component Model: 

   ::  jControl: No GUI Control     

       hint: you can use composition or inheritance model here....

   ::  jVisualControl: GUI Control

       warning:  you MUST use inheritance model here.....

2. Creating a new component:
     
   2.1. Right click Java tab:

   2.1. Insert a new [wrapper] java class  jControl/jVisualControl from template;

        hint1. Alternatively, you can paste you java code [template compatible] from clipboard!

        hint2. Alternatively, you can import a "JAR" file and selec a class [at the moment, only for no visual  control]!

        hint3: You can also use the demo AppTryCode3 to produce a complete [wrapper]  java class !

       hint4. you do not need to build the "perfect" component now .... later you can add more methods, events and properties! [sections 3 e 4 bellow]

        warning/important: All "imports" from "Controls.java" template  and new "imports" from you java class code
                   will  be researched to try write the correct JNI methods signatures.....

                     
   2.2. Rename [and extends] the new class [and constructor], write some custom field, methods, etc...
        [for "JAR" imported class this task is automated! ]
       
        guideline: please, preferentially init your news params names with "_", ex: int _flag, String _hello ...
         
        hint1: Only public methods will be translated to pascal [bridge] code.
        hint2:  use the  mask  /*.*/   to make a public method invisible for the parse [ex.  /*.*/public myfunctio() {....} ] 

   2.3. Select all  the new java class code and right click it [java tab] .
     
       hint1:  if have only one java class code you do not need select it! just right click it!
       hint2. save your java class source code in LAMW folder "......\android_wizard\smartdesigner\java" :

        warning:  the  LAMW java to pascal convert dont support complex/generic types like  "java.util.Map<,>" ,  "java.util.Set<>" etc..
       So, we need re-write  the method signature [by hand] for primitives data/array type....

      But simple java Object param [or return]  is ok   [including array!!!]!
     
      public void SetImage(Bitmap _image) {     //<<----  OK!
             this.setImage(_image);
      }
 
     public Bitmap GetImage(Bitmap _image) {     //<<---- OK!
             return this.getImage();
      }

       warning/important: All "imports" from "Controls.java" template  and new "imports" from you java class code
                   will  be researched to try write the correct JNI methods signatures.....
     
   2.4. Popup Menu: Select "Write [Draft] Pascal jControl/jVisualControl Interface".
 
   2.5. Right click Pascal Tab  and select "Register Component..." from  Popup Menu;

          warning: Mac users: please, you must copy the console app "lazres" [lazarus/tools] to the folder
          ".../LazAndroidWizard/ide_tools";

   2.6. [Dialog]:  select a 16x16 PNG icon file;

   2.7.  [Dialog]:  open a "register_*.pas" file (ex. "register_extra.pas"); **

      hint: you can select "register_template.pas" to write a custom register file,
              but, then,  you must insert it into  "tfpandroidbridge_pack.lpk".

   2.8. Ok. You got you DRAFT pascal component JNI stuff! Please, look in the folder   "..../LazAndroidWizard/android_bridges"
         directory:
         
        :: *.pas           <--- open and fix/complete the pascal code with your others events/properties/methods/variables/overload!

        :: *_icon.lrs    <--- new icon resource
        :: register_extras.pas   <--- updated!  by default, the new component will be include there!

   2.9. [Lazarus IDE Menu]: Package -> Open Package File (*.lpk) --> "tfpandroidbridge_pack.pas" in folder 
         "....../LazAndroidWizard/android_bridges".

   2.10. [Package Wizard]: Compile --->> Use ---> Install.

            Warning: to compile/install/reinstall a LAMW package in  Lazarus/Laz4Android [windows],
               please, open a "dummy" pure windows project.... you MUST always close the cross compile project!
   
   2.11. Wait .... Lazarus re-building ...

   2.12. The new component  is on "Android Bridges Extra" [or other...] palette!.
   
   3. Added more methods to your component   

   3.1.  write new method to  your ".java" code
           ex.
                 public void SetFoo(int _foo) {
                       mFoo = _foo;
                 }
                  public int GetFoo() {
                        return mFoo;
                  }

   3.1.  In java tab write a draft java class code to wrapper the [new] methods;

           class jMyComponent {

                 public void SetFoo(int _foo) {
                       mFoo = _foo;
                 }
                  public int GetFoo() {
                        return mFoo;
                  }
          }                 
           
    3.2   Right click the Java tab and select "Write [draft] complementary Pascal Interface"

    3.4   Copy the the pascal interface code to your component unit!!!
       
    4. Added "native" [events] methods to your component

    4.1.  write the native method "call" to to  your ".java" code    [study some LAMW code as example!]

               ex1:   [from jSpinner.java]
 
                controls.pOnSpinnerItemSelected(pascalObj,position,caption);   //return void

              ex2:   [fiction...]
                int  i = controls.pOnSpinnerItemSelected(pascalObj,position,caption);   //return int             
 
              ex3:   [fiction...]
                int[] v;
                 v = controls.pOnSpinnerItemSelected(pascalObj,position,caption);   //return int[]     
                 for (int i = 0; i < v.length; i++) {
                     //Log.i("v["+i+"]", ""+v);     //do some use...
                 }         
               
              ex4:   [fiction...]
                String[] s;
                 s = controls.pOnSpinnerItemSelected(pascalObj,position,caption);   //return String[]               
                for (int i = 0; i < s.length; i++) {
                     //Log.i("s["+i+"]", ""+s);     //do some use...
                 }         
 
    4.2.  write the native method signature to your [component] ".native" file    [study some LAMW code as example!]
           ex1.    [from jSpinner.native]       
              public native void pOnSpinnerItemSelected(long pasobj, int position, String caption);

           ex2.    [fiction...]       
              public native int pOnSpinnerItemSelected(long pasobj, int position, String caption);

           ex3.    [fiction...]       
              public native int[] pOnSpinnerItemSelected(long pasobj, int position, String caption);

           ex4.    [fiction...]       
              public native String[] pOnSpinnerItemSelected(long pasobj, int position, String caption);

    4.3.  In java tab write a draft java class code to wrapper the the native [one line!] method;
         
           class jMyComponent {

                public native void pOnMyComponentItemSelected(long pasobj, int position, String caption); //MyComponent

          }                 

         NOTE: the  "//MyComponent" signs the part of the method name that will be overshadowed in the nomination of the property.
                            ex.  FOnItemSelected   [ not FOnMyComponentItemSelected  ]   

    4.4   Right click the Java tab and select "Write [draft] complementary Native Method Pascal Interface"

    4.5   Copy the the pascal interface code [generated] to your component unit [mycomponent.pas] and to "Laz_And_Controls_Events.pas"!!!

    Congratulations!!!     

« Last Edit: January 10, 2020, 12:20:13 am by kordal »

Mongkey

  • Sr. Member
  • ****
  • Posts: 430
Re: Android Module Wizard
« Reply #1203 on: January 10, 2020, 11:36:35 am »
Thanks bro, your tools are awesome!

cant wait for new advanced cool bridge :D
« Last Edit: January 10, 2020, 12:04:01 pm by Mongkey »

kordal

  • New Member
  • *
  • Posts: 20
Re: Android Module Wizard
« Reply #1204 on: January 23, 2020, 11:49:40 am »
Hi @jmpessoa, @TR3E  :)
1. There is an error in the
Code: Pascal  [Select][+][-]
  1. function GetTimeInMilliseconds: Longint
function, it returns a negative value! The fact is that the Integer type does not have enough bit depth for the correct operation of the time counter.

The problem arises is data types on the Pascal side. GetTimeInMilliseconds is of type Longint = Integer = jInt = Int (java), and should be Int64 = jLong = Long (java). As a result, the function calls another jni_func_out_j, where there is also a problem with data types.

So, we have at least several problematic calling functions
Code: Pascal  [Select][+][-]
  1. function jni_func_out_j: Longint; // change Longint to Int64
  2. function jni_func_j_out_t(..: Longint) ...; // change Longint to Int64
, where the types Longint and Int64 are mixed up.

2. I`am updated the jDrawingView component. The OnClick and OnDoubleClick events have been added.
So, the first modification:
Controls.java, added to line 165, 166
Code: Java  [Select][+][-]
  1. class Const {
  2.   public static final int TouchDown            =  0;
  3.   public static final int TouchMove            =  1;
  4.   public static final int TouchUp              =  2;
  5.   public static final int Click                =  3; // new
  6.   public static final int DoubleClick          =  4;  // new
  7.   public static final int Click_Default        =  0;
  8. }
  9.  
AndroidWidget.pas, added to line 71, 72 and two new functions
Code: Pascal  [Select][+][-]
  1. // Event id for Pascal & Java
  2.   cTouchDown            = 0;
  3.   cTouchMove            = 1;
  4.   cTouchUp              = 2;
  5.   cClick                = 3;
  6.   cDoubleClick          = 4;
  7.  
  8. // ...
  9.   procedure jni_proc_s(env: PJNIEnv; _jobject: JObject; javaFuncion : string; _short: smallint);
  10.   procedure jni_proc_ss(env: PJNIEnv; _jobject: JObject; javaFuncion : string; _short1, _short2: smallint);
  11.  
  12. // ...
  13. implementation
  14. // ...
  15.   procedure jni_proc_s(env: PJNIEnv; _jobject: JObject; javaFuncion : string; _short: smallint);
  16.   var
  17.     jParams: array[0..0] of jValue;
  18.     jMethod: jMethodID = nil;
  19.     jCls   : jClass = nil;
  20.   begin
  21.     jParams[0].s:= _short;
  22.  
  23.     jCls := env^.GetObjectClass(env, _jobject);
  24.     jMethod := env^.GetMethodID(env, jCls, PChar(javaFuncion), '(S)V');
  25.     env^.CallVoidMethodA(env, _jobject, jMethod, @jParams);
  26.     env^.DeleteLocalRef(env, jCls);
  27.   end;
  28.  
  29.   procedure jni_proc_ss(env: PJNIEnv; _jobject: JObject; javaFuncion : string; _short1, _short2: smallint);
  30.   var
  31.     jParams: array[0..1] of jValue;
  32.     jMethod: jMethodID = nil;
  33.     jCls   : jClass = nil;
  34.   begin
  35.     jParams[0].s:= _short1;
  36.     jParams[1].s:= _short2;
  37.  
  38.     jCls := env^.GetObjectClass(env, _jobject);
  39.     jMethod := env^.GetMethodID(env, jCls, PChar(javaFuncion), '(SS)V');
  40.     env^.CallVoidMethodA(env, _jobject, jMethod, @jParams);
  41.     env^.DeleteLocalRef(env, jCls);
  42.   end;    
  43.  

The following modification affected JDrawingView.java and DrawingView.pas, modified files in the attached.
« Last Edit: January 24, 2020, 05:17:56 am by kordal »

ADiV

  • Jr. Member
  • **
  • Posts: 90
    • ADiV Software
Re: Android Module Wizard
« Reply #1205 on: January 24, 2020, 09:29:08 am »
Updated "jDrawingView" [thanks to Kordal]

Fixed "GetTimeInMilliseconds" long to int64 and the corresponding "jni_func".

I have changed the variables that were in capital letters, since in programming the constants are understood as capital, when it will not be so.

And I have changed the FTimeClick and FTimeDoubleClick variables from short to int.

Already uploaded to LAMW as "Pull request", it is necessary that jmpessoa accept it.


kordal

  • New Member
  • *
  • Posts: 20
Re: Android Module Wizard
« Reply #1206 on: January 24, 2020, 01:26:30 pm »
Thank you) I forgot to add line in the Init procedure. This is necessary to change property values ​​in component design time.
Code: Pascal  [Select][+][-]
  1. procedure jDrawingView.Init(refApp: jApp);
  2. // ...
  3. begin
  4.   // ...
  5.   if not FInitialized then
  6.   begin
  7.     // ...
  8.     jni_proc_ii(FjEnv, FjObject, 'SetTimeClicks', FTimeClick, FTimeDoubleClick);
  9.   end;
  10. end;
  11.  

ADiV

  • Jr. Member
  • **
  • Posts: 90
    • ADiV Software
Re: Android Module Wizard
« Reply #1207 on: January 24, 2020, 02:10:32 pm »
Ok, it's already uploaded.

nullpointer

  • New Member
  • *
  • Posts: 35
  • impossible is nothing
    • tauhidslab
Re: Android Module Wizard
« Reply #1208 on: March 07, 2020, 02:58:33 pm »
How to build Android App Bundles?

i'm trying to upload my app to Play Store and got following error

This release does not comply with the 64-bit Google Play requirements

The following APK or App Bundle is available for 64-bit devices, but only has 32-bit native code: 2.

Enter 64-bit and 32-bit native code in your application. Use the Android App Bundle publication format to ensure directly that each device architecture only accepts the required native code. This will prevent the addition of the overall application size.

https://developer.android.com/guide/app-bundle?hl=en

please help...

Manlio

  • Full Member
  • ***
  • Posts: 162
  • Pascal dev
Re: Android Module Wizard
« Reply #1209 on: March 13, 2020, 04:11:48 am »
How to build Android App Bundles?

Not using Android App Bundles is NOT the reason why your app is rejected by Google Play (see below for the real reason).

Android App Bundles (AAP files) are the *recommended* format by google, but APK files are accepted.

Android App Bundles's (AAB) advantage over APK is this: when people will download your app from google's play store, if you uploaded your app in AAB format, the user will only receive one version of the library, the one they need: downloading to a 64-bit phone will get only the 64 bit library, and downloading to a 32-bit device will get only the 32-bit files. If instead you uploaded your app as APK, all the users will receive all the files, 32 and 64  bit. I think they call that a "fat" bundle.

So AAP files are better for your users (no space wasted on their memory and in downloaded bandwidth). But APK are still accepted.

In order to create AAB bundles, I believe you need to use Android Studio to build the app, although I hope that at some point the Lazarus package will become able to do that as well.

But my suggestion is to stick with APK for the time being. You already have enough complicated things to work out, and you don't need one more...

And now the important thing:

This release does not comply with the 64-bit Google Play requirements

The reason why you app was not accepted is that it didn't contain a 64-bit version of the library.

By default, LAMW/Lazarus generates 32-bit version of the library (libcontrols.so is the default name) which contains the Pascal code you write with LAMW.

Since August 2019, google requires a 64 bit version of any native libraries (so files) and refuses to accept APK (or AAB) files that only contain 32-bit versions of embedded libraries.

32-bit libraries are stored in the folder "libs\armeabi-v7a" in your app's main folder.

(you will probably see the file libcontrols.so in that folder)

64-bit libraries are stored in the folder "libs\arm64-v8a" in your app's main folder.

(you will probably find this folder empty)

What you need to do to get your app accepted by google is to set up a separate 64-bit FPC compiler, which targets arm64 CPUs, and compile your project a second time with it, so that the 64-bit file will be created and added to the libs\arm64-v8a folder.

I had to struggle a lot to figure this out. More recently, fpdeluxe and other projects are making the task of building both 32 and 64 bit versions easier.

In my case, Lazarus IDE now produces a 32 bit library, and then I separately call a script that compiles the project again, with the 64 bit compiler this time.

At that point, both of the above folders will have the libcontrols.so file in them. If you then build the APK, both versions (32 bit and 64 bit) will be included in the APK. And when you will submit it to google, it will be accepted.

manlio mazzon gmail

DonAlfredo

  • Hero Member
  • *****
  • Posts: 1738
Re: Android Module Wizard
« Reply #1210 on: March 13, 2020, 05:14:35 am »
Hi,

A week ago, I have added a Gradle option into build.gradle:

Quote
    splits {
        abi {
            enable true
            reset()
            include 'arm64-v8a'
            universalApk false
        }
    }

To make a combined apk, build with Gradle and use this:

Quote
    splits {
        abi {
            enable true
            reset()
            include 'armeabi-v7a','arm64-v8a'
            universalApk true
        }
    }

If needed, I can put this (mutli-arch apk) into LAMW as a new feature.

ASBzone

  • Hero Member
  • *****
  • Posts: 678
  • Automation leads to relaxation...
    • Free Console Utilities for Windows (and a few for Linux) from BrainWaveCC
Re: Android Module Wizard
« Reply #1211 on: March 13, 2020, 05:52:51 pm »
In my case, Lazarus IDE now produces a 32 bit library, and then I separately call a script that compiles the project again, with the 64 bit compiler this time.

At that point, both of the above folders will have the libcontrols.so file in them. If you then build the APK, both versions (32 bit and 64 bit) will be included in the APK. And when you will submit it to google, it will be accepted.

You can use Build Modes so that you can perform both compilations from the GUI consecutively, if you'd like.

https://wiki.lazarus.freepascal.org/IDE_Window:_Compiler_Options#Build_modes
-ASB: https://www.BrainWaveCC.com/

Lazarus v2.2.7-ada7a90186 / FPC v3.2.3-706-gaadb53e72c
(Windows 64-bit install w/Win32 and Linux/Arm cross-compiles via FpcUpDeluxe on both instances)

My Systems: Windows 10/11 Pro x64 (Current)

nullpointer

  • New Member
  • *
  • Posts: 35
  • impossible is nothing
    • tauhidslab
Re: Android Module Wizard
« Reply #1212 on: April 03, 2020, 12:09:14 pm »
How to build Android App Bundles?

Not using Android App Bundles is NOT the reason why your app is rejected by Google Play (see below for the real reason).

Android App Bundles (AAP files) are the *recommended* format by google, but APK files are accepted.

Android App Bundles's (AAB) advantage over APK is this: when people will download your app from google's play store, if you uploaded your app in AAB format, the user will only receive one version of the library, the one they need: downloading to a 64-bit phone will get only the 64 bit library, and downloading to a 32-bit device will get only the 32-bit files. If instead you uploaded your app as APK, all the users will receive all the files, 32 and 64  bit. I think they call that a "fat" bundle.

So AAP files are better for your users (no space wasted on their memory and in downloaded bandwidth). But APK are still accepted.

In order to create AAB bundles, I believe you need to use Android Studio to build the app, although I hope that at some point the Lazarus package will become able to do that as well.

But my suggestion is to stick with APK for the time being. You already have enough complicated things to work out, and you don't need one more...

And now the important thing:

This release does not comply with the 64-bit Google Play requirements

The reason why you app was not accepted is that it didn't contain a 64-bit version of the library.

By default, LAMW/Lazarus generates 32-bit version of the library (libcontrols.so is the default name) which contains the Pascal code you write with LAMW.

Since August 2019, google requires a 64 bit version of any native libraries (so files) and refuses to accept APK (or AAB) files that only contain 32-bit versions of embedded libraries.

32-bit libraries are stored in the folder "libs\armeabi-v7a" in your app's main folder.

(you will probably see the file libcontrols.so in that folder)

64-bit libraries are stored in the folder "libs\arm64-v8a" in your app's main folder.

(you will probably find this folder empty)

What you need to do to get your app accepted by google is to set up a separate 64-bit FPC compiler, which targets arm64 CPUs, and compile your project a second time with it, so that the 64-bit file will be created and added to the libs\arm64-v8a folder.

I had to struggle a lot to figure this out. More recently, fpdeluxe and other projects are making the task of building both 32 and 64 bit versions easier.

In my case, Lazarus IDE now produces a 32 bit library, and then I separately call a script that compiles the project again, with the 64 bit compiler this time.

At that point, both of the above folders will have the libcontrols.so file in them. If you then build the APK, both versions (32 bit and 64 bit) will be included in the APK. And when you will submit it to google, it will be accepted.

thank you for your complete answer.

Robert Gilland

  • Full Member
  • ***
  • Posts: 160
Re: Android Module Wizard
« Reply #1213 on: April 08, 2020, 12:28:47 am »
Any Idea why I would get : Didn't find class "robert.gilland.moviemaster.jFileProvider?


E/AndroidRuntime( 6442): FATAL EXCEPTION: main

E/AndroidRuntime( 6442): java.lang.RuntimeException: Unable to get provider robert.gilland.moviemaster.jFileProvider: java.lang.ClassNotFoundException: Didn't find class "robert.gilland.moviemaster.jFileProvider" on path: DexPathList[[zip file "/data/app/robert.gilland.moviemaster-2.apk"],nativeLibraryDirectories=[/data/app-lib/robert.gilland.moviemaster-2, /vendor/lib, /system/lib]]

E/AndroidRuntime( 6442):    at android.app.ActivityThread.installProvider(ActivityThread.java:5100)

I am stumped

jmpessoa

  • Hero Member
  • *****
  • Posts: 2296
Re: Android Module Wizard
« Reply #1214 on: April 09, 2020, 03:09:02 am »

Quote
Any Idea why I would get : Didn't find class "robert.gilland.moviemaster.jFileProvider?

Are you using some jFileProvider component in your projet?

If so,  delete it and put it again...
Lamw: Lazarus Android Module Wizard
https://github.com/jmpessoa/lazandroidmodulewizard

 

TinyPortal © 2005-2018