Max
Max

Reputation: 1

Android 6 - Programmatically copy an app file to another folder

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

Answers (2)

Max
Max

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

Adeel Turk
Adeel Turk

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

Related Questions