无法在文件夹中写入外部存储下载 - Android

Posted

技术标签:

【中文标题】无法在文件夹中写入外部存储下载 - Android【英文标题】:Cannot write External Storage in folder Download - Android 【发布时间】:2022-01-11 19:33:05 【问题描述】:

我是 android 新手,有时我找不到合适的解决方案,这就是其中之一。

我编写了一个简单的应用程序来编写使用 ITextPdf 库生成的内部 pdf。这工作正常,我可以从设备文件资源管理器中看到 pdf 文件。现在我正在使用外部存储做同样的事情,但在这种情况下,我无法在下载文件夹中生成文件。我发现了对我的代码不起作用的解决方案。

我的代码:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-sdk android:minSdkVersion="21"
        android:targetSdkVersion="31"
        android:maxSdkVersion="31" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.PDFApplication">
        <activity
            android:name=".PdfDocumentTestActivity"
            android:exported="true" />
        <activity
            android:name=".MainActivity"
            android:exported="true" />
        <activity
            android:name=".SavePathActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".PrintPdfIPActivity2"
            android:exported="true" />
    </application>

文件.java

public class SavePathActivity extends AppCompatActivity 
 
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_save_path);

        Button btnShowPath = findViewById(R.id.btnPath);
      
        btnShowPath.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 

                try 
                    writeFile();
                 catch (FileNotFoundException e) 
                    e.printStackTrace();
                

            
        );
    

    private boolean isExternalStorageWritable()

        String res = Environment.getExternalStorageState();

        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
            Log.i("State","it's writable");
            return true;
        else
            return false;
        
    

    public void writeFile() throws FileNotFoundException 

        if (isExternalStorageWritable() && checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)) 
       //if (isExternalStorageWritable()) 
            String directory_path = Environment.getExternalStorageDirectory() + "/MyDir/";
            String targetPdf = directory_path + "ITEXTPDF.pdf";

            Rectangle layout = new Rectangle(PageSize.ARCH_A);
            //layout.setBackgroundColor(new BaseColor(100, 200, 180)); //Background color
            layout.setBorderColor(BaseColor.DARK_GRAY);  //Border color
            layout.setBorderWidth(6);      //Border width
            layout.setBorder(Rectangle.BOX);

            Document document = new Document(layout);
            PdfWriter writer = null;

            File dir = new File(directory_path);
            if(!dir.exists())
                dir.mkdirs();

            File file = new File(dir, "newFile.pdf");
            FileOutputStream fOut = new FileOutputStream(file);
            try 
                try 
                    writer = PdfWriter.getInstance(document, fOut);
                 catch (DocumentException e) 
                    e.printStackTrace();
                
                document.open();
                PdfContentByte cb = writer.getDirectContent();
                //Get width and height of whole page
                float pdfPageWidth = document.getPageSize().getWidth();
                float pdfPageHeight = document.getPageSize().getHeight();

                document.add(new Paragraph("pdfPageWidth = "+pdfPageWidth));
                document.add(new Paragraph("pdfPageHeight = "+pdfPageHeight));

                Barcode39 barcode39 = new Barcode39();
                barcode39.setCode("123456789");
                Image code39Image = barcode39.createImageWithBarcode(cb, null, null);
                document.add(code39Image);
                document.newPage();
                document.close();
                //viewPdf("newFile.pdf", "MyDir");
             catch (DocumentException e) 
                e.printStackTrace();
            
         else 
            Toast.makeText(getApplicationContext(), "Cannot write External Storage", Toast.LENGTH_SHORT).show();
        
    


    public boolean checkPermission(String permission)
        int check = ContextCompat.checkSelfPermission(getApplicationContext(), permission);
        int pm = PackageManager.PERMISSION_GRANTED;
        return (check == PackageManager.PERMISSION_GRANTED);
    

我在ContextCompat.checkSelfPermission(getApplicationContext(), permission) 中发现了问题。它返回-1,但我不明白不起作用。

这用于内部存储。如何查看应用程序的工作原理

【问题讨论】:

I wrote a simple app to write internal pdf generated using ITextPdf libray. This is worked fine and I can see pdf file from Device File Explorer. 请告知目录的完整路径。请告知所用设备的 Android 版本。 if(!dir.exists()) dir.mkdirs(); 目录创建了吗?这样你就不知道了。更好:if(!dir.exists()) if (!dir.mkdirs()) return; 也显示 Toast 以通知用户。我认为该目录不是一开始就创建的 您应该能够写入下载目录。好吧,如果您像往常一样拥有正常的写/读权限。仅对于 Android 10/Q,您还需要一些特别的东西。 上方是我的设备文件浏览器的图像 String directory_path = Environment.getExternalStorageDirectory() + "/MyDir/"; 这不是下载文件夹的开始。如您所说,使用下载文件夹。并告诉所用设备的 Android 版本。我第二次问了。 【参考方案1】:

在 Android Q(Api-Level 29)中,您无法再获得此权限:

https://developer.android.com/reference/android/Manifest.permission#WRITE_EXTERNAL_STORAGE

您需要使用 DocumentsFile API 或其他方法在其中写入文件。不要尝试使用 requestLegacyExternalStorage,因为它在 Android 11 中已不受支持。

【讨论】:

以上是关于无法在文件夹中写入外部存储下载 - Android的主要内容,如果未能解决你的问题,请参考以下文章

无法在Android上写入外部存储

即使设置了权限,也无法写入 Android 外部存储

在 Android 的外部存储中写入文件

DownloadManager 无法使用 Pie 下载到三星的外部存储

如何将文件写入 Android 中的外部公共存储,以便它们在 Windows 中可见?

Android 11:无法从外部存储加载文件