第13天android:向sd卡写文件

本文详细介绍了在Android中如何进行SD卡文件操作,包括权限设置、文件读写及路径获取等关键步骤,适合初学者及开发者快速掌握SD卡文件管理技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://www.verycd.com/topics/2915669/

14_传智播客Android视频教程_把文件存放在SDCard

1.小文件是方便保存到自带存储空间(1G),大文件保存在sd卡。
2.不建议写入sd卡的绝对路径,1.5版本路径就不一样。
3.文件查看器 Window-->Show View--> File Explore.
4.创建文件和写文件都要权限。
    <!-- 创建和删除文件 -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <!-- 写文件 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
5.权限相关的页面 /android-sdks/docs/reference/android/Manifest.permission.html
6.向sd卡写文件
// 判断sd卡状态
        if (Environment.MEDIA_MOUNTED.equals(Environment
                .getExternalStorageState())) {
            Toast.makeText(getApplicationContext(), "sd error", 3);
        }
        File f = new File("/mnt/sdcard/1234.txt");
        FileOutputStream fo;
        try {
            fo = new FileOutputStream(f);
            fo.write("time to work,Now".getBytes());
            fo.close();
            Toast.makeText(getApplicationContext(), "file ok!", 5);
        } catch (Exception e) {
            e.printStackTrace();
        }
7.动态取得sd卡绝对路径
File f = new File("(Environment.getExternalStorageDirectory()", "1234.txt");

上面获得的路径是:/mnt/sdcard  注意,没有反斜杠,所以new 文件的时候要像上面一样,不适合字符串拼接。

 

 

 

转载于:https://www.cnblogs.com/wanself/archive/2012/07/26/2609313.html

<think>嗯,用户问的是Android从内部存储拷贝文件SD失败的问题。我需要先理清楚可能的原因,然后逐步给出解决方案。首先,我得回忆一下Android系统对SD权限的变化,尤其是从哪个版本开始需要特殊处理。 可能的原因有几个方面。首先是权限问题,Android 6.0之后需要动态申请权限,而Android 10及以上版本引入了作用域存储,访问外部存储可能需要MANAGE_EXTERNAL_STORAGE权限,或者使用Storage Access Framework。用户的应用可能没有正确申请这些权限,导致无法SD。 其次是文件路径的问题。在Android不同版本中,访问外部存储的路径可能有变化,比如使用Context.getExternalFilesDir()或者MediaStore API。如果用户还是用旧的路径方式,可能在较新的系统上失效。 另外,SD本身的问题也不能排除,比如文件系统损坏、没有正确挂载,或者物理损坏。还有应用本身的配置,比如AndroidManifest.xml里有没有声明外部存储的权限,或者Scoped Storage适配的问题。 接下来,我需要整理解决步骤。第一步检查权限,确保在AndroidManifest.xml中声明了WRITE_EXTERNAL_STORAGE,并且在运行时动态申请了权限。对于Android 10及以上,可能需要使用ACTION_OPEN_DOCUMENT_TREE来让用户选择目录,然后通过DocumentFile API进行操作。 第二步是检查文件路径,确认使用的是正确的API获取SD路径,比如通过Environment.getExternalStorageDirectory()可能已经不可靠,应该用MediaStore或者StorageVolume的方法。 第三步是处理作用域存储,可能需要使用FileProvider来共享文件,或者适配MediaStore API进行文件操作,避免直接使用File类。 第四步是检查SD状态,比如是否可读,存储空间是否足够,或者尝试在其他应用里操作SD,看是否是系统问题。 最后,可能需要检查代码中的具体实现,比如是否使用了正确的URI,文件流是否正确关闭,以及是否有异常捕获和日志输出,帮助定位问题。 用户可能需要具体的代码示例,比如如何动态申请权限,如何使用DocumentFile,或者MediaStore的插入方式。同时提醒用户测试不同Android版本,确保兼容性。 还要考虑用户的应用是否正确地处理了Scoped Storage,特别是在Android 11及以上,MANAGE_EXTERNAL_STORAGE权限需要用户手动授权,而且Google Play对使用这个权限的应用有严格审核。 可能用户遇到的错误包括FileNotFoundException或者SecurityException,这些都需要具体分析。另外,提醒用户查看Logcat日志,找出具体的错误信息,有助于进一步诊断问题。 总之,解决方案需要涵盖权限、路径、API使用、SD状态和代码适配等多个方面,逐步排查可能的原因,并提供相应的修复方法。</think>针对Android设备从内部存储拷贝文件SD失败的问题,以下是逐步排查和解决方案: --- ### **一、权限问题排查** #### 1. **检查AndroidManifest.xml权限声明** ```xml <!-- 基础入权限(Android 9及以下需此权限) --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- Android 10及以上适配作用域存储(Scoped Storage) --> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:minSdkVersion="30" tools:ignore="ScopedStorage" /> ``` #### 2. **动态申请权限(代码层面)** ```java // Android 6.0+ 需动态申请权限 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE); } } ``` #### 3. **适配Android 10+的作用域存储** - 使用 **`MediaStore` API** 或 **`SAF`(Storage Access Framework)** SD: ```java // 示例:通过MediaStore插入文件SD ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.DISPLAY_NAME, "test.jpg"); values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/MyApp"); Uri externalUri = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL); Uri fileUri = getContentResolver().insert(externalUri, values); try (OutputStream os = getContentResolver().openOutputStream(fileUri)) { // 将文件内容入os流 } catch (IOException e) { e.printStackTrace(); } ``` --- ### **二、SD路径问题** #### 1. **获取SD正确路径** - **错误做法**:直接使用`Environment.getExternalStorageDirectory()`(已废弃)。 - **正确做法**: ```java // 通过StorageVolume获取SD路径(Android 9+) StorageManager storageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE); List<StorageVolume> volumes = storageManager.getStorageVolumes(); for (StorageVolume volume : volumes) { if (volume.isRemovable()) { File sdCardPath = volume.getDirectory(); break; } } ``` --- ### **三、文件系统兼容性** #### 1. **检查SD格式** - 确保SD格式为 **`exFAT`** 或 **`FAT32`**(Android兼容性较好)。 - **NTFS格式可能无法入**。 #### 2. **SD状态检查** ```java // 检查SD是否已挂载且可读 String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { // SD可读 } else { // 提示用户检查SD } ``` --- ### **四、代码适配问题** #### 1. **避免直接使用`File`类** - 在Android 10+中,直接通过`File`类操作SD路径会失败,需改用 **`DocumentFile`**: ```java // 使用SAF选择SD目录 Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); startActivityForResult(intent, REQUEST_CODE_SD_CARD); // 在onActivityResult中获取URI Uri treeUri = data.getData(); DocumentFile sdCardDir = DocumentFile.fromTreeUri(context, treeUri); // 创建文件入 DocumentFile newFile = sdCardDir.createFile("text/plain", "myfile.txt"); OutputStream os = getContentResolver().openOutputStream(newFile.getUri()); ``` #### 2. **适配FileProvider(跨进程文件访问)** ```xml <!-- AndroidManifest.xml中声明FileProvider --> <provider android:name="androidx.core.content.FileProvider" android:authorities="com.your.package.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> ``` --- ### **五、常见错误场景** #### 1. **`java.io.FileNotFoundException: Permission denied`** - **原因**:未正确申请权限或未使用作用域存储API。 - **解决**:改用`MediaStore`或`SAF`文件。 #### 2. **`EACCES (Permission denied)`** - **原因**:SD路径不可。 - **解决**:通过`StorageVolume`获取正确路径或让用户手动选择目录。 --- ### **六、测试建议** 1. 在不同Android版本(9/10/11/13)上测试。 2. 使用`adb logcat`查看具体错误日志。 3. 优先使用模拟器或真机调试SD。 通过以上步骤,可系统性解决Android内部存储到SD拷贝失败的问题。如果问题仍存在,需检查设备厂商是否对SD访问做了额外限制(如小米、华为等定制系统)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值