Am using this code to try to read a particular directory an android devices.. this is the code in a released application. it works fine on all devices except SamSung devices..
fetchFromOriginalDirectory() async{
var result = await PhotoManager.requestPermission();//getting permission to check files
if (result) {
Directory dir = Directory('/storage/emulated/0/');
List<FileSystemEntity> _files;
_files = dir.listSync(recursive: true, followLinks: false).reversed.toList();//getting all files(stickers) in this directory
for(FileSystemEntity entity in _files) {//for each file gotten do this
String path = entity.path;
I first thought the problem was this line "/storage/emulated/0/" but after using multiple plugins to check for the right path. i found out the paths are the same. But for some reason the app cant read the files on samsung files. even after all permissions have been granted
Hey guys i fixed it by doing this
<application
android:requestLegacyExternalStorage="true" //adding this line
>
In the android manifest file.
Related
I want to export a save file so the user can later import it into the app again later, but how do I allow exporting to a directory outside the app dir (/Android/com.app/files)
if (!(await Permission.storage.request().isGranted)) return;
final String? exportPath = await FilePicker.platform.getDirectoryPath();
if (exportPath == null) return;
File exportFile = await File(
"$exportPath/zs_tracker_data.sav",
).create(recursive: true);
This code is backed by these gradle properties:
android.useAndroidX=true
android.enableJetifier=true
With compileSdkVersion 33 selected, and these permissions:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
All of these above allows me to get a path, and then get this prompt:
However, even when I press 'Allow', I am not allowed to touch that directory and get: Unhandled Exception: FileSystemException: Cannot create file, path = '/storage/emulated/0/Backups/zs_tracker_data.sav' (OS Error: Operation not permitted, errno = 1)
I've considered allowing MANAGE_EXTERNAL_STORAGE, but then my app won't be allowed on Play Store, since the only reasons it needs storage permissions are for creating backups and importing backups. I've also seen this post: Flutter read/write to external storage with Android SDK 30+, but the answer blows over my head completely and seems horribly over complex for my simple backup export/importing...
How do I go about this in a decently simple way? I just want to be able to save the exported file somewhere where the user can easily find it
Maybe use a totally different approach which doesn't require any permissions. Use sharing to allow a user to choose whatever a destination she/he desires. For example using share_plus plugin:
Share.shareFiles(['<path to file>'], text: 'Export file');
In my android project I have created an assets folder in which I have added some json files and I want to read them with a stringBuffer. The assets folder is listed inside src/main. So far I have added the following code:
String[] files = assetManager.list("");
ArrayList<String> it = new ArrayList<>(Arrays.asList(files));
And so far I am getting the names of the files successfully inside my ArrayList. Then I am trying this:
InputStream input = assetManager.open("filename.json");
But I get the following error:
Failed to open file
'/data/data/package/code_cache/.overlay/base.apk/assets/filename.json':
No such file or directory
I also have included the follwing permission in the manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Any idea what might be the problem here?
You can clear storage in device and then rebuild app, that help my same issue.
I got the same issue on my Android project many times. Try uninstalling the app on your emulator and rebuild your app.
After a lot of googling, and a lot of tries with "out-of-context" code, I'm begging you to help me.
I'm trying to figure out if it's possible to write on the external storage with Nativescript. I'm not interested to write within the application context. So what the docs shows, it's not what i'm looking for.
I've managed to achieve this from a thread on the Nativescript forum:
android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS).toString();
It works, it gives me a path, but when I have this path I have no clue of what to do with it. How to create a file inside that path, read it etc.
What I need to achieve is to create a folder that both the user and the application can easily access. The user should be able to access this folder with the builtin files explorer.
The application runs on Angular.
I really struggled with this one on Android device and in the end it was due to:
Not making sure the required permissions has been granted by the user in the app
Using "Android File Transfer" on my Macbook to verify the files have been created and to download them
tns info
nativescript 6.0.3
tns-core-modules 6.0.7
tns-android 6.0.2
tns plugins
nativescript-permissions 1.3.7
example code
import * as fs from "tns-core-modules/file-system"
...
// First get the required permissions
// Note: this permissions should also be in your AndroidManifest.xml file as:
// <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
const permissions = require('nativescript-permissions')
permissions.requestPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
.then(() => {
console.log('Required Android permissions have been granted');
})
.catch(() => {
console.error('Required Android permissions have been denied!');
});
// Get the publicly accessable Downloads directory path
const sdDownloadPath = android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS).toString()
console.log('sdDownloadPath: ' + sdDownloadPath)
// Get a specific folder in that path (will be created if it does not exist)
const myAppFolder = fs.Folder.fromPath(fs.path.join(sdDownloadPath, 'myApp'))
console.log('myApp path: ' + myAppFolder.path)
// Get a file in that path (will be created if it does not exist)
// Note: In this case we try to get a unique file every time this code is run
let date = new Date()
date = date.toISOString().replace('.', '')
const myFile = myAppFolder.getFile(`myfile_${date}.txt`)
console.log('myFile path: ' + myFile.path)
// Write some data to this new file
myFile.writeText('Hello duder 123')
.then(() => {})
.catch((err) => console.log(`Error writing to file: ${err}`))
// Try and read back the data that was written
myFile.readText()
.then((res) => {
console.log(`Text read back: ${res}`)
}).catch((err) => {
console.log(err.stack);
});
// List all files in the myApp folder
myAppFolder.getEntities()
.then((entities) => {
// entities is array with the document's files and folders.
entities.forEach((entity) => {
console.log(entity)
});
}).catch((err) => {
console.log(err.stack);
});
android file transfer issue
One problem I wasted a lot of time on was that I could see the files with getEntities() but could not see them when using the 3rd party tool "Android File Transfer (AFT)" on Mac. I eventually stumbled across "Android Studio's -> Device File Explorer" and could see all my created files and folders with it so realised the issue is with AFT.
I now make use of Airdroid to browse and download device files.
applicable reference
https://docs.nativescript.org/angular/ng-framework-modules/file-system
(angular docs but relevant to nativescript-vue as well)
Do you know your external(sd card) path?
If it is like /storage/emulated/0, then you could try this to create a folder or file.
import * as fs from "tns-core-modules/file-system";
let externalPath= fs.path.join(android.os.Environment.getExternalStorageDirectory().getAbsolutePath().toString());
//Create a folder with known path
var folder: fs.Folder = fs.Folder.fromPath(sdCardPath+"/test");
//Create a file
var testFile: fs.File = folder.getFile("test.txt");
console.log("Path " + folder.path)
User should be able to access this fold and file. It is in device internal storage which is "external" folder.
I still try to figure out how to get access to sd card but hope above code work for you.
I have the same issue and finally solved it by adding android:requestLegacyExternalStorage="true" inside the AndroidManifest.xml file
follow the thread here
I've had to upload a separate expansion file with my app (developed in Qt) in Google Play console. It's a simple rcc file. I have the name of file after the upload (it shows on the google console page). But I can't seem to find any info o how to get the shared-storage path (as mentioned) on the Android docs page (http://developer.android.com/google/play/expansion-files.html#StorageLocation).
I did come across this question (How to add android expansion files using Qt) where the user seems to have solved the issue but doesn't give any details on how to get the shared-storage path.
I've solved it:
I converted a qrc containing the large files to a binary using the qt rcc tool, then I used the following code to call the proper methods from the Qt Android Activity and retrieve the correct path to the expansion files:
QAndroidJniObject mediaDir = QAndroidJniObject::callStaticObjectMethod("android/os/Environment", "getExternalStorageDirectory", "()Ljava/io/File;");
QAndroidJniObject mediaPath = mediaDir.callObjectMethod( "getAbsolutePath", "()Ljava/lang/String;" );
QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
QAndroidJniObject package = activity.callObjectMethod("getPackageName", "()Ljava/lang/String;");
QString dataAbsPath = mediaPath.toString()+"/Android/obb/"+package.toString()+"/yourExpansionFileName.obb";
QAndroidJniEnvironment env; // Don't know what this is for ?
if (env->ExceptionCheck()) { env->ExceptionClear(); } // Or this...?
bool loadResource = QResource::registerResource(dataAbsPath);
Don't forget to add #include <QAndroidJniEnvironment> in your app (and QT += androidextras in pro file), and last add this permission to the manifest (as the expansion file is located inside the external storage):
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
I didn't check if the file was there or not before loading (every device I tested worked straight), but the android docs say you might need to download it manually. There is also some catch to uploading expansion files, you can only add them with the second apk submission (in Google play).
This code may be help you.
QStringList systemEnvironment = QProcess::systemEnvironment();
looking for
EXTERNAL_STORAGE=/storage/emulated/legacy
EXTERNAL_ADD_STORAGE=/storage/external_SD
SECONDARY_STORAGE=/storage/external_SD
...
This code worked for me:
QString s = QStandardPaths::writableLocation(QStandardPaths::movieLoaction);
QDir MyDir;
s = s + "/MyFolder"
MyDir.mkdir(s);
In your Android device you must check the storage permissions for your application. If not add this permission then run the application.
I want to get the external and internal storage in my app. I'm using this code
Scanner scanner = new Scanner(new File("/etc/vold.fstab"));
while (scanner.hasNext()) {
String line = scanner.nextLine();
if (line.toLowerCase().contains("dev_mount")) {
if (line.toLowerCase().contains("nonremovable")) {
VoldMounts.put(line.split(" ")[2],true);
}else {
VoldMounts.put(line.split(" ")[2],false);
}
}
}
It's working fine on Android 4.2.2 and below, but on Android 4.3 the file is changed to /fstab.<device> and this file needs root access. How can I read the fstab without the need of root access? I don't want to use /proc/mount.
Thanks.
Here is some official information that confirms that "for Android releases 4.3 and later, the various fstab files used by init, vold and recovery were unified in the /fstab. file". As that file has -rw-r----- root root permissions there is no way to read it from an app on a non-rooted device.