Android File Sharing Between Apps - Content Stream

Hi all,

I’m trying to have my App pull a file that is sent from another App in Android using sharing:

https://developer.android.com/training/sharing/send

I found the following older thread which explains the problem exactly, but it’s archived so I can’t reply:

https://forums.coronalabs.com/topic/67582-android-launch-app-from-share-with-dialog-how-to-get-shared-image/

So what I guess what I’m asking is since the original thread is somewhat old these days, have we moved on in any way shape or form?

I can receive the content URI from the share (e.g. “android.intent.extra.STREAM” : "content://0@media/external/images/media/13773) but I’m unable to do anything with it that I know of?

Ideally I’d like to either:

Find the original file (filepath?) from the content stream

OR

If that can’t be done, at least be able to do something with the stream to be able to save the file easily (although it would still be nice to know the original file name).

Hopefully someone has encountered something similar before and can offer some help?

Many thanks,

Paul,

I think you can get the file and path using this awesome free plugin in Marketplace. 

Android File, URI Manager and External Storage

I played with it awhile ago, so I don’t remember exactly how it works, but if you can get the Uri, then the plugin would be worth looking into.

I’ve got the code integrated into one of my apps, but it’s embarrassing.  If you need to see it after looking at the github examples, let me know.

Hope this helps,

Nail

Thanks Nail,

I’ve seen this plugin mentioned in a few places myself, however I’m having difficulty finding out how to use it to pull a URI from a content stream. If you’ve got some code you don’t mind sharing with me, I’d certainly be appreciative!

Also, don’t be embarrassed, I’m far from being a proficient with Lua, and I’m pretty sure most things I have written are probably far worse than anything you’ve put together! :slight_smile:

Paul

Paul,

I haven’t played with the stream intent, I’ve got the code working to get an attachment file contained in an email, similar to the iOS openURL scheme.  I’m thinking getting the file from the Android stream must be similar though by using the plugin to access the uri of the file which appears you are already getting.

I’ll try to dig into the code later tonight if I get a chance (stuff going on tonight), otherwise I should be able to post some code tomorrow evening.

Nail

Paul,

Here’s the code I used.

Glean from it what you can.

I added my onSystemEvent code, which you already must have, not sure what it looks like though.

I am looking for “file//” in my event URL like this as it’s what I’m looking for.

if (string.sub(eventURL, 1, 7) == “file://”) then

You may have to look of  “content//” as that’s what you get for a URL of the streamed file.

I get this for an eventURL:

eventURL == file:///storage/emulated/0/Android/data/com.android.email/cache/TeamPortal_MultipleContact_Info-2.mcnt

I have no idea if FileManager will get the file from the stream “content”, but it’s worth a try since it is a valid URL.

--FileManager Code Blocks used in main.lua --near top of main.lua --will hold plugin if Android local FileManager -- = require "plugin.cnkFileManager" local path = "" local FileName = "" --variable that will hold the fileName for the file imported at Temporary.Directory local launchArgs = ... local launchFile = ""; local fileName; local TempFile local contents = "" local \_platform = system.getInfo( "platform" ) print("\_platform == "..\_platform.."") if ( system.getInfo( "platform" ) == "android" ) then print("Require/ Device platform == android") FileManager = require "plugin.cnkFileManager" end --list Documents Directory local function listDocDirectory() local \_path = system.pathForFile( "", system.DocumentsDirectory ) --print ("\*\*\* Files in Documents Directory \*\*\*") print ("\n--- Files in Documents Directory ---") for file in lfs.dir( \_path ) do -- "file" is the current file or directory name --print( "Found file: " .. file ) print ( file ) end print ("----------------------------------------------\n") end --list temporary directory local function listTempDirectory() local \_path = system.pathForFile( "", system.TemporaryDirectory ) --print ("\*\*\* Files in Temporary Directory \*\*\*") print ("\n--- Files in Temporary Directory ---") for file in lfs.dir( \_path ) do -- "file" is the current file or directory name --print( "Found file: " .. file ) print ( file ) end print ("---------------------------------------------\n") end local getDocPath = function(fName) --returns file Name from eventURL print("getDocPath = function(fName) is called") local f = fName; print("getDocPath / f == "..f.."") if \_platform == "android" then local t = {} -- table to store the indices local i = 0 while true do i = string.find(f, "/", i+1) -- find 'next' newline if i == nil then break end table.insert(t, i) end print("#t == "..#t.."") print("t[#t] == "..t[#t].."") f = string.sub(f, t[#t] + 1, -1) print("FileName == "..f.."") else local docStart, docEnd = f:find("Documents"); print("getDocPath / docStart == "..docStart.." , docEnd == "..docEnd.."") f = f:sub(docEnd+1); print("getDocPath / f == "..f.."") end return f; end --pickFile listener local function listener1 (event) if event.done == "ok" then displayInfo ("File " .. event.destFileName .. " Saved !") print ("FILE READY TO BE SHARED --\> ", event.destPath, event.destFileName) --list the directories listTempDirectory() listDocDirectory() --save the name of the file getted fileName = event.destFileName; else displayInfo ("ERROR. Read the Log.") print ("ERROR: ", event.error) end end local function openDownloadedFileAndroidOnly(path) print("\*\*\*openDownloadedFileAndroidOnly(\_path) is called") --do something with the imported file print("\*\*\*path = ",path) local \_path = system.pathForFile( FileName, system.DocumentsDirectory) print("\*\*\*\_path = ",\_path) local fileHandle = io.open( \_path, "r" ) for line in fileHandle:lines() do print("Space in line") print( line ) TempFile = json.decode(line); print("?????????????????------------ TempFile ==", TempFile) end io.close( fileHandle ) fileHandle = nil local destDir = system.DocumentsDirectory -- where the file is stored local results, reason = os.remove( system.pathForFile( launchFile, destDir ) ) if results then print( "file removed" ) else print( "file does not exist", reason ) end --Here is --[[] print("????????????????-------------- TempFile == ", TempFile) print("?????????????????------------- TempFile.Index.Index ==", TempFile.Index.Index) if TempFile.Index.Type == "Contact" then print("") print("?????????????---------- Contact IMPORTED") print("???????????????----------- TempFile.Index.Type == ", TempFile.Index.Type) Analytics.logEvent("Download Contact DataFile") AB.importEmailContactToAddressBook(TempFile) elseif TempFile.Index.Type == "Group" then print("") print("?????????????---------- Group IMPORTED") print("???????????????----------- TempFile.Index.Type == ", TempFile.Index.Type) Analytics.logEvent("Donload Group DataFile") AB.importEmailGroupContactsToAddressBook(TempFile) end --]] end --receive the event and show the details about the file,this listener is passed to the FileManager plugin which saves the file to your app local function listener3( event ) print("") print("\*\*\*\*\* listener3(event) is called") if event.done then if event.done == "ok" then print ("\nFILE COPIED TO " .. event.destPath .. " with name: " .. event.destFileName) print ("\nThe file is : " .. event.size .. " Bytes Size.") local myText = display.newText( "File " .. event.destFileName .. " Copied !", display.contentCenterX, display.contentCenterY, native.systemFont, 16 ) myText:setFillColor( 1, 0, 0, 1 ) timer.performWithDelay( 3000, function() --destroy image if myText then myText:removeSelf() myText = nil end end) elseif event.done == "dummy" then print ("\nFILE FROM URI: " .. event.uri .. " Can be copied to Path :" .. event.destPath .. "with name: " .. event.destFileName .. " in a safe way") print ("\nThe file is : " .. event.size .. " Bytes Size. and has the original Name: " .. event.origFileName) end --list the directories listTempDirectory() listDocDirectory() local \_path \_path = system.pathForFile( FileName, system.DocumentsDirectory) --I call this function to do something with the imported file on Android openDownloadedFileAndroidOnly(\_path) elseif event.error then print ("\nERROR " .. event.error .. " With errorCode: " .. event.errorCode) print ("\nTrying to copy the file from the uri: " .. event.uri .. " To the path : " .. event.destPath) if event.errorCode == "2" then print ("\nThe User Refused to give permission to the app to get the file. Try again and give permission. It is safe!") elseif event.errorCode == "1" then print ("\nYou NEED to include the following at the build.settings file:") print ("\nandroid.permission.READ\_EXTERNAL\_STORAGE") end end end if (launchArgs and launchArgs.url) then print("??????????????????------------------ launchArgs == ", launchArgs) --PrintReadableTables.print\_r(launchArgs) local LaunchArgsURL = launchArgs.url launchFile = launchArgs.url; print("launchArgs.url == "..launchArgs.url.."") local \_fileName if (string.sub(launchFile, 1, 7) == "file://") then -- handle custom extension \_fileName = getDocPath(launchFile); print("???????????????????----------- launchFile == ", launchFile) print("???????????????????----------- \_fileName == ", \_fileName) FileName = \_fileName local TestFunction = "3" --used to change functions for testing to see what works print("TestFunction == ",TestFunction) if \_platform == "android" then if TestFunction == "1" then print ("\nPick a File \*/\*, and copy it to TemporaryDirectory using pickFile(...)") -- local path = system.pathForFile( nil, system.TemporaryDirectory) path = system.pathForFile( \_fileName, system.TemporaryDirectory) -- local fileName = nil -- fileName we want the copy will be named (String) local fileName = \_fileName local headerText = nil -- personalized dialog (String) local mimeType = "\*/\*" -- mimetype to filter local onlyOpenable = true --avoid non openable files --local onlyDocuments = nil --open only documents filter local onlyDocuments = true local dumyMode = false --simulate the copy FileManager.pickFile(path, listener1, fileName, headerText, mimeType, onlyOpenable, onlyDocuments, dumyMode ) elseif TestFunction == "3" then local myUri = launchFile if myUri and myUri ~= "" then print ("\nUsing the saved myUri : \n" .. myUri .. "\n Get the file using the getFileFromUri(...)" ) path = system.pathForFile( nil, system.DocumentsDirectory ) --the path to copy the file to. local uri = myUri --the uri to get the file from. local fileName = nil -- fileName we want the copy will be named (String) local dumyMode = false --simulate the copy FileManager.getFileFromUri(path, uri, listener3, fileName, dumyMode ) else print ("\n--\> There is no Uri recorded. Use first the button 3 to get a valid Uri.") end return --stop function for Android and continue from listener3 which is passed to the FileManager plugin above end else -- for iOS path = system.pathForFile( \_fileName, system.DocumentsDirectory ) end local fileHandle = io.open( path, "r" ) for line in fileHandle:lines() do print("Space in line") print( line ) TempFile = json.decode(line); print("?????????????????------------ TempFile ==", TempFile) end io.close( fileHandle ) fileHandle = nil local destDir = system.DocumentsDirectory -- where the file is stored local results, reason = os.remove( system.pathForFile( launchFile, destDir ) ) if results then print( "file removed" ) else print( "file does not exist", reason ) end --do something with the TempFile here with iOS --I have a custom file type that is a json file, depending on what .Type of file it is, I pass the file to the corresponding function -- the code block below is useless to you, but shows an example of how to possibly handle the file --[[] print("????????????????-------------- TempFile == ", TempFile) -- print("?????????????????------------- TempFile.Index.Index ==", TempFile.Index.Index) if TempFile.Index.Type == "Contact" then print("???????????????----------- TempFile.Index.Type == ", TempFile.Index.Type) Analytics.logEvent("Download Contact DataFile") AB.importEmailContactToAddressBook(TempFile) elseif TempFile.Index.Type == "Group" then print("") print("?????????????---------- Group IMPORTED") print("???????????????----------- TempFile.Index.Type == ", TempFile.Index.Type) Analytics.logEvent("Donload Group DataFile") AB.importEmailGroupContactsToAddressBook(TempFile) end --]] else --print("\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* return to mContacts") -- handle URL Scheme / do something end end local onSystemEvent = function(event) print("event should print below") -- PrintReadableTables.print\_r(event) print("----------------------------------------") print("???????????????-------------------------------OnSystemEvent has been called") --TestGroup:toFront() local eventType = event.type; print("????????????????------------------------------- eventType == ", eventType) local eventURL = event.url; print("???????????????????------------------------------ eventURL == ", eventURL) if (eventType == "applicationOpen") then -- app resumes from background print("???????????????-------------------------------applicationOpen has been called") print("eventURL == "..eventURL.."") -- I get this for my eventURL --SM-T113: eventURL == file:///storage/emulated/0/Android/data/com.android.email/cache/TeamPortal\_MultipleContact\_Info-2.mcnt if (eventURL) then print("eventURL Flag1") local \_fileName launchFile = eventURL print("eventURL Flag2") print("???????????????????TopFlag----------- launchFile == ", launchFile) print("eventURL Flag3") if (string.sub(eventURL, 1, 7) == "file://") then -- handle custom extension --if (string.sub(launchFile, 1, 7) == "file://") then -- handle custom extension --launchFile = getDocPath(launchFile); print("???????????????????Flag2 ----------- launchFile == ", launchFile) \_fileName = getDocPath(launchFile); print("???????????????????----------- launchFile == ", launchFile) print("???????????????????----------- \_fileName == ", \_fileName) --I get this from the getDocPath(launchFile) --SM-T113: ???????????????????----------- launchFile == file:///storage/emulated/0/Android/data/com.android.email/cache/TeamPortal\_MultipleContact\_Info-2.mcnt --SM-T113: ???????????????????----------- \_fileName == TeamPortal\_MultipleContact\_Info-2.mcnt FileName = \_fileName local path local ContactsFile local FileLocation = "Void" print("\_platform == ",\_platform) local TestFunction = "3" print("TestFunction == ",TestFunction) if \_platform == "android" then if TestFunction == "1" then print ("\nPick a File \*/\*, and copy it to TemporaryDirectory using pickFile(...)") -- local path = system.pathForFile( nil, system.TemporaryDirectory) path = system.pathForFile( \_fileName, system.TemporaryDirectory) -- local fileName = nil -- fileName we want the copy will be named (String) local fileName = \_fileName local headerText = nil -- personalized dialog (String) local mimeType = "\*/\*" -- mimetype to filter local onlyOpenable = true --avoid non openable files --local onlyDocuments = nil --open only documents filter local onlyDocuments = true local dumyMode = false --simulate the copy FileManager.pickFile(path, listener1, fileName, headerText, mimeType, onlyOpenable, onlyDocuments, dumyMode ) elseif TestFunction == "3" then local myUri = launchFile if myUri and myUri ~= "" then print ("\nUsing the saved myUri : \n" .. myUri .. "\n Get the file using the getFileFromUri(...)" ) path = system.pathForFile( nil, system.DocumentsDirectory ) --the path to copy the file to. local uri = myUri --the uri to get the file from. local fileName = nil -- fileName we want the copy will be named (String) local dumyMode = false --simulate the copy FileManager.getFileFromUri(path, uri, listener3, fileName, dumyMode ) else print ("\n--\> There is no Uri recorded. Use first the button 3 to get a valid Uri.") end return --stop function for Android and continue from listener3 which is passed to FileManager plugin end --local tempDirectory = -- path = system.pathForFile( fileName, storage/emulated/0/Android/data/com.android.email/cache/ ) else -- path = system.pathForFile( launchFile, system.DocumentsDirectory ) path = system.pathForFile( \_fileName, system.DocumentsDirectory ) end print("FileLocation FLAG2== "..FileLocation.."") local fileHandle print("Above fileHandle Flag") fileHandle = io.open( path, "r" ) print("fileHandle == "..fileHandle.."") print("Above for line in fileHandle Flag") for line in fileHandle:lines() do print("Space in line") print( line ) TempFile = json.decode(line); print("?????????????????------------ TempFile ==", TempFile) end io.close( fileHandle ) fileHandle = nil local destDir = system.DocumentsDirectory -- where the file is stored local results, reason = os.remove( system.pathForFile( launchFile, destDir ) ) if results then print( "file removed" ) else print( "file does not exist", reason ) end --do something with the file here --my code below to handle the expected file my app receives -- an example of possible ways to handle the file --[[] print("????????????????-------------- TempFile == ", TempFile) print("?????????????????------------- TempFile.Index.Index ==", TempFile.Index.Index) if TempFile.Index.Type == "Contact" then print("???????????????----------- TempFile.Index.Type == ", TempFile.Index.Type) Analytics.logEvent("Download Contact DataFile") AB.importEmailContactToAddressBook(TempFile) elseif TempFile.Index.Type == "Group" then print("") print("?????????????---------- Group IMPORTED") print("???????????????----------- TempFile.Index.Type == ", TempFile.Index.Type) Analytics.logEvent("Download Group DataFile") AB.importEmailMultipleContactsToAddressBook(TempFile) end --]] else -- handle URL Scheme / do something end end elseif (eventType == "applicationStart") then -- app resumes from background print("???????????????-------------------------------applicationStart has been called") if (eventURL) then launchFile = getDocPath(eventURL); fileName.text = launchFile; end elseif (eventType == "applicationResume") then -- app resumes from background print("???????????????-------------------------------applicationResume has been called") if (eventURL) then launchFile = getDocPath(eventURL); fileName.text = launchFile; end -- possibly call a Resume function if needed -- TimeTracker.onResumeFunction() elseif (eventType == "applicationSuspend") then -- print("???????????????-------------------------------applicationSuspend has been called") -- call an Suspend function if needed --TimeTracker.onSuspendFunction() elseif (eventType == "applicationExit") then -- print("???????????????-------------------------------applicationExit has been called") --call an Exit function if needed end end Runtime:addEventListener("system", onSystemEvent);

Let me know it you get anywhere with this, I’m interested.

Nail

Much appreciated Nail, I’ll give this a go now. :slight_smile:

Paul

So, this was unexpected.

I can pull the file name… Ish!

Using your getDocPath for  “content://0@media/external/images/media/13773”

I am given the file name “13773”

Great! :slight_smile:

The only problem is the file is called “test.pdf”

How bizzare!

I’ll keep looking, but at least that means that the plugin has managed to find the file somehow. The problem is now preserving the original filename.

From what I have read elsewhere I’m being told that sometimes you won’t be able to receive the original filename, but I find that hard to believe as when I share the same file to WhatsApp (for instance), the original filename (test.pdf) is preserved. I’ll keep at it, but I think we’re getting somewhere at least, thanks Nail!

Several hours later after getting to grips with the plugin, we got there!

It was quite simple in its most basic form:

local fileName = nil

local dumyMode = false

path = system.pathForFile( nil, system.DocumentsDirectory )

FileManager.getFileFromUri(path, “content://0@media/external/file/13581”, listener3, fileName, dumyMode )

I also noted (after I finished), that the documentation on the plugin specifically mentions it can deal with content streams:

From http://cnksoft.es/index.php/otro-software/9-plugin-cnkfilemanager-for-corona


Uri: (Mandatory)

(String)

Uri to be passed to the plugin.

Uri examples:

content://com.example.sample.provider/files/xyz/image/JPEG_2017.jpeg


A great little plugin it is too!

Thanks again Nail!

When I get a bit more time, I might have to look at building a plugin that works with this to allow easy access for sharing files, I wouldn’t want anyone else reinventing the wheel when it’s not necessary. 

Paul

Paul,

Good Deal!  

I struggled for days trying to get this to work as I new nothing about the required Android intents needed at the time and then I stumbled on the missing key… FileManager   :slight_smile: to complete the process.

Nail

Paul,

I think you can get the file and path using this awesome free plugin in Marketplace. 

Android File, URI Manager and External Storage

I played with it awhile ago, so I don’t remember exactly how it works, but if you can get the Uri, then the plugin would be worth looking into.

I’ve got the code integrated into one of my apps, but it’s embarrassing.  If you need to see it after looking at the github examples, let me know.

Hope this helps,

Nail

Thanks Nail,

I’ve seen this plugin mentioned in a few places myself, however I’m having difficulty finding out how to use it to pull a URI from a content stream. If you’ve got some code you don’t mind sharing with me, I’d certainly be appreciative!

Also, don’t be embarrassed, I’m far from being a proficient with Lua, and I’m pretty sure most things I have written are probably far worse than anything you’ve put together! :slight_smile:

Paul

Paul,

I haven’t played with the stream intent, I’ve got the code working to get an attachment file contained in an email, similar to the iOS openURL scheme.  I’m thinking getting the file from the Android stream must be similar though by using the plugin to access the uri of the file which appears you are already getting.

I’ll try to dig into the code later tonight if I get a chance (stuff going on tonight), otherwise I should be able to post some code tomorrow evening.

Nail

Paul,

Here’s the code I used.

Glean from it what you can.

I added my onSystemEvent code, which you already must have, not sure what it looks like though.

I am looking for “file//” in my event URL like this as it’s what I’m looking for.

if (string.sub(eventURL, 1, 7) == “file://”) then

You may have to look of  “content//” as that’s what you get for a URL of the streamed file.

I get this for an eventURL:

eventURL == file:///storage/emulated/0/Android/data/com.android.email/cache/TeamPortal_MultipleContact_Info-2.mcnt

I have no idea if FileManager will get the file from the stream “content”, but it’s worth a try since it is a valid URL.

--FileManager Code Blocks used in main.lua --near top of main.lua --will hold plugin if Android local FileManager -- = require "plugin.cnkFileManager" local path = "" local FileName = "" --variable that will hold the fileName for the file imported at Temporary.Directory local launchArgs = ... local launchFile = ""; local fileName; local TempFile local contents = "" local \_platform = system.getInfo( "platform" ) print("\_platform == "..\_platform.."") if ( system.getInfo( "platform" ) == "android" ) then print("Require/ Device platform == android") FileManager = require "plugin.cnkFileManager" end --list Documents Directory local function listDocDirectory() local \_path = system.pathForFile( "", system.DocumentsDirectory ) --print ("\*\*\* Files in Documents Directory \*\*\*") print ("\n--- Files in Documents Directory ---") for file in lfs.dir( \_path ) do -- "file" is the current file or directory name --print( "Found file: " .. file ) print ( file ) end print ("----------------------------------------------\n") end --list temporary directory local function listTempDirectory() local \_path = system.pathForFile( "", system.TemporaryDirectory ) --print ("\*\*\* Files in Temporary Directory \*\*\*") print ("\n--- Files in Temporary Directory ---") for file in lfs.dir( \_path ) do -- "file" is the current file or directory name --print( "Found file: " .. file ) print ( file ) end print ("---------------------------------------------\n") end local getDocPath = function(fName) --returns file Name from eventURL print("getDocPath = function(fName) is called") local f = fName; print("getDocPath / f == "..f.."") if \_platform == "android" then local t = {} -- table to store the indices local i = 0 while true do i = string.find(f, "/", i+1) -- find 'next' newline if i == nil then break end table.insert(t, i) end print("#t == "..#t.."") print("t[#t] == "..t[#t].."") f = string.sub(f, t[#t] + 1, -1) print("FileName == "..f.."") else local docStart, docEnd = f:find("Documents"); print("getDocPath / docStart == "..docStart.." , docEnd == "..docEnd.."") f = f:sub(docEnd+1); print("getDocPath / f == "..f.."") end return f; end --pickFile listener local function listener1 (event) if event.done == "ok" then displayInfo ("File " .. event.destFileName .. " Saved !") print ("FILE READY TO BE SHARED --\> ", event.destPath, event.destFileName) --list the directories listTempDirectory() listDocDirectory() --save the name of the file getted fileName = event.destFileName; else displayInfo ("ERROR. Read the Log.") print ("ERROR: ", event.error) end end local function openDownloadedFileAndroidOnly(path) print("\*\*\*openDownloadedFileAndroidOnly(\_path) is called") --do something with the imported file print("\*\*\*path = ",path) local \_path = system.pathForFile( FileName, system.DocumentsDirectory) print("\*\*\*\_path = ",\_path) local fileHandle = io.open( \_path, "r" ) for line in fileHandle:lines() do print("Space in line") print( line ) TempFile = json.decode(line); print("?????????????????------------ TempFile ==", TempFile) end io.close( fileHandle ) fileHandle = nil local destDir = system.DocumentsDirectory -- where the file is stored local results, reason = os.remove( system.pathForFile( launchFile, destDir ) ) if results then print( "file removed" ) else print( "file does not exist", reason ) end --Here is --[[] print("????????????????-------------- TempFile == ", TempFile) print("?????????????????------------- TempFile.Index.Index ==", TempFile.Index.Index) if TempFile.Index.Type == "Contact" then print("") print("?????????????---------- Contact IMPORTED") print("???????????????----------- TempFile.Index.Type == ", TempFile.Index.Type) Analytics.logEvent("Download Contact DataFile") AB.importEmailContactToAddressBook(TempFile) elseif TempFile.Index.Type == "Group" then print("") print("?????????????---------- Group IMPORTED") print("???????????????----------- TempFile.Index.Type == ", TempFile.Index.Type) Analytics.logEvent("Donload Group DataFile") AB.importEmailGroupContactsToAddressBook(TempFile) end --]] end --receive the event and show the details about the file,this listener is passed to the FileManager plugin which saves the file to your app local function listener3( event ) print("") print("\*\*\*\*\* listener3(event) is called") if event.done then if event.done == "ok" then print ("\nFILE COPIED TO " .. event.destPath .. " with name: " .. event.destFileName) print ("\nThe file is : " .. event.size .. " Bytes Size.") local myText = display.newText( "File " .. event.destFileName .. " Copied !", display.contentCenterX, display.contentCenterY, native.systemFont, 16 ) myText:setFillColor( 1, 0, 0, 1 ) timer.performWithDelay( 3000, function() --destroy image if myText then myText:removeSelf() myText = nil end end) elseif event.done == "dummy" then print ("\nFILE FROM URI: " .. event.uri .. " Can be copied to Path :" .. event.destPath .. "with name: " .. event.destFileName .. " in a safe way") print ("\nThe file is : " .. event.size .. " Bytes Size. and has the original Name: " .. event.origFileName) end --list the directories listTempDirectory() listDocDirectory() local \_path \_path = system.pathForFile( FileName, system.DocumentsDirectory) --I call this function to do something with the imported file on Android openDownloadedFileAndroidOnly(\_path) elseif event.error then print ("\nERROR " .. event.error .. " With errorCode: " .. event.errorCode) print ("\nTrying to copy the file from the uri: " .. event.uri .. " To the path : " .. event.destPath) if event.errorCode == "2" then print ("\nThe User Refused to give permission to the app to get the file. Try again and give permission. It is safe!") elseif event.errorCode == "1" then print ("\nYou NEED to include the following at the build.settings file:") print ("\nandroid.permission.READ\_EXTERNAL\_STORAGE") end end end if (launchArgs and launchArgs.url) then print("??????????????????------------------ launchArgs == ", launchArgs) --PrintReadableTables.print\_r(launchArgs) local LaunchArgsURL = launchArgs.url launchFile = launchArgs.url; print("launchArgs.url == "..launchArgs.url.."") local \_fileName if (string.sub(launchFile, 1, 7) == "file://") then -- handle custom extension \_fileName = getDocPath(launchFile); print("???????????????????----------- launchFile == ", launchFile) print("???????????????????----------- \_fileName == ", \_fileName) FileName = \_fileName local TestFunction = "3" --used to change functions for testing to see what works print("TestFunction == ",TestFunction) if \_platform == "android" then if TestFunction == "1" then print ("\nPick a File \*/\*, and copy it to TemporaryDirectory using pickFile(...)") -- local path = system.pathForFile( nil, system.TemporaryDirectory) path = system.pathForFile( \_fileName, system.TemporaryDirectory) -- local fileName = nil -- fileName we want the copy will be named (String) local fileName = \_fileName local headerText = nil -- personalized dialog (String) local mimeType = "\*/\*" -- mimetype to filter local onlyOpenable = true --avoid non openable files --local onlyDocuments = nil --open only documents filter local onlyDocuments = true local dumyMode = false --simulate the copy FileManager.pickFile(path, listener1, fileName, headerText, mimeType, onlyOpenable, onlyDocuments, dumyMode ) elseif TestFunction == "3" then local myUri = launchFile if myUri and myUri ~= "" then print ("\nUsing the saved myUri : \n" .. myUri .. "\n Get the file using the getFileFromUri(...)" ) path = system.pathForFile( nil, system.DocumentsDirectory ) --the path to copy the file to. local uri = myUri --the uri to get the file from. local fileName = nil -- fileName we want the copy will be named (String) local dumyMode = false --simulate the copy FileManager.getFileFromUri(path, uri, listener3, fileName, dumyMode ) else print ("\n--\> There is no Uri recorded. Use first the button 3 to get a valid Uri.") end return --stop function for Android and continue from listener3 which is passed to the FileManager plugin above end else -- for iOS path = system.pathForFile( \_fileName, system.DocumentsDirectory ) end local fileHandle = io.open( path, "r" ) for line in fileHandle:lines() do print("Space in line") print( line ) TempFile = json.decode(line); print("?????????????????------------ TempFile ==", TempFile) end io.close( fileHandle ) fileHandle = nil local destDir = system.DocumentsDirectory -- where the file is stored local results, reason = os.remove( system.pathForFile( launchFile, destDir ) ) if results then print( "file removed" ) else print( "file does not exist", reason ) end --do something with the TempFile here with iOS --I have a custom file type that is a json file, depending on what .Type of file it is, I pass the file to the corresponding function -- the code block below is useless to you, but shows an example of how to possibly handle the file --[[] print("????????????????-------------- TempFile == ", TempFile) -- print("?????????????????------------- TempFile.Index.Index ==", TempFile.Index.Index) if TempFile.Index.Type == "Contact" then print("???????????????----------- TempFile.Index.Type == ", TempFile.Index.Type) Analytics.logEvent("Download Contact DataFile") AB.importEmailContactToAddressBook(TempFile) elseif TempFile.Index.Type == "Group" then print("") print("?????????????---------- Group IMPORTED") print("???????????????----------- TempFile.Index.Type == ", TempFile.Index.Type) Analytics.logEvent("Donload Group DataFile") AB.importEmailGroupContactsToAddressBook(TempFile) end --]] else --print("\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* return to mContacts") -- handle URL Scheme / do something end end local onSystemEvent = function(event) print("event should print below") -- PrintReadableTables.print\_r(event) print("----------------------------------------") print("???????????????-------------------------------OnSystemEvent has been called") --TestGroup:toFront() local eventType = event.type; print("????????????????------------------------------- eventType == ", eventType) local eventURL = event.url; print("???????????????????------------------------------ eventURL == ", eventURL) if (eventType == "applicationOpen") then -- app resumes from background print("???????????????-------------------------------applicationOpen has been called") print("eventURL == "..eventURL.."") -- I get this for my eventURL --SM-T113: eventURL == file:///storage/emulated/0/Android/data/com.android.email/cache/TeamPortal\_MultipleContact\_Info-2.mcnt if (eventURL) then print("eventURL Flag1") local \_fileName launchFile = eventURL print("eventURL Flag2") print("???????????????????TopFlag----------- launchFile == ", launchFile) print("eventURL Flag3") if (string.sub(eventURL, 1, 7) == "file://") then -- handle custom extension --if (string.sub(launchFile, 1, 7) == "file://") then -- handle custom extension --launchFile = getDocPath(launchFile); print("???????????????????Flag2 ----------- launchFile == ", launchFile) \_fileName = getDocPath(launchFile); print("???????????????????----------- launchFile == ", launchFile) print("???????????????????----------- \_fileName == ", \_fileName) --I get this from the getDocPath(launchFile) --SM-T113: ???????????????????----------- launchFile == file:///storage/emulated/0/Android/data/com.android.email/cache/TeamPortal\_MultipleContact\_Info-2.mcnt --SM-T113: ???????????????????----------- \_fileName == TeamPortal\_MultipleContact\_Info-2.mcnt FileName = \_fileName local path local ContactsFile local FileLocation = "Void" print("\_platform == ",\_platform) local TestFunction = "3" print("TestFunction == ",TestFunction) if \_platform == "android" then if TestFunction == "1" then print ("\nPick a File \*/\*, and copy it to TemporaryDirectory using pickFile(...)") -- local path = system.pathForFile( nil, system.TemporaryDirectory) path = system.pathForFile( \_fileName, system.TemporaryDirectory) -- local fileName = nil -- fileName we want the copy will be named (String) local fileName = \_fileName local headerText = nil -- personalized dialog (String) local mimeType = "\*/\*" -- mimetype to filter local onlyOpenable = true --avoid non openable files --local onlyDocuments = nil --open only documents filter local onlyDocuments = true local dumyMode = false --simulate the copy FileManager.pickFile(path, listener1, fileName, headerText, mimeType, onlyOpenable, onlyDocuments, dumyMode ) elseif TestFunction == "3" then local myUri = launchFile if myUri and myUri ~= "" then print ("\nUsing the saved myUri : \n" .. myUri .. "\n Get the file using the getFileFromUri(...)" ) path = system.pathForFile( nil, system.DocumentsDirectory ) --the path to copy the file to. local uri = myUri --the uri to get the file from. local fileName = nil -- fileName we want the copy will be named (String) local dumyMode = false --simulate the copy FileManager.getFileFromUri(path, uri, listener3, fileName, dumyMode ) else print ("\n--\> There is no Uri recorded. Use first the button 3 to get a valid Uri.") end return --stop function for Android and continue from listener3 which is passed to FileManager plugin end --local tempDirectory = -- path = system.pathForFile( fileName, storage/emulated/0/Android/data/com.android.email/cache/ ) else -- path = system.pathForFile( launchFile, system.DocumentsDirectory ) path = system.pathForFile( \_fileName, system.DocumentsDirectory ) end print("FileLocation FLAG2== "..FileLocation.."") local fileHandle print("Above fileHandle Flag") fileHandle = io.open( path, "r" ) print("fileHandle == "..fileHandle.."") print("Above for line in fileHandle Flag") for line in fileHandle:lines() do print("Space in line") print( line ) TempFile = json.decode(line); print("?????????????????------------ TempFile ==", TempFile) end io.close( fileHandle ) fileHandle = nil local destDir = system.DocumentsDirectory -- where the file is stored local results, reason = os.remove( system.pathForFile( launchFile, destDir ) ) if results then print( "file removed" ) else print( "file does not exist", reason ) end --do something with the file here --my code below to handle the expected file my app receives -- an example of possible ways to handle the file --[[] print("????????????????-------------- TempFile == ", TempFile) print("?????????????????------------- TempFile.Index.Index ==", TempFile.Index.Index) if TempFile.Index.Type == "Contact" then print("???????????????----------- TempFile.Index.Type == ", TempFile.Index.Type) Analytics.logEvent("Download Contact DataFile") AB.importEmailContactToAddressBook(TempFile) elseif TempFile.Index.Type == "Group" then print("") print("?????????????---------- Group IMPORTED") print("???????????????----------- TempFile.Index.Type == ", TempFile.Index.Type) Analytics.logEvent("Download Group DataFile") AB.importEmailMultipleContactsToAddressBook(TempFile) end --]] else -- handle URL Scheme / do something end end elseif (eventType == "applicationStart") then -- app resumes from background print("???????????????-------------------------------applicationStart has been called") if (eventURL) then launchFile = getDocPath(eventURL); fileName.text = launchFile; end elseif (eventType == "applicationResume") then -- app resumes from background print("???????????????-------------------------------applicationResume has been called") if (eventURL) then launchFile = getDocPath(eventURL); fileName.text = launchFile; end -- possibly call a Resume function if needed -- TimeTracker.onResumeFunction() elseif (eventType == "applicationSuspend") then -- print("???????????????-------------------------------applicationSuspend has been called") -- call an Suspend function if needed --TimeTracker.onSuspendFunction() elseif (eventType == "applicationExit") then -- print("???????????????-------------------------------applicationExit has been called") --call an Exit function if needed end end Runtime:addEventListener("system", onSystemEvent);

Let me know it you get anywhere with this, I’m interested.

Nail

Much appreciated Nail, I’ll give this a go now. :slight_smile:

Paul

So, this was unexpected.

I can pull the file name… Ish!

Using your getDocPath for  “content://0@media/external/images/media/13773”

I am given the file name “13773”

Great! :slight_smile:

The only problem is the file is called “test.pdf”

How bizzare!

I’ll keep looking, but at least that means that the plugin has managed to find the file somehow. The problem is now preserving the original filename.

From what I have read elsewhere I’m being told that sometimes you won’t be able to receive the original filename, but I find that hard to believe as when I share the same file to WhatsApp (for instance), the original filename (test.pdf) is preserved. I’ll keep at it, but I think we’re getting somewhere at least, thanks Nail!

Several hours later after getting to grips with the plugin, we got there!

It was quite simple in its most basic form:

local fileName = nil

local dumyMode = false

path = system.pathForFile( nil, system.DocumentsDirectory )

FileManager.getFileFromUri(path, “content://0@media/external/file/13581”, listener3, fileName, dumyMode )

I also noted (after I finished), that the documentation on the plugin specifically mentions it can deal with content streams:

From http://cnksoft.es/index.php/otro-software/9-plugin-cnkfilemanager-for-corona


Uri: (Mandatory)

(String)

Uri to be passed to the plugin.

Uri examples:

content://com.example.sample.provider/files/xyz/image/JPEG_2017.jpeg


A great little plugin it is too!

Thanks again Nail!

When I get a bit more time, I might have to look at building a plugin that works with this to allow easy access for sharing files, I wouldn’t want anyone else reinventing the wheel when it’s not necessary. 

Paul

Paul,

Good Deal!  

I struggled for days trying to get this to work as I new nothing about the required Android intents needed at the time and then I stumbled on the missing key… FileManager   :slight_smile: to complete the process.

Nail