Reputation: 1
I have an app running in Android 6 that streams data in from a BLE device. This works fine when using something like:
myFile = new File(getExternalFilesDir(filepath), MyData);
The resulting file is at a location that looks like:
Filepath: /storage/emulated/0/Android/data/my_package/files/my_file
I'd like to copy this file to a new folder that is not buried in the mass under the Android/data directory so a user can easily find and retrieve the data connecting to a phone/tablet via the USB cable. So far, I've been unable to figure out how to do this ... or if it's even possible. Anything I try seems to result in a permission exception.
I'd like this folder to be at the same level as ~/Android/data if possible. If not, are there any alternatives? Such as putting the data out on the SD card.
I've read through many posts and articles on the Android file system. It's all very confusing and vague. And new versions of Android seem to change the way things work. If anyone knows of a clear and concise explanation relative to Android 6 (Marshmallow) (maybe even with working examples!) please let me know.
Thanks, Max
Upvotes: 0
Views: 1681
Reputation: 1
I used the permission suggestion from Adeel Turk. I didn't need to check the build version, since I'm using only Android 6 (API 23).
//
// Get storage write permission
//
public boolean isStoragePermissionGranted(int requestCode) {
if (ContextCompat.checkSelfPermission(MyActivity.this,android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
//Now you have permission
return true;
} else {
ActivityCompat.requestPermissions(MyActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode);
return false;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Now you have permission
// Check file copy generated the request
// and resume file copy
if(requestCode == WFileRequest)
try {
copyFile(OriginalDataFileName);
} catch (IOException e) {
e.printStackTrace();
}
}
}
While this got through the permission exceptions, it didn't answer the question of how to create a folder outside of the default application directory. The following code gets permission and creates a folder at /storage/emulated/0 called AppData which appears on the top level of Device storage. The permission request code WFileRequest was set to 4 as in Adeel Turk's example, but I understand you can use any number. The permission request callback then checks the request code and invokes the copyFile routine again with the name of the file that was originally written.
Most of this code used examples from a couple other posts in this forum at how to create a folder in android External Storage Directory? and How to copy programmatically a file to another directory?
public void copyFile(String SourceFileName) throws FileNotFoundException, IOException
{
String filepath = "";
//
// Check permission has been granted
//
if (isStoragePermissionGranted(WFileRequest)) {
//
// Make the AppData folder if it's not already there
//
File Directory = new File(Environment.getExternalStorageDirectory() + "/AppData");
Directory.mkdirs();
Log.d(Constants.TAG, "Directory location: " + Directory.toString());
//
// Copy the file to the AppData folder
// File name remains the same as the source file name
//
File sourceLocation = new File(getExternalFilesDir(filepath),SourceFileName);
File targetLocation = new File(Environment.getExternalStorageDirectory() + "/AppData/" + SourceFileName);
Log.d(Constants.TAG, "Target location: " + targetLocation.toString());
InputStream in = new FileInputStream(sourceLocation);
OutputStream out = new FileOutputStream(targetLocation);
// Copy the bits from instream to outstream
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
}
Upvotes: 0
Reputation: 907
android 6.0 restricts to get run time permissionsfor some security reasons. So follwing code will help you to get the permissons.
NOTE dont remove permissions from manifest the given below process is just for 6.0 for other android OS permossion will be granted from manifest
public static final int galleryPermissionRequestCode=4;
public void chkForPermissoins(){
if (Build.VERSION.SDK_INT >= 23) {
//do your check here
isStoragePermissionGranted(camPermissionRequestCode);
} else {
//You already have the permission because the os you appp is running on is less tahn 23 (6.0)
}
}
public boolean isStoragePermissionGranted(int requsetCode) {
if (Build.VERSION.SDK_INT >= 23) {
if (ContextCompat.checkSelfPermission(getActivity(),android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
//Now you have permsssion
return true;
} else {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, requsetCode);
return false;
}
}
else { //permission is automatically granted on sdk<23 upon installation
//Now you have permsssion
return true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(grantResults[0]== PackageManager.PERMISSION_GRANTED){
//Now you have permsssion
//resume tasks needing this permission
}
}
Upvotes: 1