Android Question Using Photos from the Phone

mohsen nasrabady

Active Member
Licensed User
solved with this code
B4X:
Sub cs_Result (Success As Boolean, Dir As String, FileName As String)
If Success Then  
Dim fp As String = GetPathFromContentResult(FileName)
name = fp.SubString2(fp.LastIndexOf("/")+1,fp.Length)
path = fp.SubString2(0,fp.LastIndexOf("/"))
End If
End Sub
 

lymey

Active Member
Licensed User
You can use this code to get the full path (if such is available):
B4X:
Sub GetPathFromContentResult(UriString As String) As String
  If UriString.StartsWith("/") Then Return UriString 'If the user used a file manager to choose the image
  Dim Cursor1 As Cursor
  Dim Uri1 As Uri
  Dim Proj() As String = Array As String("_data")
  Dim cr As ContentResolver
  cr.Initialize("")
  If UriString.StartsWith("content://com.android.providers.media.documents") Then
  Dim i As Int = UriString.IndexOf("%3A")
  Dim id As String = UriString.SubString(i + 3)
  Uri1.Parse("content://media/external/images/media")
  Cursor1 = cr.Query(Uri1, Proj, "_id = ?", Array As String(id), "")
  Else
  Uri1.Parse(UriString)
  Cursor1 = cr.Query(Uri1, Proj, "", Null, "")
  End If
  Cursor1.Position = 0
  Dim res As String
  res = Cursor1.GetString("_data")
  Cursor1.Close
  Return res
End Sub
It depends on the following libraries: ContentResolver, SQL and Phone.
Is it possible to get the path / or file from Google Dive also? I am using the content chooser to get a file, and the Uri string looks like:
B4X:
content://com.google.android.apps.docs.storage/document/acc%3D1%3Bdoc%3D3
I suppose the real question is - can you programmatically access a file on Google Drive using the content chooser?
 

lymey

Active Member
Licensed User
You should be able to open an InputStream to this url.
I have never tried this before, and can't find a good example. But this is what I did:
B4X:
Sub GetPathFromContentResult(UriString As String) As String
  If UriString.StartsWith("/") Then Return UriString 'If the user used a file manager to choose the image
   
If UriString.StartsWith("content://com.google.android.apps.docs.storage/document") Then
  Dim jo As JavaObject
  jo = jo.InitializeStatic("anywheresoftware.b4a.objects.streams.File").GetField("ContentDir")
   
  Dim In As InputStream = File.OpenInput(jo, UriString)
'the following to see if inputstream works:    
  Dim xbmp As Bitmap
  xbmp.Initialize2(In)
  pic.SetBackgroundImage(xbmp)
'need to save file (with the same file name displayed in Google Drive
End If
 
End Sub
and this is the error I got:
java.io.FileNotFoundException: /(String) ContentDir/content:/com.google.android.apps.docs.storage/document/acc%3D1%3Bdoc%3D3: open failed: ENOENT (No such file or directory)
Obviously I am doing something wrong! Something to do with the way the java object is initialized ...but I am in uncharted territory for me!

Also how do I resolve the filename from Google Drive using the content chooser?
 

Erel

Administrator
Staff member
Licensed User
Try this:
B4X:
Sub CC_Result (Success As Boolean, Dir As String, FileName As String)
 If Success Then
  Dim in As InputStream = File.OpenInput(Dir, FileName)
  ...
 End If
End Sub
 

lymey

Active Member
Licensed User
Try this:
B4X:
Sub CC_Result (Success As Boolean, Dir As String, FileName As String)
If Success Then
  Dim in As InputStream = File.OpenInput(Dir, FileName)
  ...
End If
End Sub
That's great I can get the file content - thank you.
But how do I resolve the file name from Google Drive if I am using the content chooser?
 

lymey

Active Member
Licensed User
This is what happens using Google Drive with the ContentChooser with the following code:
B4X:
Sub cc_Result (Success As Boolean, Dir As String, FileName As String)
    Log("Success = " & Success & ", Dir = " & Dir & ", FileName = " & FileName)
    Dim realPath As String = GetPathFromContentResult(FileName)
    Log("realPath = " & realPath)
    Activity.SetBackgroundImage(LoadBitmapSample("", realPath, 100%x, 100%y))
End Sub

Sub GetPathFromContentResult(UriString As String) As String
   If UriString.StartsWith("/") Then Return UriString 'If the user used a file manager to choose the image
   Dim Cursor1 As Cursor
   Dim Uri1 As Uri
   Dim Proj() As String = Array As String("_data")
   Dim cr As ContentResolver
   cr.Initialize("")
   If UriString.StartsWith("content://com.android.providers.media.documents") Then
     Dim i As Int = UriString.IndexOf("%3A")
     Dim id As String = UriString.SubString(i + 3)
     Uri1.Parse("content://media/external/images/media")
     Cursor1 = cr.Query(Uri1, Proj, "_id = ?", Array As String(id), "")
   Else
     Uri1.Parse(UriString)
     Cursor1 = cr.Query(Uri1, Proj, "", Null, "")
   End If
   Cursor1.Position = 0
   Dim res As String
   res = Cursor1.GetString("_data")
   Cursor1.Close
   Return res
End Sub
An error is generated at :
B4X:
 Cursor1 = cr.Query(Uri1, Proj, "", Null, "")
Error:
java.lang.IllegalArgumentException: Unknown column requested: _data
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:167)
This is the log generated by cc_result:
Success = true, Dir = ContentDir, FileName = content://com.google.android.apps.docs.storage/document/acc%3D1%3Bdoc%3D3
Any ideas on how to change GetPathFromContentResult?
 

lymey

Active Member
Licensed User
This is what happens using Google Drive with the ContentChooser with the following code:
I did some poking around and found this: http://stackoverflow.com/questions/20067508/get-real-path-from-uri-android-kitkat-new-storage-access-framework
One of the suggestions to obtain the file name from Google Drive was to read '_display_name' from the cursor. So I altered the code:

B4X:
Sub GetPathFromContentResult(UriString As String) As String
   If UriString.StartsWith("/") Then Return UriString 'If the user used a file manager to choose the image
   Dim Cursor1 As Cursor
   Dim Uri1 As Uri
   'Dim Proj() As String = Array As String("_data")
   Dim Proj() As String = Array As String("_display_name")
  
   Dim cr As ContentResolver
   cr.Initialize("")
   If UriString.StartsWith("content://com.android.providers.media.documents") Then
     Dim i As Int = UriString.IndexOf("%3A")
     Dim id As String = UriString.SubString(i + 3)
     Uri1.Parse("content://media/external/images/media")
     Cursor1 = cr.Query(Uri1, Proj, "_id = ?", Array As String(id), "")
   Else
     Uri1.Parse(UriString)
     Cursor1 = cr.Query(Uri1, Proj, "", Null, "")
   End If
   Cursor1.Position = 0
   Dim res As String
   'res = Cursor1.GetString("_data")
   res = Cursor1.GetString("_display_name")
   Cursor1.Close
   Return res
End Sub
This now returns the correct file name when using the chooser to select a Google Drive file.
 

mohsen nasrabady

Active Member
Licensed User
some times the sub
cs_Result (Success As Boolean, Dir As String, FileName As String)
return nothing and log is
onActivityResult: IOnActivityResult was released
what's the problem?
 

Erel

Administrator
Staff member
Licensed User
Make sure that ContentChooser is a process global variable.
 

little3399

Active Member
Licensed User
Hi, Erel
Does the 1.zip sample can be only show PhotoLibrary and not include the Files Manager ? TKs!
 

Erel

Administrator
Staff member
Licensed User
It is better to post a link next time.

ContentChooser creates an intent with the given mime and sends it to the OS. Any application that is registered for this mime type will be returned.
 
Top