Android Studio实现手机内部存储文件夹创建失败求助
Android内部存储创建文件夹问题解答
一、Android是否允许在内部存储创建文件夹?
Android完全允许在应用专属内部存储创建文件夹,且不需要任何权限——这是应用的私有空间,其他应用无法访问,卸载应用时会被自动删除。
但如果你指的是外部公共存储(比如手机根目录、Documents目录等),Android 10(API 29)及以上引入了分区存储政策,直接通过File API写入公共目录会受限,需要适配新规则。
二、代码创建失败的核心问题及修复方案
1. 路径拼接完全错误
你定义的folderPath是无效路径:
String folderPath=Environment.getDataDirectory().getAbsolutePath() +"/storage/emulated/0Pdf Scanner";
Environment.getDataDirectory()指向应用内部存储根目录(比如/data),拼接后变成不存在的无效路径,自然无法创建。
2. 创建文件夹的逻辑错误
createFolder()方法里先调用folder.createNewFile()(创建文件),再调用folder.mkdir()(创建同名文件夹),同一个路径不能既是文件又是文件夹,直接导致失败。
3. 变量与逻辑混乱
你同时维护directory和folder两个不同的File对象,一个指向外部存储的"Pdf Scanner",另一个指向错误的内部路径,逻辑相互干扰。
4. 权限请求的RequestCode冲突
你用同一个REQUEST_CODE=100同时处理权限请求和拍照/选图的结果回调,导致权限通过后调用createFolder(),但拍照完成后也会触发错误逻辑。
5. 分区存储适配问题
Android 10+中,WRITE_EXTERNAL_STORAGE权限无法直接写入公共目录,建议优先使用应用专属外部存储(无需权限,兼容所有版本)。
三、修正后的代码示例
以下是修复后的完整代码,采用应用专属外部存储创建文件夹:
package com.example.pdfscanner; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.RecyclerView; import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.provider.MediaStore; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import java.io.File; public class MainActivity extends AppCompatActivity { // 区分权限请求和拍照/选图的RequestCode private final static int PERMISSION_REQUEST_CODE = 7; private final static int IMAGE_CAPTURE_REQUEST_CODE = 100; private final static int IMAGE_PICK_REQUEST_CODE = 101; Button convert, upload, camera; ImageView img; TextView title; ProgressBar progressBar; RecyclerView recyclerView; File directory; // 统一管理目标文件夹 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); askPermission(); title = findViewById(R.id.fileName); convert = findViewById(R.id.converter_tool_convert); camera = findViewById(R.id.converter_tool_camera); upload = findViewById(R.id.converter_tool_upload); img = findViewById(R.id.converter_tool_imageView); progressBar = findViewById(R.id.progressbar); recyclerView = findViewById(R.id.recyclerView); // 应用专属外部存储路径,无需权限,兼容所有版本 directory = new File(getExternalFilesDir(null), "Pdf Scanner"); // 检查并创建文件夹 if (!directory.exists()) { boolean isCreated = directory.mkdirs(); Toast.makeText(getApplicationContext(), isCreated ? "文件夹已创建" : "文件夹创建失败", Toast.LENGTH_LONG).show(); } camera.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (directory.exists()) { progressBar.setVisibility(View.VISIBLE); Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, IMAGE_CAPTURE_REQUEST_CODE); } else { progressBar.setVisibility(View.GONE); Toast.makeText(MainActivity.this, "文件夹未创建,尝试重新创建", Toast.LENGTH_SHORT).show(); createFolder(); } } }); upload.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (directory.exists()) { progressBar.setVisibility(View.VISIBLE); Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, IMAGE_PICK_REQUEST_CODE); } else { progressBar.setVisibility(View.GONE); Toast.makeText(MainActivity.this, "文件夹未创建,尝试重新创建", Toast.LENGTH_SHORT).show(); createFolder(); } } }); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); progressBar.setVisibility(View.GONE); if (resultCode != RESULT_OK) { Toast.makeText(this, "操作取消", Toast.LENGTH_SHORT).show(); return; } if (data != null && data.getData() != null) { Uri selectedImg = data.getData(); String[] filePathColumn = {MediaStore.Images.Media.DISPLAY_NAME}; Cursor cursor = getContentResolver().query(selectedImg, filePathColumn, null, null); if (cursor != null) { cursor.moveToFirst(); String name = cursor.getString(cursor.getColumnIndex(filePathColumn[0])); cursor.close(); img.setImageURI(selectedImg); title.setText(name); } } else { Toast.makeText(this, "未选择图片", Toast.LENGTH_SHORT).show(); } } private void askPermission() { // Android 10+ 无需WRITE_EXTERNAL_STORAGE访问应用专属外部存储 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) + ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, PERMISSION_REQUEST_CODE); } } else { // 仅请求相机权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST_CODE); } } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == PERMISSION_REQUEST_CODE) { boolean allGranted = true; for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { allGranted = false; break; } } if (allGranted) { createFolder(); } else { Toast.makeText(this, "权限未授予,部分功能无法使用", Toast.LENGTH_SHORT).show(); } } } private void createFolder() { if (!directory.exists()) { boolean isCreated = directory.mkdirs(); Toast.makeText(this, isCreated ? "文件夹创建成功" : "文件夹创建失败", Toast.LENGTH_SHORT).show(); if (!isCreated) { Log.e("FolderCreate", "失败路径: " + directory.getAbsolutePath()); } } } }
四、额外说明
- 应用专属外部存储路径:
getExternalFilesDir(null)指向/storage/emulated/0/Android/data/com.example.pdfscanner/files,属于应用私有,卸载时自动删除,无需权限。 - 若需在公共目录(如Documents)创建文件夹,Android 10+需使用MediaStore API,或申请
MANAGE_EXTERNAL_STORAGE权限(仅适合文件管理器类应用,需谷歌审核)。 - 避免使用已废弃的
Environment.getExternalStorageDirectory()方法。
内容的提问来源于stack exchange,提问作者044_Harshvardhan Singh
相关产品推荐
相关产品推荐

