【问题标题】:Android 6 - Programmatically copy an app file to another folderAndroid 6 - 以编程方式将应用文件复制到另一个文件夹
【发布时间】:2016-11-08 04:41:00
【问题描述】:

我有一个在 Android 6 中运行的应用程序,它从 BLE 设备流式传输数据。这在使用类似的东西时效果很好:

myFile = new File(getExternalFilesDir(filepath), MyData);

生成的文件位于如下位置:

文件路径:/storage/emulated/0/Android/data/my_package/files/my_file

我想将此文件复制到 Android/data 目录下未埋在大量文件中的新文件夹中,以便用户可以轻松找到并检索通过 USB 电缆连接到手机/平板电脑的数据。到目前为止,我一直无法弄清楚如何做到这一点......或者是否有可能。我尝试的任何事情似乎都会导致权限异常。

如果可能,我希望此文件夹与 ~/Android/data 处于同一级别。如果没有,是否有任何替代方案?比如把数据放到SD卡上。

我已经阅读了很多关于 Android 文件系统的帖子和文章。这一切都非常混乱和模糊。新版本的 Android 似乎改变了工作方式。如果有人知道关于 Android 6 (Marshmallow) 的清晰简洁的解释(甚至可能有工作示例!)请告诉我。

谢谢,马克斯

【问题讨论】:

标签: android android-6.0-marshmallow android-file


【解决方案1】:

出于某些安全原因,android 6.0 限制获取运行时权限。因此,以下代码将帮助您获得许可。

注意不要从清单中删除权限,下面给出的过程仅适用于 6.0,其他 android 操作系统的权限将从清单中授予

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
        }
    }

【讨论】:

  • 比我预期的要复杂得多!我需要一些时间来处理和测试它。欣赏示例代码,因为它似乎涵盖了 Android 开发人员页面中没有很好地介绍的一些技术。
  • 非常感谢,如果您愿意,可以通过投票支持我的答案来感谢您:D
  • 我会投票,但我需要更多积分才能这样做。很抱歉,您的回答确实让我指出了正确的方向。
【解决方案2】:

我使用了 Adeel Turk 的许可建议。我不需要检查构建版本,因为我只使用 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();
            }
    }
}

虽然这通过了权限例外,但它没有回答如何在默认应用程序目录之外创建文件夹的问题。以下代码获得许可并在 /storage/emulated/0 处创建一个名为 AppData 的文件夹,该文件夹显示在设备存储的顶层。在 Adeel Turk 的示例中,权限请求代码 WFileRequest 设置为 4,但我知道您可以使用任何数字。权限请求回调然后检查请求代码并使用最初写入的文件的名称再次调用 copyFile 例程。

大部分代码都使用了论坛中how to create a folder in android External Storage Directory?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();
    }

}

【讨论】:

    猜你喜欢
    • 2012-01-29
    • 2015-10-30
    • 1970-01-01
    • 1970-01-01
    • 2017-01-04
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    • 1970-01-01
    相关资源
    最近更新 更多