Android Question Save an image from the smartphone gallery in the database and upload it to a listview.

WebQuest

Active Member
Licensed User
Hi, I'm new to the forum and I'm a beginner. I'm trying to load an image from the smartphone gallery and then save it in the database and then upload it to a listview. But I keep getting errors !. At the fristtime I open the gallery of the smartphone I select an image and I return the message (Image Added) that makes me deduce that the rescue in the db has been successful. But when I restart the app it returns me this error: java.lang.NullPointerException: Attempt to get length of null array.


B4X:
Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("ImageHome")
    LoadSystem
    LoadListImage
   
End Sub

B4X:
Sub ImageViewAggImage_Click
    Dim Chooser As ContentChooser
    Chooser.Initialize("chooser")
    Chooser.Show("image/*", "Select an image")
   
End Sub
B4X:
Sub chooser_Result (Success As Boolean, Dir As String, FileName As String)
If Success Then


Dim b() As Byte = ImageToBytes(xui.LoadBitmap(Dir,FileName))

s.ExecNonQuery("INSERT INTO Image (Picture) VALUES('" & b.Length & "')")
ToastMessageShow("Image Added",True)

Else
ToastMessageShow("No image selected", True)
End If
End Sub[[/CODE]


B4X:
Sub chooser_Result (Success As Boolean, Dir As String, FileName As String)

Sub LoadSystem
  
    Dim ruta As String
    If File.ExternalWritable Then
        ruta = File.DirInternal
    Else
        ruta = File.DirInternal
    End If
    If  File.Exists(File.DirInternal,"dbi.db")= False Then
        File.Copy(File.DirAssets,"dbi.db",File.DirInternal,"dbi.db")
    End If
    s.Initialize(ruta,"dbi.db",True)
    Log("dbi Inizializzato")
    init
End Sub


[CODE]Sub ImageToBytes( image As Bitmap) As Byte()
Dim out As OutputStream

out.InitializeToBytesArray(100)
image.WriteToStream(out,100,"JPG")
    Return out.ToBytesArray
End Sub
B4X:
Sub LoadListImage
 
    Dim Cursor1 As Cursor
    Dim Name As String
    Dim Buffer() As Byte
    Dim IpSt As InputStream
    Dim Bitmap1 As Bitmap
    Cursor1 = s.ExecQuery("SELECT  name,Picture FROM Image")
 
    For i = 0 To Cursor1.RowCount - 1
        Cursor1.Position = i
        Name =Cursor1.GetString("name")
        Buffer = Cursor1.GetBlob("Picture")
        IpSt.InitializeFromBytesArray(Buffer, 0, Buffer.Length)
        Bitmap1.Initialize2(IpSt)
        IpSt.Close
        ListViewImage.AddTwoLinesAndBitmap(Name,"",Bitmap1)
        Cursor1.Close
       
    Next
   
    SetDivider(ListViewImage, Colors.LightGray, 1dip)
 
End Sub
 

npsonic

Active Member
Licensed User
There is very simple error in your code. You insert length of the byte array not the bytes them self.

B4X:
s.ExecNonQuery2("INSERT INTO Image (Picture) VALUES ?", Array As Object(b))
 
Upvote 0

WebQuest

Active Member
Licensed User
Hello thanks to the starboard tested to work only once, loading the image in the listview, but after other tests I continue to give the same error.
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Upvote 0

WebQuest

Active Member
Licensed User
I think the problem is now loading, because adding an if overflows the error but does not load anything in the listview.

this error = java.lang.NullPointerException: Attempt to get length of null array



B4X:
Sub LoadListImage
 
    Dim Cursor1 As Cursor
    Dim Name As String
    Dim Buffer() As Byte
    Dim IpSt As InputStream
    Dim Bitmap1 As Bitmap
    Cursor1 = s.ExecQuery("SELECT  name,Picture FROM Image")
 If Buffer.Length>0 Then
    For i = 0 To Cursor1.RowCount - 1
        Cursor1.Position = i
        Name =Cursor1.GetString("name")
       
        IpSt.InitializeFromBytesArray(Buffer, 0, Buffer.Length)
            Buffer = Cursor1.GetBlob("Picture")
        Bitmap1.Initialize2(IpSt)
        IpSt.Close
        ListViewImage.AddTwoLinesAndBitmap(Name,"",Bitmap1)
        Cursor1.Close
     
    Next
   Else
       ToastMessageShow("Empty List",True)
    End If
 
Upvote 0

WebQuest

Active Member
Licensed User
the image is loaded from the gallery of the device and then saved in the db, but at this point something I'm wrong.

B4X:
Sub chooser_Result (Success As Boolean, Dir As String, FileName As String)
    
    If Success Then
    
        Dim b() As Byte = ImageToBytes(xui.LoadBitmap(Dir,FileName))
        s.ExecNonQuery2("INSERT INTO Image (Picture) VALUES (?)", Array As Object(b))
        ToastMessageShow("Image Added",True)
    
        
    Else
        ToastMessageShow("No image selected", True)
    End If
End Sub
 
Upvote 0

WebQuest

Active Member
Licensed User
The (buffer) is always less than 0, even after the image has been selected. I do not know how to solve.
 
Upvote 0

npsonic

Active Member
Licensed User
You are correctly storing bytes, but you initialize inputstream before populating buffer, so it will always be empty.

Add this before InitializeFromBytesArray

B4X:
Buffer = Cursor1.GetBlob("Picture")
 
Upvote 0

WebQuest

Active Member
Licensed User
Always the same error, I tested the chooser result with an imageview and the image is loaded correctly. I think the problem is in the INSERT command.


B4X:
Sub chooser_Result (Success As Boolean, Dir As String, FileName As String)
    
    If Success Then
        PanelAddImage.Visible=True
        ImageViewPicture.Gravity=Gravity.FILL
        ImageViewPicture.Bitmap =LoadBitmap(Dir,FileName)
        'EditTextTitle.Color = Colors.LightGray
        EditTextTitle.RequestFocus
        'EditTextTitle.Text = FileName
        
        Dim b() As Byte = ImageToBytes(xui.LoadBitmap(Dir,FileName))
        s.ExecNonQuery2("INSERT INTO Image (Picture) VALUES (?)", Array As Object(b))
        ToastMessageShow("Image Added",True)
        LoadListImage
        
    Else
        ToastMessageShow("No image selected", True)
    End If
 
Upvote 0

npsonic

Active Member
Licensed User
Use KeyValueStore if you are not sure what to do with sqlite.
 
Upvote 0

WebQuest

Active Member
Licensed User
thanks for the tip, so if I understand correctly I can store bitmaps and display them in the listview without the sql commands?
 
Upvote 0

npsonic

Active Member
Licensed User
When you previously were saving bitmap into your database, did you also insert name with it? Of course you will always get null if there is nothing saved with the name you are querying.

B4X:
s.ExecNonQuery2("INSERT INTO Image (Picture, name) VALUES (?)", Array As Object(b, Filename))

Here's example with KeyValueStore. In this example "picKvs" is KeyValueStore. I used code that you previously provided.

B4X:
Sub Chooser_Result (Success As Boolean, Dir As String, FileName As String)
    If Success Then
        PanelAddImage.Visible = True
        ImageViewPicture.Bitmap = LoadBitmapResize(Dir,FileName,ImageViewPicture.Width,ImageViewPicture.Height,True)
        EditTextTitle.RequestFocus
        picKvs.PutBitmap(FileName,LoadBitmap(Dir,FileName))
        ToastMessageShow("Image Added",True)
    Else
        ToastMessageShow("No image selected", True)
    End If
End Sub

Sub LoadListImage
    Dim keys As List = picKvs.ListKeys
    For Each key As String In keys
        ListViewImage.AddTwoLinesAndBitmap(key,"",picKvs.GetBitmap(key))
    Next
    SetDivider(ListViewImage, Colors.LightGray, 1dip)
    keys.Clear
End Sub
 
Upvote 0

WebQuest

Active Member
Licensed User
Thanks you were very clear, the name I had left out, I had focused on the image, I try to follow your advice.
 
Upvote 0

WebQuest

Active Member
Licensed User
Resolved, I have found the problem of (Buffer), in the loop (For) the parameters must be written after (Next) otherwise the cycle reads all the fields even the empty ones resetting the error (Empty buffer).
B4X:
Sub LoadListImage
    Dim list2 As DataItemsCategoryImage
    Dim Cursor1 As Cursor
    Dim Name As String
    Dim Buffer() As Byte
    Dim IpSt As InputStream
    Dim Bitmap1 As Bitmap
    Cursor1 = s.ExecQuery("SELECT  name,Picture FROM Image")
     If Buffer.Length>0 Then
    For i = 0 To Cursor1.RowCount - 1
        Cursor1.Position = i
    Next
    Name =Cursor1.GetString("name")
    Buffer = Cursor1.GetBlob("Picture")
    IpSt.InitializeFromBytesArray(Buffer, 0, Buffer.Length)
    Bitmap1.Initialize2(IpSt)
    IpSt.Close
    list2.FristRow=Name
    list2.ScondRow=""
    list2.Picture=Bitmap1
    ListViewImage.AddTwoLinesAndBitmap2(list2.FristRow,list2.ScondRow,list2.Picture,list2)
    ListViewImage.TwoLinesAndBitmap.ItemHeight = 106dip
    ListViewImage.TwoLinesAndBitmap.ImageView.SetLayout(5dip, 3dip, 100dip, 100dip)
    Cursor1.Close
    End If
    SetDivider(ListViewImage, Colors.LightGray, 1dip)
 
End Sub
 
Upvote 0

WebQuest

Active Member
Licensed User
the problem now is that the load of the Activity is loaded in the listview one (Row) at position 0, how can I load all the rows?
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
How does that code even work? You test if Buffer.Length > 0, but it will never be > 0 as is, since you declare buffer
B4X:
Dim Buffer() As Byte
, but you never assign anything to buffer and therefore Buffer.Length is always 0. Also, you SELECT statement pulls all records from your Image table, but the For/Next loop just cycles through the results until it just gets to the last record. What are you really trying to accomplish here?
 
Upvote 0
Top