Adobe-Runtime-Support icon indicating copy to clipboard operation
Adobe-Runtime-Support copied to clipboard

Feature : [Android] Air should retrieve list of internal and external drive for targeting to save documents.

Open balaedit opened this issue 3 years ago • 22 comments

To point the internal directory, Air have below snip :

var file:File = File.documentsDirectory.resolvePath("AIR Test");

To point the external directory, Air don't have File object to work around it.

I achieve by putting 'file:///storage'+(SerialNumberOfPendrive)

Air should have retrieve function so that we can easily target the internal or external (if Exists) drive without using any extensions (ANE's)

balaedit avatar Mar 01 '21 11:03 balaedit

it's already 4 days, the request has posted, no reply from HARMAN's.

balaedit avatar Mar 05 '21 04:03 balaedit

Hi - sorry, yes, although adding extra comments to the thread is a good idea as it triggers another email notification...

@balaedit would you like to suggest something that would work here? I'm not entirely sure whether this needs new functionality or whether it should be possible to get at what you're after using the existing StorageVolume classes? e.g. StorageVolumeInfo.storageVolumeInfo.getStorageVolumes(); See https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/filesystem/StorageVolume.html https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/filesystem/StorageVolumeInfo.html#getStorageVolumes()

ajwfrost avatar Mar 05 '21 08:03 ajwfrost

After giving permission to the app using permission method :

var fPerCheck: File = new File(); fPerCheck.addEventListener(PermissionEvent.PERMISSION_STATUS, checkPermissions);

try { fPerCheck.requestPermission(); } catch (e: Error) { // another request is in progress trace("REQUEST ERROR!!! : " + e.toString()); } finally {

} function checkPermissions(e: PermissionEvent): void { trace("Status is : " + e.status.toString()); // does not reach to this point if user declined permission request if (e.status == 'granted') { checkLocalFile(); } }

function checkLocalFile() { var volumes = StorageVolumeInfo.storageVolumeInfo.getStorageVolumes(); for (var i = 0; i < volumes.length; i++) { var volume:StorageVolume = volumes[i]; trace ("isRemovable :" + volume.isRemovable); } }

After compiling the code and executing the checkLocalFile Function, getting below error :

TypeError: Error #1009: Cannot access a property or method of a null object reference. at sam1_fla::MainTimeline/checkLocalFile()[sam1_fla.MainTimeline::frame1:171] at sam1_fla::MainTimeline/checkPermissions()[sam1_fla.MainTimeline::frame1:162]

This is working properly on Desktop but not on android.

My app is about online learning of school education. App needed lots of data to download so it is not suitable for internal storage. I used alternate way to resolve the issue but it's not the proper way to handle every student manually using student's sdcard's serial number.

Needed very much to resolve this issue.

Below posted by other since very long time :

https://community.adobe.com/t5/air/internal-external-storage-external-sd-card-storage/td-p/3036042

https://community.adobe.com/t5/air/getexternalfilesdirs-how-do-we-write-to-external-sd-card-for-android-4-4-and-above/td-p/7690431

balaedit avatar Mar 05 '21 09:03 balaedit

Okay thanks for the details .. I'll ask one of the Android guys to look into this. It seems that it should work via the above APIs but for some reason there's a null return value there...

ajwfrost avatar Mar 05 '21 09:03 ajwfrost

It's an easy one to add, we have it available in the Application ANE:

https://docs.airnativeextensions.com/asdocs/application/com/distriqt/extension/application/Device.html#getExternalFilesDir()

but you might want to work it into the existing AIR SDK.

marchbold avatar Mar 05 '21 10:03 marchbold

I already purchased Harman's Adobe Air, UDID ane, pdf viewer ane. So I not in position to purchase another ANE. Is there any free ANE available for android to retrieve device sdcard location to save the downloaded content.

balaedit avatar Mar 05 '21 11:03 balaedit

Hi @balaedit Can I check what you're actually trying to do here: is it just to have a location for your application itself to store larger amounts of data, rather than having any kind of random file access capabilities to the entire of a storage card? I would be curious as to the value you get for File.applicationStorageDirectory? thanks

ajwfrost avatar Mar 09 '21 11:03 ajwfrost

Mine Developing Mode App on PlayStore : https://play.google.com/store/apps/details?id=air.EduLearningApp

You can login using Mobile OTP authentication.

Currently in the app, the data is storing in Application storage directory i.e. File.applicationStorageDirectory syntax.

It is good for single child at home for single standard online education material. But we came across that many have more than one child using our app, so data is beyond 20 GB of higher grade (Standard).

So we decided to give 64GB memory card or they need have external device prompt (alert) from app to save data. but File.desktopDirectory syntax return device internal storage i.e. storage/0 File.documentsDirectory syntax return device internal storage i.e. storage/0 File.userDirectory syntax return device internal storage i.e. storage/0

There is no syntax to get device storage device.

Currently, I am working around building ANE for my requirement. Please help if you have anything freely ready available.

balaedit avatar Mar 10 '21 09:03 balaedit

Interesting.. thanks. We're checking the code because from a quick check, it looked like the 'applicationStorageDirectory' should already have been using the android 'getExternalFilesDir' method.

So if that's not the case then there's nothing we've got immediately to hand, but we could look at adding something for getting that external path. Not necessarily the root folder of the SD card, but the folder into which your application can place it's files.

I'm assuming you've already got the SD card set up to be used as default storage by Android, or have checked if you can set this up on an app-by-app basis? e.g. see the steps in the below link.. https://www.internetgeeks.org/tech/how-to-make-sd-card-default-storage-on-android/

thanks

ajwfrost avatar Mar 10 '21 10:03 ajwfrost

Hi... Thanks for reply.

File.applicationStorageDirectory—a storage directory unique to each installed AIR application means it is a cache / application linked folder i.e. the downloaded data will destroy as soon the app is removed/uninstalled.

On the other side, My devices, like Redmi 9, Redmi 9 Pro, Mi A3, One+ Norde do not have feature of setting SD Card as a Default Storage Option.

If you have any ready free ANE, please share it at : [email protected]

Thanks.

balaedit avatar Mar 12 '21 04:03 balaedit

Hi...

Finally I created ANE which retrieve all the list of the drive including internal and pure external or removable drives.

My ANE retrieve SD card location so that we can easily save the data to the external drive from my application.

Thanks Andrew Frost and Michael.

balaedit avatar Apr 19 '21 11:04 balaedit

The reason to reopen is Android is not giving access to the external storage write permission.

Our SDK syntax for writing external storage is : File.applicationRemovableStorageDirectory.resolvePath("Filename");

But My data is read and write in the root folder "MyFolderName" of the external storage.

Using syntax applicationRemovableStorageDirectory return /storage/0EED-3116/Android/data/myAppName/files/temp.txt in the file object name's nativePath and null in the file object name's url but I want to write in /storage/0EED-3116/myFolderName

var temp:File = File.applicationRemovableStorageDirectory.resolvePath("temp.txt"); trace(temp.nativePath); // return /storage/0EED-3116/Android/data/air.filePicker/files/temp.txt trace(temp.url); // return error and in debugger it shows 'exception from the getter' // changing the native path temp1.nativePath = "/storage/0EED-3116/temp.txt" // giving request permission to the above path and while writing file on it return error with access denied.

How to achieve this requirement.

Please do needful as soon as possible.

balaedit avatar Jul 04 '22 12:07 balaedit

Hi

The applicationRemovableStorageDirectory is an application-specific folder, hence the subfolder structure that's then provided. This is obtained via the Android APIs.

To actually write to the root of the SD card is not something I believe should be possible using the latest Android APIs? I'll check with a colleague on this though..

ajwfrost avatar Jul 04 '22 15:07 ajwfrost

Hi

The applicationRemovableStorageDirectory is an application-specific folder, hence the subfolder structure that's then provided. This is obtained via the Android APIs.

To actually write to the root of the SD card is not something I believe should be possible using the latest Android APIs? I'll check with a colleague on this though..

Is there any update on this issue.

balaedit avatar Jul 14 '22 11:07 balaedit

It already had been more than 10 days. No response.

I had done some research and found that,

To save data in external location on mobile (currently i.e. document directory) or any external directory (i,e. applicationRemovableStorageDirectory) we need to add "" in the app's manifest xml. But how to request that permission from the app.

Please guide me to resolve my issue.

I have need this requirement.

balaedit avatar Jul 27 '22 08:07 balaedit

Hi - sorry, we were tracking this more under #1871 .. the ability to save something in "any" folder is only possible if you have the MANAGE_EXTERNAL_STORAGE permission, but that's not something that we'd expect AIR apps to have (as Google would be reviewing apps for this, it's mostly just for File Manager type things): https://ourcodeworld.com/articles/read/1559/how-does-manage-external-storage-permission-work-in-android

So, in order to have the user provide access to files and/or folders, we will be updating the File.browseForXxx functions so that they use the system-provided intents for this, rather than the current built-in file selection dialog. This would then mean that we automatically get the permissions to access the files that the user has selected.

FYI currently it should still be possible to do something like File.documentsDirectory.resolvePath("Documents").resolvePath("MyFile.txt") and read/write to that file, but this is only possible if the file is created/owned by your application. Scoped storage means that you won't see files that someone else has put there.

In your comment above there's a blank "" so I think a copy/paste or formatting error has happened - not sure which permission you were meaning?

thanks

ajwfrost avatar Jul 27 '22 08:07 ajwfrost

The blank "" was <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>.

Thanks for resolving the issue for internal storage i.e. File.documentsDirectory.resolvePath("Documents").resolvePath("MyFile.txt"). I will check for this. Is this documented in our Air SDK release notes. Sorry if it is documented that I missed to read it.

Is File.applicationRemovableStorageDirectory.resolvePath("Documents").resolvePath("MyFile.txt") work for external/removable drives.

balaedit avatar Jul 27 '22 09:07 balaedit

Okay thanks - so yes, MANAGE_EXTERNAL_STORAGE is something you can request via the descriptor/manifest but I don't believe we have any way to check on it at runtime. But I'm not sure it's something that Google/Android want people to be using if their apps don't need it, i.e. only for "file manager" type apps.

The directory resolution thing is still a little bit up in the air so not really documented as we're still investigating how best to approach all this! So it's just something that's been mentioned in one or two of the issues/discussions in this github system...

I would have expected anything under the File.applicationRemovableStorageDirectory to be accessible without needing specific subfolders or permissions, because this is an application-specific folder already...?

thanks

ajwfrost avatar Jul 27 '22 09:07 ajwfrost

Thanks for early reply, I would like to know that, like mxPlayer, vlc player or any other music player can pickup any files from internal or external files to play in respective app. How? I don't think that they are in category of "File manager" app. I required that type of functionality in my app.

balaedit avatar Jul 27 '22 11:07 balaedit

That may depend what sort of access they are getting...

It shouldn't be possible for their apps to just automatically access any files from internal/external storage; however, it's possible that they'd be able to use the MediaStore APIs to read any indexed media content: https://developer.android.com/training/data-storage/shared/media

Alternatively they could be popping up a message asking the user to select a folder in which to search for media files - which would then mean the user is essentially giving the app permission to read everything in that folder, which is one of the things we're looking to do via the File.requestPermission AS3API.

thanks

ajwfrost avatar Jul 27 '22 16:07 ajwfrost

I would have expected anything under the File.applicationRemovableStorageDirectory to be accessible without needing specific subfolders or permissions, because this is an application-specific folder already...?

Above line was written by @ajwfrost.

File.documentsDirectory.resolvePath("Documents").resolvePath("MyFile.txt") or File.documentsDirectory.resolvePath("Download").resolvePath("MyFile.txt") Using the above syntax, we get the internal storage access of the android device. Thanks for this, but since my requirement is not getting resolved.

We are giving data in the external storage i.e. SD card and using the syntax File.applicationRemovableStorageDirectory.resolvePath("myFile.txt");

I get : /storage/0E0C-400C/Android/data/app.name/files/Documents/myFile.txt

Which is wiped out as soon as the app uninstalled.

My requirement will be complete as you did for internal storage syntax i.e. File.documentsDirectory.resolvePath("Documents").resolvePath("MyFile.txt") for external method/function needs to add in the AIR SDK such as File.applicationRemovableStorageDirectory.resolvePath("Documents").resolvePath("MyFile.txt") or File.documentsRemovableStorageDirectory.resolvePath("MyFile.txt") to target document folder of the external storage as document folder in SDcard is by default created as soon as it is inserted.

It will solve all the issues for internal (already given solution) and external (needs to implement).

Thanks Balkrishna Vitthal Guttikonda

balaedit avatar Aug 11 '22 00:08 balaedit

@balaedit so just to check, you are looking to store something in a folder on the SD Card, but in such a way that it's a generic file and not one that is removed when the app is uninstalled?

In which case I think this is going to need the use of the Android Storage Access Framework: we are working on an ANE that can be used for this, but it's also going to need the user to select where to put the file. Unless it's a known media type where we could then use the Media Store APIs (images/videos/audio), that is... and the goal is for the ANE to offer both options, it will then be up to app developers to request the appropriate permissions.

So if you're trying to save a document like a PDF or text file, into a common storage area such as the "Documents" folder, you can use the ANE which provides shared storage access (https://developer.android.com/training/data-storage/shared/documents-files) and this would allow the user to select the document location and name, and once they've done this you can then write the file. If you've got your app descriptor set up with the right permissions, the files can then be also set such that they're openable by other applications... but all this is a bit of a minefield!

thanks

ajwfrost avatar Aug 16 '22 15:08 ajwfrost