Android Question Get path/filename from STREAM for FTP

barx

Well-Known Member
Licensed User
Longtime User
I haven't used intents or data streams before, so this is a little new to me. Basically I want to be able to share pictures from gallery via FTP. I have managed to get my app to show in the Share list on gallery and it loads the desired activity when I share. I have logged the starting intent and it's extras and here is an example
B4X:
  Dim sInt As Intent
  sInt = Activity.GetStartingIntent
  Log(sInt.ExtrasToString)
  Log(sInt.GetData)
gives
B4X:
** Activity (shareftp) Create, isFirst = true **
** Activity (shareftp) Resume **
(Intent) Intent { act=android.intent.action.SEND_MULTIPLE typ=image/* flg=0x1 cmp=barxdroid.fotop/.shareftp (has clip) (has extras) }
Bundle[{android.intent.extra.STREAM=[content://media/external/images/media/6616, content://media/external/images/media/6615], exit_on_sent=true}]
null

The above example had 2 files selected.
So, my problem is how can I get a filename and ideally path so I can use for ftp

;)
 

barx

Well-Known Member
Licensed User
Longtime User
Just a note to Erel I did a better explanation of the last section of this post but I kept getting a server error when trying to post it. Rather strange.
 
Upvote 0

barx

Well-Known Member
Licensed User
Longtime User
B4X:
content://media/external/images/media/xxxx
How would I go about this then?

Copy the GetPathFromContentResult function and pass it each of the

B4X:
content://media/external/images/media/xxxx

How would I extract each of them?

Thanks
 
Upvote 0

barx

Well-Known Member
Licensed User
Longtime User
Any ideas How I get the uris from the intent. I thought it would be intent.GetExtra(""). in the quotes I have tried "bundle", "content", "android.intent.extra.STREAM". none seem to work...
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
It is not clear from the logs whether it is an array or list.
Try this:
B4X:
Dim jIntent As JavaObject = StartingIntent
Dim bundle As JavaObject = jIntent.RunMethod("getExtras", Null)
Dim links() As String = bundle.RunMethod("getStringArrayExtra", Array As Object("android.intent.extra.STREAM"))
For Each link As String In Links
 Log(link)
Next
 
Upvote 0

barx

Well-Known Member
Licensed User
Longtime User
Thanks for making an attempt at this. It's a little strange isn't it.

Your code give following error in log

B4X:
** Activity (shareftp) Pause, UserClosed = false **


** Activity (shareftp) Create, isFirst = false **


** Activity (shareftp) Resume **


shareftp_activity_resume (java line: 260)
java.lang.RuntimeException: Method: getStringArrayExtra not found in: android.os.Bundle
    at anywheresoftware.b4j.object.JavaObject$MethodCache.getMethod(JavaObject.java:238)
    at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:68)
    at barxdroid.fotop.shareftp._activity_resume(shareftp.java:260)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:525)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
    at barxdroid.fotop.shareftp.afterFirstLayout(shareftp.java:95)
    at barxdroid.fotop.shareftp.access$100(shareftp.java:16)
    at barxdroid.fotop.shareftp$WaitForLayout.run(shareftp.java:74)
    at android.os.Handler.handleCallback(Handler.java:730)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:5419)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:525)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
    at dalvik.system.NativeStart.main(Native Method)
java.lang.RuntimeException: Method: getStringArrayExtra not found in: android.os.Bundle

I tried changing 'getStringArrayExtra' to 'getParcelableArrayListExtra' and bascially the same error but referencing getParcelableArrayListExtra.

any other ideas?
 
Upvote 0

barx

Well-Known Member
Licensed User
Longtime User
Changed to 'getStringArray'.
B4X:
    Dim links() As String = bundle.RunMethod("getStringArray", Array As Object("android.intent.extra.STREAM"))

Get a Null Pointer now at the beginning of the For Loop

links is Null.

Got this code from one of the 1000 pages I have read

B4X:
if (Intent.ACTION_SEND_MULTIPLE.equals(action)) && Intent.hasExtra(Intent.EXTRA_STREAM)) {
    ArrayList list = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
    for (Parcelable p : list) {
        Uri uri = (Uri) p;
        /// do something with it.
    }
}

Maybe I will try to create a small lib.

cheers
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Try this:
B4X:
If StartingIntent.Action = "android.intent.action.SEND_MULTIPLE" AND StartingIntent.HasExtra("android.intent.extra.STREAM") Then
 Dim jIntent As JavaObject = StartingIntent
 Dim List1 As List = jIntent.RunMethod("getParcelableArrayListExtra", Array As Object("android.intent.extra.STREAM")
 For Each u As Uri In List1
  Log(u)
 Next
End If
You should reference ContentResolver library.
 
Upvote 0

barx

Well-Known Member
Licensed User
Longtime User
Awesome, that part is working. Now when I pass a uri to the function copied from http://www.b4x.com/android/forum/threads/uri-content-media-to-real-file.13473/#post-76176
I get an error as the Cursor is not initializing.

I'm assuming it is to do with this line
B4X:
Proj = Array As String("_data")

in that I am looking at a 'stream'. Tried changing _data to _stream and _STREAM. No joy. Feeling such a n00b....

Full Error

B4X:
** Activity (main) Create, isFirst = true **


** Activity (main) Resume **


** Activity (main) Pause, UserClosed = false **


** Activity (main) Resume **
** Activity (main) Pause, UserClosed = true **


** Activity (shareftp) Create, isFirst = true **


** Activity (shareftp) Resume **


(HierarchicalUri) content://media/external/images/media/7365
shareftp_getpathfromcontentresult (B4A line: 80)
Cursor.Position = 0
java.lang.RuntimeException: Object should first be initialized (Cursor).
    at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:46)
    at anywheresoftware.b4a.sql.SQL$CursorWrapper.setPosition(SQL.java:300)
    at barxdroid.fotop.shareftp._getpathfromcontentresult(shareftp.java:364)
    at barxdroid.fotop.shareftp._activity_resume(shareftp.java:303)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:525)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
    at barxdroid.fotop.shareftp.afterFirstLayout(shareftp.java:95)
    at barxdroid.fotop.shareftp.access$100(shareftp.java:16)
    at barxdroid.fotop.shareftp$WaitForLayout.run(shareftp.java:74)
    at android.os.Handler.handleCallback(Handler.java:730)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:5419)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:525)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
    at dalvik.system.NativeStart.main(Native Method)
 
Upvote 0

barx

Well-Known Member
Licensed User
Longtime User
OK, things took a little twist. The first bit of code that I reported as working, worked fine when sharing multiple images, but the list was not initialized if just 1 image was shared.

In the end I managed to put together a little library that takes care of both.

Not sure if the lib will be of use to anyone else and I struggled with what to call it.

Currently lib called UriTools:
2 methods
getRealPathFromUri - returns a full path from uri. Left public for just in case.
getPathsFromIntent - pass an intent with uri(s) as extras. Extracts uri(s) and then uses above method to convert the uri(s) to paths. Returns a List of Full Paths.

If anyone thinks it would be a good idea to upload, just shout. Also, if you have a better name........
 
Upvote 0

Chelu

Member
Licensed User
Longtime User
Hi barx.
I use your UriTools library.
I have found a problem with Android 6.0 and Gallery.
getPathsFromIntent fails with Gallery, but works fine with others apps.
With Gallery it detect multiple items, when I share a single item, and crash with a "null object reference"
B4X:
    Log (in)
        Log (in.ExtrasToString)
        listaA= ut.getPathsFromIntent (in)
        If listaA.IsInitialized Then
            For Each pfile As String In listaA
                Utilidades.AlmacenaAdj (pfile)
            Next
            VisibleTab (1)
        End If

The crash:

B4X:
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
(Intent) Intent { act=android.intent.action.SEND typ=image/jpeg flg=0x10400001 cmp=cheluCreations.CrossPoster/.main clip={image/jpeg U:content://com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F18221/ACTUAL/2136723254} (has extras) }
Bundle[{task_launched_for_result=true, android.intent.extra.STREAM=content://com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F18221/ACTUAL/2136723254}]
Multiple Items Detected
Error occurred on line: 242 (Main)
java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.Iterator java.util.ArrayList.iterator()' on a null object reference
    at barxdroid.uritools.uriTools.getPathsFromIntent(uriTools.java:40)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:697)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:336)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:246)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:134)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:157)
    at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:262)
    at cheluCreations.CrossPoster.main._capturaintent(main.java:666)
    at cheluCreations.CrossPoster.main._activity_resume(main.java:622)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:697)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:339)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:246)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:134)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
    at cheluCreations.CrossPoster.main$ResumeMessage.run(main.java:298)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5417)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
 
Upvote 0

barx

Well-Known Member
Licensed User
Longtime User
Unfortunately I don't have a 6.x device to even try testing this on. I know there is a big shake up with permissions in marshmellow. Maybe access to gallery needs a special permission?? I have no idea to be honest :oops:
 
Upvote 0

Chelu

Member
Licensed User
Longtime User
Ok, thanks.
I don't think than gallery needs a special permission, but I will not surrender.
 
Upvote 0
Top