Android Question Using Photos from the Phone

Discussion in 'Android Questions' started by Shadow&Max, Feb 3, 2014.

  1. Shadow&Max

    Shadow&Max Active Member Licensed User

    OK, so I want to retrieve a photo from the phone... I use the ContentChooser to get the photo.

    Now, I want to save the location of that picture in a file, and reload it at a later time.

    I can GET the picture the first time... That's working. Then I save the Dir and FileName to variables that are saved in the file.

    When I reload the file, I want to set an image control to that photo.

    I'm getting a Security message when I try to access that file again:
    java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord{429c19b0 13253:com.twodogapps.gaa/u0a136} (pid=13253, uid=10136) requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS

    The file dir and file name that are being saved are:
    Dir: ContentDir
    FileName: content://com.android.providers.media.documents/document/image%3A131

    The ContentChooser is initialized, I'm pretty sure. I set the image like this:

    iv.SetBackgroundImage(LoadBitmap(gs.listhere(Index).PhotoDir, gs.listhere(Index).PhotoFile))

    In the above line, the index is correct and is getting the values above. As soon as it hits this line, I get the SecurityException shown above.

    What am I doing wrong here?

    Also, on my phone's permissions for the app it says:

    1. Modify or delete the contents of your USB storage
    2. full network access
    3. access Bluetooth settings - Pair with Bluetooth devices
    4. read the contents of your USB storage.
    As far as I can tell those are all I need in terms of permissions.

    I don't want to save the file in my apps database because they're just too big and no need to waste duplicate space.
     
    Last edited: Feb 4, 2014
  2. Erel

    Erel Administrator Staff Member Licensed User

  3. Shadow&Max

    Shadow&Max Active Member Licensed User

    Hi Erel... Doesn't work... I copied and pasted the GetPathFromContentResult sub to my project, ran it, and immediately error out with basically the same error as above... Permission Denied.

    This is on a Motorola Moto-X .

    I get the same (almost the same error) on the:

    Code:
    Cursor = r.RunMethod4("query", _
      
    Array As Object(Uri, Proj, NullNullNull), _
      
    Array As String("android.net.Uri", _
          
    "[Ljava.lang.String;""java.lang.String", _
          
    "[Ljava.lang.String;""java.lang.String"))
    This is the error:
    java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord{42076d20 4861:com.twodogapps.gaa/u0a136} (pid=4861, uid=10136) requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS

    Again, the variables I get back after selecting the photo are:

    The file dir and file name that are being saved are:
    Dir: ContentDir
    FileName: content://com.android.providers.media.documents/document/image%3A131

    My call to GetPathFromContentResult is:
    iv.SetBackgroundImage(LoadBitmap("", GetPathFromContentResult(gs.slist(Index).PhotoFile)))

    Where gs.slist(Index).PhotoFile is the FileName above (iv is an imageview)

    Now, I'm not getting the permissions error, but the program errors out trying to return res, which is null...
     
    Last edited: Feb 4, 2014
  4. Erel

    Erel Administrator Staff Member Licensed User

    Seems like this is related to Android 4.4. Are you testing it on Android 4.4?

    Have you tried to add the permission to the manifest editor:
    Code:
    AddPermission(android.permission.MANAGE_DOCUMENTS)
     
  5. Shadow&Max

    Shadow&Max Active Member Licensed User

    Yes Erel... My phone is a new Moto-X and it's running 4.4. I'll try adding the line to the manifest and see what happens... haven't messed with the manifest file before, but I'll give it a whack... Be back in a few to report back...
     
  6. Shadow&Max

    Shadow&Max Active Member Licensed User

    Nope... Same thing... Didn't work... What's next??? :(

    I really need to get this to work.

    Is there any other way to extract the exact location of that file? What I don't understand is that I can read it with the cc.Show, and can choose the file and even assign it to the imageview after the cc.show. So I'm obviously being allowed to get there to view them and even display it. But when I try to read from them directly, it violates the permissions. Doesn't make sense.
     
    Last edited: Feb 5, 2014
  7. Erel

    Erel Administrator Staff Member Licensed User

    Seems like your only option is to copy the picture when the result is available.
     
  8. Shadow&Max

    Shadow&Max Active Member Licensed User

    Will there be a fix for this at some point? If this is a KitKat thing, it's imperative that it get into B4A at some point fairly soon... KitKat's all over the place now.
     
  9. jsanchezc

    jsanchezc Member Licensed User

    I copy image from chooser to dirdefaultexternal

    I solved doing this:
    Code:
    Sub chooser_Result (Success As Boolean, Dir As String, FileName As String)
      
    If Success Then
     
          
    Try
          
    File.Copy(Dir ,FileName,file.DirDefaultExternal ,"myfilename.jpg"  )
            PanelImage.SetBackgroundImage( 
    LoadBitmap(file.DirDefaultExternal ,"myfilename.jpg"))
          
    Catch
             
    Log(LastException.Message)
        
    End Try     
     
      
    End If
    End Sub
     
  10. Shadow&Max

    Shadow&Max Active Member Licensed User

    Thanks! It's a great solution... the only problem I see is that I'm trying to avoid bloat... my phone takes 10MP shots... if a user save 20 of them in the app, that's a 200MB overhead that's doubled because the pictures are already in the media store on the phone. I suppose I could also resize and shrink them down so that they're not bigger than the biggest tablet out there in terms of size and resolution. The resolution may not be THAT important either... but if I save 200MB of photos, it'll make some users pretty grumpy I would think!

    I may use this though... I'll try it first and see if it gets around KitKat's issues...

    Thanks again!
     
  11. Erel

    Erel Administrator Staff Member Licensed User

    You can use this code to get the full path (if such is available):
    Code:
    Sub GetPathFromContentResult(UriString As StringAs 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.
     
    Last edited: Feb 9, 2014
    fredo and koaunglay like this.
  12. Gregg Homan

    Gregg Homan Member Licensed User

    Erel,

    The new version of GetPathFromContentResult() is now throwing errors for both content://media... and content://com.android... uri formats. Note that the older version of GetPathFromContentResult() worked for the content://media... uri format but threw an error for the content://com.android... uri format.

    I ran the test below on a Droid Maxx running Android V4.4. Also, I don't remember running into this problem with the content://com.android... uri format until after upgrading my phone to V4.4, but, I am not 100% certain of this.

    Thanks,
    Gregg

    GetPathFromContentResult("content://com.android.providers.media.documents/document/image%3a7567") and
    GetPathFromContentResult("content://media/external/images/media/7567") both error out on following line of code within GetPathFromContentResult():
    Code:
    res = Cursor1.GetString("_data")
    GetPathFromContentResult("content://com.android.providers.media.documents/document/image%3a7567") and
    GetPathFromContentResult("content://media/external/images/media/7567") both throw the following identical error:
    Code:
    android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
        at android.database.AbstractCursor.checkPosition(AbstractCursor.java:
    426)
        at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:
    136)
        at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:
    50)
        at android.database.CursorWrapper.getString(CursorWrapper.java:
    114)
        at anywheresoftware.b4a.sql.SQL$CursorWrapper.GetString(
    SQL.java:355)
        at Ovinion.Ovinion.main._getpathfromcontentresult(main.java:
    3145)
        at Ovinion.Ovinion.main._chooser_result(main.java:
    1832)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    515)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    173)
        at anywheresoftware.b4a.BA.raiseEvent(BA.java:
    157)
        at anywheresoftware.b4a.phone.Phone$
    ContentChooser$1.ResultArrived(Phone.java:843)
        at anywheresoftware.b4a.BA$
    4.run(BA.java:477)
        at anywheresoftware.b4a.BA.setActivityPaused(BA.java:
    388)
        at Ovinion.Ovinion.main$ResumeMessage.run(main.java:
    252)
        at android.os.Handler.handleCallback(Handler.java:
    733)
        at android.os.Handler.dispatchMessage(Handler.java:
    95)
        at android.os.Looper.loop(Looper.java:
    137)
        at android.app.ActivityThread.main(ActivityThread.java:
    5083)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    777)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    593)
        at dalvik.system.NativeStart.main(Native Method)
     
  13. Erel

    Erel Administrator Staff Member Licensed User

    Change this line:
    Code:
    If p.SdkVersion >= 19 Then
    To:
    Code:
    If p.SdkVersion >= 19 AND UriString.IndexOf("%3A") >-1  Then
    It should solve the issue with the previous format. What is the location of this image?
     
  14. Gregg Homan

    Gregg Homan Member Licensed User

    Erel,
    I replaced code line are suggested above; and, now GetPathFromContentResult() is throwing different errors for the two different uri formats.
    Gregg

    GetPathFromContentResult("content://media/external/images/media/7567") errors on following line and throws error below:
    Code:
    res = Cursor1.GetString("_data")
    Code:
    android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
        at android.database.AbstractCursor.checkPosition(AbstractCursor.java:
    426)
        at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:
    136)
        at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:
    50)
        at android.database.CursorWrapper.getString(CursorWrapper.java:
    114)
        at anywheresoftware.b4a.sql.SQL$CursorWrapper.GetString(
    SQL.java:355)
        at Ovinion.Ovinion.main._getpathfromcontentresult(main.java:
    3145)
        at Ovinion.Ovinion.main._chooser_result(main.java:
    1832)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    515)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    173)
        at anywheresoftware.b4a.BA.raiseEvent(BA.java:
    157)
        at anywheresoftware.b4a.phone.Phone$
    ContentChooser$1.ResultArrived(Phone.java:843)
        at anywheresoftware.b4a.BA$
    4.run(BA.java:477)
        at anywheresoftware.b4a.BA.setActivityPaused(BA.java:
    388)
        at Ovinion.Ovinion.main$ResumeMessage.run(main.java:
    252)
        at android.os.Handler.handleCallback(Handler.java:
    733)
        at android.os.Handler.dispatchMessage(Handler.java:
    95)
        at android.os.Looper.loop(Looper.java:
    137)
        at android.app.ActivityThread.main(ActivityThread.java:
    5083)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    777)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    593)
        at dalvik.system.NativeStart.main(Native Method)
    GetPathFromContentResult("content://com.android.providers.media.documents/document/image%3a7567") errors on following line and throws error below:
    Code:
    Cursor1 = cr.Query(Uri1, Proj, NullNullNull)
    Code:
    java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaDocumentsProvider uri content://com.android.providers.media.documents/document/image%3a7567 from pid=7601, uid=10229 requires android.permission.MANAGE_DOCUMENTS, or grantUriPermission()
        at android.os.Parcel.readException(Parcel.java:
    1461)
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:
    185)
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:
    137)
        at android.content.ContentProviderProxy.query(ContentProviderNative.java:
    413)
        at android.content.ContentResolver.query(
    ContentResolver.java:461)
        at android.content.ContentResolver.query(
    ContentResolver.java:404)
        at anywheresoftware.b4a.objects.ContentResolverWrapper.Query(ContentResolverWrapper.java:
    43)
        at Ovinion.Ovinion.main._getpathfromcontentresult(main.java:
    3135)
        at Ovinion.Ovinion.main._chooser_result(main.java:
    1832)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    515)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    173)
        at anywheresoftware.b4a.BA.raiseEvent(BA.java:
    157)
        at anywheresoftware.b4a.phone.Phone$
    ContentChooser$1.ResultArrived(Phone.java:843)
        at anywheresoftware.b4a.BA$
    4.run(BA.java:477)
        at anywheresoftware.b4a.BA.setActivityPaused(BA.java:
    388)
        at Ovinion.Ovinion.main$ResumeMessage.run(main.java:
    252)
        at android.os.Handler.handleCallback(Handler.java:
    733)
        at android.os.Handler.dispatchMessage(Handler.java:
    95)
        at android.os.Looper.loop(Looper.java:
    137)
        at android.app.ActivityThread.main(ActivityThread.java:
    5083)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    777)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    593)
        at dalvik.system.NativeStart.main(Native Method)
     
  15. barx

    barx Well-Known Member Licensed User

    I made a little library to do this not so long ago. You can try it if you like.
     

    Attached Files:

    Devan likes this.
  16. Gregg Homan

    Gregg Homan Member Licensed User

    Barx,

    Thanks for your help. I am not sure what I am doing wrong for I thought following code should have worked but I am getting compiler error shown below.

    Thanks,
    Gregg

    Code:
    Dim fn As String
    Dim uri1 As Uri
    Dim ut As uriTools   'Requires lib UriTools Verion 1.0 by Barx
    uri1.Parse("content://com.android.providers.media.documents/document/image%3a7567")
    fn = ut.getRealPathFromURI(uri1)
    Compiler error:
    Code:
    Parsing code.                          0.33
    Compiling code.                        
    0.40
    Compiling layouts code.                
    0.07
    Generating R 
    file.                      0.63
    Compiling generated Java code.          Error
    B4A line: 
    1225
    fn = ut.getRealPathFromURI(uri1)
    javac 
    1.7.0_25
    src\Ovinion\Ovinion\main.java:
    1843: error: getRealPathFromURI(BA,Uri) has private access in uriTools
    _fn = _ut.getRealPathFromURI(processBA,(android.net.Uri)(_uri1.getObject()));Debug.locals.put(
    "fn", _fn);
     
  17. barx

    barx Well-Known Member Licensed User

    2 mins I will check the lib code.
     
  18. barx

    barx Well-Known Member Licensed User

    My Bad, you are correct. I have only ever used the other method which then in turn calls this one as and when required. Surprised it even shown in b4a.

    Anyways, try this one. Made the method public.
     

    Attached Files:

  19. Gregg Homan

    Gregg Homan Member Licensed User

    Barx,

    getRealPathFromURI() throws same error below as Erel's GetPathFromContentResult() when processing content://com.android... uri formats but both subroutines appear to handle content://media... uri formats OK. There seems to be some form of permissions issue. BTW, adding AddPermission("android.permission.MANAGE_DOCUMENTS") to the manifest file does not help either; and, I don't know how to implement grantUriPermision() as stated in first line of error message below. Do you have any additional ideas?

    Gregg

    Code:
    Dim fn As String
    Dim uri1 As Uri
    Dim ut As uriTools

    uri1.Parse(
    "content://media/external/images/media/7567")
    fn = ut.getRealPathFromURI(uri1) 
    'WORKS

    uri1.Parse(
    "content://com.android.providers.media.documents/document/image%3a7567")
    fn = ut.getRealPathFromURI(uri1) 
    'FAILS
    Error thrown when processing content://com.android... uri formats:
    Code:
    java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaDocumentsProvider uri content://com.android.providers.media.documents/document/image%3a7567 from pid=7311, uid=10229 requires android.permission.MANAGE_DOCUMENTS, or grantUriPermission()
        at android.os.Parcel.readException(Parcel.java:
    1461)
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:
    185)
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:
    137)
        at android.content.ContentProviderProxy.query(ContentProviderNative.java:
    413)
        at android.content.ContentResolver.query(
    ContentResolver.java:461)
        at android.content.ContentResolver.query(
    ContentResolver.java:404)
        at barxdroid.uritools.uriTools.getRealPathFromURI(uriTools.java:
    54)
        at Ovinion.Ovinion.main._chooser_result(main.java:
    1859)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    515)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    173)
        at anywheresoftware.b4a.BA.raiseEvent(BA.java:
    157)
        at anywheresoftware.b4a.phone.Phone$
    ContentChooser$1.ResultArrived(Phone.java:843)
        at anywheresoftware.b4a.BA$
    4.run(BA.java:477)
        at anywheresoftware.b4a.BA.setActivityPaused(BA.java:
    388)
        at Ovinion.Ovinion.main$ResumeMessage.run(main.java:
    252)
        at android.os.Handler.handleCallback(Handler.java:
    733)
        at android.os.Handler.dispatchMessage(Handler.java:
    95)
        at android.os.Looper.loop(Looper.java:
    137)
        at android.app.ActivityThread.main(ActivityThread.java:
    5083)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    777)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    593)
        at dalvik.system.NativeStart.main(Native Method)
     
  20. barx

    barx Well-Known Member Licensed User

    this is interesting as an app that i have been working on that uses this works fine on a nexus 7 running kitkat.....

    edit: on the other hand, I get the uri's from an intent Extras
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice