You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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());
            }
        }
    }
}

四、额外说明

  1. 应用专属外部存储路径:getExternalFilesDir(null)指向/storage/emulated/0/Android/data/com.example.pdfscanner/files,属于应用私有,卸载时自动删除,无需权限。
  2. 若需在公共目录(如Documents)创建文件夹,Android 10+需使用MediaStore API,或申请MANAGE_EXTERNAL_STORAGE权限(仅适合文件管理器类应用,需谷歌审核)。
  3. 避免使用已废弃的Environment.getExternalStorageDirectory()方法。

内容的提问来源于stack exchange,提问作者044_Harshvardhan Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 14:30:42