Android Question [SOLVED] Read file from jar inside a Class

Star-Dust

Expert
Licensed User
Longtime User
I'm trying to read a file inside my library compiled in jar.
I need to read this file from within the class that is contained in the library and not from the App

I tried this tutorial but it works only if I load the file inside the jar file from the application does not work if the load inside my own class
https://www.b4x.com/android/forum/threads/embedding-files-in-compiled-libraries.37689/#content

I explain better I'm creating a CustomView and that it needs to load an image that is inside the library itself and I would like to understand how to upload the image.

Thank's
 
Can't test it now, but most SO answers seem to go in this direction
Code: Copy
InputStream is = this.getClass().getResourceAsStream("/data/file.txt"); // or wherever the file is and how it is named
So an option would be to add an inline Java call based on this, and complete it to get the Bitmap from the InputStream.

If there isn't a simpler approach before, I'll be able to test it in a couple of hours.
 
Upvote 0
this error raises me
Cannot find file: sf1.png
sdswitch_v0 (java line: 124)
java.lang.RuntimeException: Object should first be initialized (InputStream).
at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:50)
at b4a.example.sdswitch._v0(sdswitch.java:124)
at b4a.example.sdswitch._v5(sdswitch.java:85)
at b4a.example.sdswitch._designercreateview(sdswitch.java:73)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:191)
at anywheresoftware.b4a.objects.CustomViewWrapper.AfterDesignerScript(CustomViewWrapper.java:67)
at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayout(LayoutBuilder.java:162)
at anywheresoftware.b4a.objects.ActivityWrapper.LoadLayout(ActivityWrapper.java:209)
at b4a.example.main._activity_create(main.java:341)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:191)
at b4a.example.main.afterFirstLayout(main.java:104)
at b4a.example.main.access$000(main.java:17)
at b4a.example.main$WaitForLayout.run(main.java:82)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)

the code is this
Code: Copy
Public Sub LoadFileFileFromJar(FileName As String) As InputStream
    If fromAssets Then Return File.OpenInput(File.DirAssets, FileName)
    Dim r As Reflector
    r.Target = Me
    r.Target = r.RunMethod("getClass")
    Dim In As InputStream = r.RunMethod2("getResourceAsStream", "/data/" & FileName, "java.lang.String")
    If In.IsInitialized = False Then
        LogColor("Cannot find file: " & FileName, Colors.Red)
    End If
    Return In
End Sub

Public Sub LoadBitmapFromJar(FileName As String) As Bitmap
    Dim bmp As Bitmap
    Dim In As InputStream = LoadFileFileFromJar(FileName)
    bmp.Initialize2(In)
    In.Close
    Return bmp
End Sub
 
Upvote 0
I identified the melgium the error.
java.io.FileNotFoundException: sf1.png
But the file is present within the JAR
upload_2018-8-22_14-55-54.png


the error is generated in this row:
Code: Copy
Dim In As InputStream = LoadFileFileFromJar(FileName)
 
Upvote 0
You can open the APK with 7zip and see where the file was copied to.

If you added a resource to an existing library then the IDE might still think that the library doesn't have resources as it caches this information. Try to restart the IDE.

Consider creating an AAR instead of a Jar. It will allow you to add assets files.
 
Upvote 0
You can open the APK with 7zip and see where the file was copied to.

If you added a resource to an existing library then the IDE might still think that the library doesn't have resources as it caches this information. Try to restart the IDE.

Consider creating an AAR instead of a Jar. It will allow you to add assets files.
Resources are added. I put the immegine in the previous post.
I restarted the IDe but it does not change anything.

Create an AAR with B4A?
 
Upvote 0
I have some other simpler way to include and use an image in my jar library created in b4A?
 
Upvote 0
Upvote 0
I tried the exact minimum code 20 times and it gave me an error.
So I inserted some Try to handle errors.

Now put the orignal one back and it works :mad::mad::mad::mad:

Thank's Erel
 
Upvote 0
Probably because of the IDE cache. The IDE checks for resources only once when the library is first loaded.
Hidden trick ;)!! I also made several compilations but the file was never found!!
At the end I arrived to something similar but only could make it work if the file was placed in the same folder as the class, not the package root. I suppose that's because the paths are relative to it...
Code: Copy
Public Sub loadInternalBitmap As Bitmap
    Dim Jo As JavaObject = Me
    Dim b As Bitmap = Jo.RunMethod("loadMyBitmap",Null)
    Return b
End Sub

#if JAVA
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import java.io.InputStream;
public Bitmap loadMyBitmap() {
    InputStream is = this.getClass().getResourceAsStream("internalbitmap.jpg");
    Bitmap bmp = BitmapFactory.decodeStream(is);
    return(bmp);
}
#End If
 
Upvote 0
but only could make it work if the file was placed in the same folder as the class, not the package root. I suppose that's because the paths are relative to it...
It is not complicated to put it in the same folder.

At this point only the string parameter for the file name is missing ;)
 
Upvote 0
I tried this variant where I entered the filename.
It works properly. Obviously the files must be placed in the same folder as the library.

Also to ensure that when I'm in the design mode of the library does not go to search in resources but in DirAssest... I made a small change that handles this thing.
Code: Copy
Public Sub loadInternalBitmap(Nomefile As String) As Bitmap
    If File.Exists(File.DirAssets,Nomefile) Then
        Return LoadBitmap(File.DirAssets,Nomefile)
    Else   
        Dim Jo As JavaObject = Me
        Dim b As Bitmap = Jo.RunMethod("loadMyBitmap",Array As Object(Nomefile))
        Return b
    End If
End Sub

#if JAVA
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import java.io.InputStream;
public Bitmap loadMyBitmap(String filename) {
    InputStream is = this.getClass().getResourceAsStream(filename);
    Bitmap bmp = BitmapFactory.decodeStream(is);
    return(bmp);
}
#End If
 
Upvote 0
Back
Top