ข้อยกเว้น 'การเปิดล้มเหลว: EACCES (ปฏิเสธการอนุญาต)' บน Android


297

ฉันได้รับ

เปิดล้มเหลว: EACCES (Permission denied)

ในบรรทัด OutputStream myOutput = new FileOutputStream(outFileName);

android.permission.WRITE_EXTERNAL_STORAGEฉันจะตรวจสอบรากและฉันพยายาม

ฉันจะแก้ไขปัญหานี้ได้อย่างไร

try {
    InputStream myInput;

    myInput = getAssets().open("XXX.db");

    // Path to the just created empty db
    String outFileName = "/data/data/XX/databases/"
            + "XXX.db";

    // Open the empty db as the output stream
    OutputStream myOutput = new FileOutputStream(outFileName);

    // Transfer bytes from the inputfile to the outputfile
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer)) > 0) {
        myOutput.write(buffer, 0, length);
    }

    // Close the streams
    myOutput.flush();
    myOutput.close();
    myInput.close();
    buffer = null;
    outFileName = null;
}
catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}

ฉันมีปัญหาเดียวกันบนแท็บเล็ต Android แต่สถานการณ์ของฉันอาจไม่ซ้ำกันดังนั้นฉันจึงรายงานวิธีแก้ไขปัญหาของฉันที่นี่ในความคิดเห็น ข้อผิดพลาดเกิดขึ้นเมื่อแอปพยายามเข้าถึงไดเรกทอรี / data / data / myapp / foo ซึ่งมีไฟล์มากกว่า 50 xml แอปไม่ได้ล้างโฟลเดอร์เนื่องจากข้อผิดพลาด หลังจากลบไฟล์เก่าแล้วข้อผิดพลาดก็หายไป ฉันไม่รู้ว่าทำไม. อาจเป็นปัญหาของอุปกรณ์ Android ทั่วไป
ฮ่องกง

วิธีนี้แก้ไขฉันได้: stackoverflow.com/questions/33666071/…
partho

คำตอบ:


236

ฉันมีปัญหาเดียวกัน ... ที่<uses-permissionอยู่ผิดที่ ถูกต้อง:

 <manifest>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
        ...
        <application>
            ...
            <activity> 
                ...
            </activity>
        </application>
    </manifest> 

uses-permissionความต้องการแท็กจะอยู่นอกapplicationแท็ก


2
มันคือการอนุญาตการใช้งานจำเป็นต้องอยู่นอกแอปพลิเคชัน
462990

3
ฉันได้รับคำเตือน: " <uses-permission>แท็กปรากฏขึ้นหลังจาก<application>แท็ก"
mr5

11
คำเตือนในหุ่นยนต์ 4.4.4 android:maxSdkVersion="18"ไม่ใช้พารามิเตอร์ มันสร้างข้อยกเว้นนี้
guisantogui

1
การอนุญาตนี้มีผลบังคับใช้ตั้งแต่ระดับ API 19 ก่อนที่ API ระดับ 19 การอนุญาตนี้จะไม่ถูกบังคับใช้และแอปทั้งหมดยังคงสามารถเข้าถึงเพื่ออ่านจากที่เก็บข้อมูลภายนอก
Zar E Ahmer

1
ฉันกำลังใช้ API lvl 15, ฉันได้รับข้อผิดพลาดขณะพยายามย้ายไฟล์ไปยัง OTG USB Stick
Ravi Mehta

330

สำหรับ API 23+ คุณต้องขอสิทธิ์ในการอ่าน / เขียนแม้ว่าจะอยู่ในรายการของคุณอยู่แล้ว

// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
};

/**
 * Checks if the app has permission to write to device storage
 *
 * If the app does not has permission then the user will be prompted to grant permissions
 *
 * @param activity
 */
public static void verifyStoragePermissions(Activity activity) {
    // Check if we have write permission
    int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);

    if (permission != PackageManager.PERMISSION_GRANTED) {
        // We don't have permission so prompt the user
        ActivityCompat.requestPermissions(
                activity,
                PERMISSIONS_STORAGE,
                REQUEST_EXTERNAL_STORAGE
        );
    }
}

AndroidManifest.xml

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

สำหรับเอกสารอย่างเป็นทางการเกี่ยวกับการขอสิทธิ์สำหรับ API 23+ ให้ตรวจสอบhttps://developer.android.com/training/permissions/requesting.html


13
เพียงชี้แจงเพื่อให้สิ่งนี้ใช้งานได้กิจกรรมต้องจัดการการตอบสนองการร้องขอการอนุญาตของกิจกรรม ดูdeveloper.android.com/training/permissions/…สำหรับรายละเอียดเพิ่มเติม
kldavis4

ลิงค์ที่มีประโยชน์พร้อมคำอธิบายและตัวอย่างได้ที่นี่ในthecheesefactory.com/blog/…
Paul Alexander

1
นี่ไม่ใช่สิ่งที่เลวร้ายใช่ไหม ด้วยความเคารพต่อประสบการณ์ของผู้ใช้
M. Usman Khan

5
แต่ฉันจะใช้มันที่ไหน ตัวอย่างเช่นหากฉันต้องการถ่ายรูปฉันต้องเรียกใช้ VerifyStoragePermissions ก่อน startActivityForResult หรือที่ onActivityResult หรือไม่ มันทำให้ฉันสับสนจริงๆ
กีวีลี

3
ขอบคุณนี้แก้ปัญหาของฉัน เพียงแค่ทราบ: หากมีคนไม่สามารถแก้ไข "Manifest.permission" คุณเพียงแค่ต้องนำเข้า "android.Manifest" นำเข้า
Oubaida AlQuraan

167

Google มีคุณสมบัติใหม่ในAndroid Q : มุมมองที่ถูกกรองสำหรับที่จัดเก็บข้อมูลภายนอก การแก้ไขอย่างรวดเร็วสำหรับการที่จะเพิ่มรหัสนี้ในไฟล์ AndroidManifest.xml:

<manifest ... >
    <!-- This attribute is "false" by default on apps targeting Android Q. -->
    <application android:requestLegacyExternalStorage="true" ... >
     ...
    </application>
</manifest>

คุณสามารถอ่านเพิ่มเติมได้ที่นี่: https://developer.android.com/training/data-storage/compatibility


@Billy ผมสังเกตเห็นว่ามันจะเกิดขึ้นเฉพาะบนอุปกรณ์ที่มี API 29. ดังนั้น i สืบค้นสำหรับการเปลี่ยนแปลงในผู้ให้บริการไฟล์
ยูเรียลแฟรงเคิล

ในที่สุดก็ทำให้ cloudtestingsc Screenshotter_lib.aar ทำงานร่วมกับบรรทัดนี้ที่เพิ่มเข้าไปในรายการ androidTest ขอขอบคุณสำหรับการค้นพบนี้
bko

6
คุณช่วยฉันประหยัดเวลาได้มาก หลายสิ่งหลายอย่างกลายเป็นความเจ็บปวดสำหรับนักพัฒนาใน Q. ฉันคิดว่าคำตอบนี้ควรโพสต์เป็นคำถามแยกต่างหากและสมควรได้รับการโหวตมากขึ้น
sanjeev

ฉันต้องการอ่านเพิ่มเติมเกี่ยวกับเคล็ดลับเวทย์มนตร์ดำน้อยนี้ แต่น่าเสียดายที่ลิงค์ส่งคืนข้อผิดพลาด 404 ... ขอบคุณต่อไป
SadSido

ให้คำเตือนandroid:requestLegacyExternalStorage="true"มันจะไม่ทำลายรุ่นที่ต่ำกว่า ryt? @UrielFrankel
Santanu Sur

58

ฉันสังเกตสิ่งนี้ครั้งเดียวเมื่อเรียกใช้แอปพลิเคชันภายในตัวจำลอง ในการตั้งค่าอีมูเลเตอร์คุณต้องระบุขนาดของที่จัดเก็บข้อมูลภายนอก ("การ์ด SD") อย่างถูกต้อง โดยค่าเริ่มต้นฟิลด์ "ที่จัดเก็บข้อมูลภายนอก" ว่างเปล่าและนั่นอาจหมายความว่าไม่มีอุปกรณ์ดังกล่าวและ EACCES ถูกโยนทิ้งแม้ว่าจะได้รับอนุญาตในรายการ


51

นอกจากคำตอบทั้งหมดแล้วตรวจสอบให้แน่ใจว่าคุณไม่ได้ใช้โทรศัพท์เป็นที่เก็บข้อมูล USB

ฉันมีปัญหาเดียวกันกับ HTC Sensation ในโหมดที่เก็บข้อมูล USB ที่เปิดใช้งาน ฉันยังคงสามารถดีบัก / เรียกใช้แอปได้ แต่ฉันไม่สามารถบันทึกลงในที่จัดเก็บข้อมูลภายนอกได้


ขอบคุณชายถึงแม้ว่าฉันได้ขอสิทธิ์จากผู้ใช้ที่รันไทม์ ข้อผิดพลาดนี้เกิดขึ้นกับโปรแกรมจำลอง
Sharp Edge

1
เมื่อฉันเชื่อมต่ออุปกรณ์ Samsung Galaxy S6 ก่อนอื่นให้ตัวเลือก "อนุญาตการเข้าถึงข้อมูลอุปกรณ์" ด้วย "DENY" หรือ "ALLOW" และจากแถบการแจ้งเตือนฉันได้รับตัวเลือกใช้ USB สำหรับ 1. MTP 2. PTP 3. MIDI อุปกรณ์ 4. การชาร์จ เลือกแบบไหน
ทดสอบ

34

เพิ่มหุ่นยนต์: requestLegacyExternalStorage = "true"ไปยัง Android Manifest มันทำงานร่วมกับ Android 10 (Q) ที่ SDK 29+
หรือหลังจากการโยกย้ายAndroid X

 <application
    android:name=".MyApplication"
    android:allowBackup="true"
    android:hardwareAccelerated="true"
    android:icon=""
    android:label=""
    android:largeHeap="true"
    android:supportsRtl=""
    android:theme=""
    android:requestLegacyExternalStorage="true">

ว้าวทำงานได้อย่างสมบูรณ์นั่นคือคำตอบที่ฉันขอมาก @rhaldar คุณช่วยชีวิตฉันไว้
Ayush Katuwal

29

ปัญหาของฉันอยู่ที่ "TargetApi (23)" ซึ่งจำเป็นถ้า minSdkVersion ของคุณร้อง 23

ดังนั้นฉันได้รับอนุญาตคำขอด้วยตัวอย่างต่อไปนี้

protected boolean shouldAskPermissions() {
    return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1);
}

@TargetApi(23)
protected void askPermissions() {
    String[] permissions = {
            "android.permission.READ_EXTERNAL_STORAGE",
            "android.permission.WRITE_EXTERNAL_STORAGE"
    };
    int requestCode = 200;
    requestPermissions(permissions, requestCode);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
// ...
    if (shouldAskPermissions()) {
        askPermissions();
    }
}

28

โซลูชันสำหรับAndroid Q :

<application ...
    android:requestLegacyExternalStorage="true" ... >

คุณได้บันทึกวันของฉัน ได้รับอนุญาต แต่ Glide ไม่สามารถอ่านภาพได้จนกว่าฉันจะตั้งค่านี้
ปรึกษา

ข้อควรระวัง: Android 11 จะลบการเข้าถึงแบบดั้งเดิมในเดือนสิงหาคม 2020 ดังนั้นจึงควรอัพเกรดการเข้าถึงไฟล์เพื่อใช้ Storage Access Framework (SAF) สำหรับแอปของคุณดีขึ้น
dimib

16

ฉันกำลังประสบกับสิ่งเดียวกัน สิ่งที่ฉันพบคือถ้าคุณไปที่การตั้งค่า -> ตัวจัดการแอปพลิเคชัน -> แอพของคุณ -> การอนุญาต -> เปิดใช้งานการจัดเก็บมันจะแก้ปัญหาได้


1
ฉันไม่พบส่วนนี้
Evan Sevy

13

มันเปิดออกมันเป็นความผิดพลาดที่โง่ตั้งแต่ฉันยังมีโทรศัพท์ของฉันยังคงเชื่อมต่อกับพีซีตั้งโต๊ะและไม่ได้ตระหนักถึงสิ่งนี้

ดังนั้นฉันต้องปิดการเชื่อมต่อ USB และทุกอย่างทำงานได้ดี


ทำงานให้ฉันด้วย แต่ทำไมมันถึงใช้งานได้? สิ่งที่แตกต่างไม่ได้เชื่อมต่อ USB กับพีซี
user13107

คำถามที่ดี. ฉันไม่เคยตรวจสอบเรื่องนี้อีกเลย ฉันเดาว่าจะมีการล็อคการเขียนจากระบบเมื่อคุณเชื่อมต่ออุปกรณ์ (ดังนั้นอาจเลียนแบบอุปกรณ์ usb ในคอมพิวเตอร์ของคุณ) บางทีนี่อาจเป็นการหลีกเลี่ยงข้อมูลที่ไม่สอดคล้องกัน ไม่แน่ใจว่า
Tobias Reich

ฉันพบสาเหตุที่นี่stackoverflow.com/questions/7396757/ …ดูคำตอบของฉันstackoverflow.com/a/43863548/1729501
13107

13

ฉันมีปัญหาเดียวกันกับ Samsung Galaxy Note 3 ที่รัน CM 12.1 ปัญหาสำหรับฉันคือที่ฉันมี

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="18"/>

และต้องใช้เพื่อถ่ายและจัดเก็บรูปถ่ายของผู้ใช้ เมื่อฉันพยายามโหลดรูปถ่ายเดียวกันใน ImageLoader ฉันพบ(Permission denied)ข้อผิดพลาด การแก้ปัญหาคือการเพิ่มอย่างชัดเจน

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

เนื่องจากสิทธิ์ข้างต้น จำกัด สิทธิ์ในการเขียนสูงสุดของ API เวอร์ชัน 18 เท่านั้นและด้วยสิทธิ์การอ่าน


ไม่ได้ช่วยฉัน! คุ้มค่าลองดูสิ! ขอบคุณ
Sakiboy

9

นอกเหนือจากคำตอบทั้งหมดหากลูกค้าใช้ Android 6.0 Android จะเพิ่มรูปแบบการอนุญาตใหม่สำหรับ (Marshmallow)

เคล็ดลับ:หากคุณกำหนดเป้าหมายเป็นเวอร์ชัน 22 หรือต่ำกว่าแอปพลิเคชันของคุณจะขอสิทธิ์ทั้งหมดในเวลาติดตั้งเช่นเดียวกับในอุปกรณ์ใด ๆ ที่ใช้ระบบปฏิบัติการด้านล่าง Marshmallow หากคุณกำลังลองจำลองจาก Android 6.0 เป็นต้นไปคุณต้องไปที่ settings-> apps-> YOURAPP -> สิทธิ์อย่างชัดเจนและเปลี่ยนการอนุญาตหากคุณได้รับอนุญาต


2
ไม่น่าเชื่อฉันใช้เวลา 2 วันพยายามคิดเรื่องนี้ ทุกครั้งที่ฉันรู้สึกว่าสิ่งต่าง ๆ ทำงานได้อย่างราบรื่นบน Android สิ่งนี้เกิดขึ้น
Jaime Ivan Cervantes

7

น่าแปลกที่หลังจากวางทับ"/"ก่อนที่ฉันnewFileปัญหาของฉันได้รับการแก้ไข ฉันเปลี่ยนสิ่งนี้:

File myFile= new File(Environment.getExternalStorageDirectory() + "newFile");

สำหรับสิ่งนี้:

File myFile= new File(Environment.getExternalStorageDirectory() + "/newFile");

1
ไม่มีอะไรแปลกที่นี่ ด้วยบรรทัดแรกคุณกำลังพยายามสร้างไฟล์ในไดเรกทอรีเดียวกันกับไฟล์ที่มีไดเรกทอรีที่เก็บข้อมูลภายนอกของคุณ เช่น /storage/.../somethingnewfile แทน /storage/.../something/newfile
Stéphane

@ Stéphaneข้อผิดพลาดตัวเองแปลกถ้าคุณดูคำตอบที่หลากหลาย
Darush

3
วิธีที่ถูกต้องในการทำเช่นนี้คือการใช้ไฟล์ (dir, file) cosntructor
Nick Cardoso

@NickCardoso คุณยังสามารถใช้ไฟล์ (ชื่อพา ธ สตริง) ดูเหมือนว่าคุณไม่ได้รับจุดที่นี่ คำถามไม่เกี่ยวกับวิธีใช้คลาส File ช่วงของคำตอบในหัวข้อนี้แสดงให้เห็นว่าการเข้าใจผิดของข้อผิดพลาดนี้เป็นอย่างไรและมีวิธีการแก้ไขที่เป็นไปได้มากมาย ในกรณีของฉันข้อผิดพลาดคือเครื่องหมายทับหายไป บางคนพบว่ามีประโยชน์ แน่ใจว่าคุณสามารถใช้วิธีการเข้าถึงไฟล์ของคุณเอง ไปข้างหน้าและโพสต์คำตอบของคุณ มันอาจช่วยแก้ปัญหาของใครบางคน
Darush

คุณไม่ได้รับจุด หากคุณใช้ Constructor ที่ถูกต้องคุณไม่จำเป็นต้องแฮ็ค ความคิดเห็นของฉันถูกเพิ่มเพื่อช่วยให้ผู้อ่านในอนาคตเข้าใจผิดจากความผิดพลาดของคุณ มันไม่ใช่คำวิจารณ์ส่วนตัวและไม่ต้องการคำตอบ
Nick Cardoso

6

ฉันมีปัญหาเดียวกันและไม่มีข้อเสนอแนะช่วย แต่ผมพบว่าเหตุผลที่น่าสนใจสำหรับว่าในอุปกรณ์ทางกายภาพ, Galaxy Tab

เมื่อเปิดที่เก็บข้อมูล USB ที่เก็บข้อมูลภายนอกการอ่านและเขียนสิทธิ์จะไม่มีผลใด ๆ เพียงปิดที่เก็บข้อมูล USB และด้วยสิทธิ์ที่ถูกต้องคุณจะได้รับการแก้ไขปัญหา


2
ประณามฉันใช้เวลาประมาณ 3 ชั่วโมงในการทำงาน ตามปกติแล้วฉันต้องรีบูตอุปกรณ์และใช้งานได้ ขอบคุณมาก
crgarridos

5

ฉันคาดหวังว่าทุกอย่างด้านล่าง/dataจะเป็นของ "พื้นที่เก็บข้อมูลภายใน" คุณควร /sdcardแต่จะสามารถที่จะเขียนถึง


5
ฉันได้ลองใช้ <การอนุญาต - อนุญาต android: name = "android.permission.WRITE_INTERNAL_STORAGE" /> ด้วย ยังเหมือนเดิม
Mert

1
โดยทั่วไปแล้ว / data-partition จะป้องกันการเขียนสำหรับผู้ใช้ทั่วไป (ที่ไม่ใช่รูท) ที่พยายามเข้าถึงไฟล์ธรรมดา สำหรับที่เก็บข้อมูลภายในมีวิธีการเฉพาะที่จะทำเช่นนั้นโดยเฉพาะถ้าคุณต้องการเข้าถึงฐานข้อมูล Android หน้านักพัฒนาจะช่วยคุณในเรื่องนี้
ovenror

5

เปลี่ยนคุณสมบัติการอนุญาตในของคุณ/system/etc/permission/platform.xml
และกลุ่มจำเป็นต้องกล่าวถึงเช่นเดียวกับด้านล่าง

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
    <group android:gid="sdcard_rw" />
    <group android:gid="media_rw" />    
</uses-permission>

platform.xml ถูกล็อคขวาพยายามผ่านเชลล์ adb แต่ต้องการ ADB สคริปต์ใดก็ได้ที่จะให้ฉันใช้สำหรับ mod
John

ล้มเหลว. นำอุปกรณ์ของฉันเข้าสู่การวนรอบการบูต
Tobse

5

ฉันมีข้อผิดพลาดเดียวกันเมื่อพยายามเขียนภาพในโฟลเดอร์ DCIM / กล้องบน Galaxy S5 (android 6.0.1) และฉันคิดว่ามีเพียงโฟลเดอร์นี้เท่านั้นที่ถูก จำกัด ฉันสามารถเขียนลงใน DCIM / โฟลเดอร์ใดก็ได้ แต่ไม่ใช่ในกล้อง นี่ควรเป็นข้อ จำกัด / การปรับแต่งตามแบรนด์


4

เมื่อแอปพลิเคชันของคุณเป็นของแอปพลิเคชันระบบจะไม่สามารถเข้าถึงการ์ด SD


4

โปรดทราบว่าแม้ว่าคุณจะกำหนดสิทธิ์ที่ถูกต้องทั้งหมดในรายการ: แอปของบุคคลที่สามเท่านั้นที่ได้รับอนุญาตให้เขียนบนการ์ดภายนอกของคุณคือ "ไดเรกทอรีของตนเอง" (เช่น / sdcard / Android / data /) พยายามเขียนถึง ที่อื่น: คุณจะได้รับการยกเว้น: EACCES (การอนุญาตถูกปฏิเสธ)


3

บางทีคำตอบคือ:

บน API> = 23 อุปกรณ์หากคุณติดตั้งแอพ (ไม่ใช่แอพระบบ) คุณควรตรวจสอบสิทธิ์ในการจัดเก็บใน "การตั้งค่า - แอปพลิเคชัน" มีรายการสิทธิ์สำหรับทุกแอปคุณควรตรวจสอบ! ลอง


3

ในกรณีของฉันฉันใช้ ห้องสมุดเลือกไฟล์ที่กลับเส้นทางที่จะจัดเก็บข้อมูลภายนอก /root/แต่มันเริ่มต้นจาก และแม้จะมีการWRITE_EXTERNAL_STORAG E ที่ได้รับอนุญาตที่รันไทม์ฉันยังคงมีข้อผิดพลาดEACCES (ได้รับอนุญาต)
ดังนั้นใช้Environment.getExternalStorageDirectory()เพื่อรับเส้นทางที่ถูกต้องไปยังที่จัดเก็บข้อมูลภายนอก

ตัวอย่าง:
ไม่สามารถเขียนได้: /root/storage/emulated/0/newfile.txt
สามารถเขียนได้: /storage/emulated/0/newfile.txt

boolean externalStorageWritable = isExternalStorageWritable();
File file = new File(filePath);
boolean canWrite = file.canWrite();
boolean isFile = file.isFile();
long usableSpace = file.getUsableSpace();

Log.d(TAG, "externalStorageWritable: " + externalStorageWritable);
Log.d(TAG, "filePath: " + filePath);
Log.d(TAG, "canWrite: " + canWrite);
Log.d(TAG, "isFile: " + isFile);
Log.d(TAG, "usableSpace: " + usableSpace);

/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

เอาท์พุท 1:

externalStorageWritable: true
filePath: /root/storage/emulated/0/newfile.txt
isFile: false
usableSpace: 0

เอาท์พุท 2:

externalStorageWritable: true
filePath: /storage/emulated/0/newfile.txt
isFile: true
usableSpace: 1331007488

ฉันมีปัญหาที่แน่นอนเหมือนกัน การนำrootส่วนออกจากเส้นทางแก้ไขปัญหาของฉันได้
xabush

3
Environment.getExternalStoragePublicDirectory();

เมื่อใช้วิธีที่เลิกใช้แล้วตั้งแต่ Android 29 เป็นต้นไปคุณจะได้รับข้อผิดพลาดเดียวกัน:

java.io.FileNotFoundException: open failed: EACCES (Permission denied)

ความละเอียดที่นี่:

getExternalStoragePublicDirectory เลิกใช้แล้วใน Android Q


3

สำหรับทุกคนที่มาที่นี่จากผลการค้นหาและกำหนดเป้าหมายเป็น Android 10: Android 10 (API 29) จะเปลี่ยนการอนุญาตที่เกี่ยวข้องกับพื้นที่เก็บข้อมูล

ฉันแก้ไขปัญหาเมื่อฉันแทนที่อินสแตนซ์ก่อนหน้าของฉันEnvironment.getExternalStorageDirectory()(ซึ่งเลิกใช้แล้วกับ API 29) ด้วยcontext.getExternalFilesDir(null)ด้วย

สังเกตได้ว่า context.getExternalFilesDir(type)สามารถส่งคืน null ได้หากตำแหน่งที่เก็บไม่พร้อมใช้งานดังนั้นโปรดตรวจสอบว่าเมื่อใดก็ตามที่คุณกำลังตรวจสอบว่าคุณมีสิทธิ์ภายนอก

อ่านเพิ่มเติมที่นี่


2

ฉันกำลังสร้างโฟลเดอร์ภายใต้ / data / ใน init.rc ของฉัน (ล้อเล่นรอบกับ aosp บน Nexus 7) และมีปัญหาตรงนี้

มันกลับกลายเป็นว่าการให้สิทธิ์โฟลเดอร์ rw (666) นั้นไม่เพียงพอและมันต้องเป็น rwx (777) ดังนั้นจึงใช้ได้ทั้งหมด!


2

การบังคับใช้สิทธิ์การจัดเก็บโพสต์ 6.0 สามารถข้ามได้หากคุณมีอุปกรณ์ที่รูทผ่านคำสั่ง adb เหล่านี้:

root@msm8996:/ # getenforce
getenforce
Enforcing
root@msm8996:/ # setenforce 0
setenforce 0
root@msm8996:/ # getenforce
getenforce
Permissive

1

เพิ่มสิทธิ์ในรายการ

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

3
ไม่มีสิทธิ์android.permission.READ_INTERNAL_STORAGE
Ryan R

0

ฉันมีปัญหาเดียวกัน (API> = 23)

วิธีแก้ปัญหาhttps://stackoverflow.com/a/13569364/1729501งานได้สำหรับฉัน แต่ไม่สามารถตัดการเชื่อมต่อแอพเพื่อแก้ไขข้อบกพร่องได้

ทางออกของฉันคือการติดตั้งไดรเวอร์อุปกรณ์ adb ที่เหมาะสมบน Windows ไดรเวอร์ Google USB ไม่ทำงานสำหรับอุปกรณ์ของฉัน

ขั้นตอนที่ 1: ดาวน์โหลดไดรเวอร์ adb สำหรับแบรนด์อุปกรณ์ของคุณ

ขั้นตอนที่ 2: ไปที่ตัวจัดการอุปกรณ์ -> อุปกรณ์อื่น ๆ -> ค้นหารายการที่มีคำว่า "adb" -> เลือกอัปเดตไดรเวอร์ -> ระบุตำแหน่งในขั้นตอนที่ 1



0

เพิ่มการพึ่งพา gradle

implementation 'com.karumi:dexter:4.2.0'

เพิ่มรหัสด้านล่างในกิจกรรมหลักของคุณ

import com.karumi.dexter.Dexter;
import com.karumi.dexter.MultiplePermissionsReport;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.multi.MultiplePermissionsListener;
    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash);

    new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {


                checkMermission();
            }
        }, 4000);
    }

    private void checkMermission(){
        Dexter.withActivity(this)
                .withPermissions(
                        android.Manifest.permission.READ_EXTERNAL_STORAGE,
                        android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        android.Manifest.permission.ACCESS_NETWORK_STATE,
                        Manifest.permission.INTERNET
                ).withListener(new MultiplePermissionsListener() {
            @Override
            public void onPermissionsChecked(MultiplePermissionsReport report) {
                if (report.isAnyPermissionPermanentlyDenied()){
                    checkMermission();
                } else if (report.areAllPermissionsGranted()){
                    // copy some things
                } else {
                    checkMermission();
                }

            }
            @Override
            public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
                token.continuePermissionRequest();
            }
        }).check();
    }

0

ในกรณีของฉันมีข้อผิดพลาดปรากฏบนบรรทัด

      target.createNewFile();

เนื่องจากฉันไม่สามารถสร้างไฟล์ใหม่บนการ์ด sd ได้ดังนั้นฉันจึงต้องใช้วิธีการ DocumentFile

      documentFile.createFile(mime, target.getName());

สำหรับคำถามข้างต้นปัญหาอาจแก้ไขได้ด้วยวิธีนี้

    fos=context.getContentResolver().openOutputStream(documentFile.getUri());

ดูที่หัวข้อนี้ด้วย วิธีใช้ API การเข้าถึงการ์ด SD ใหม่ที่แสดงสำหรับ Android 5.0 (Lollipop)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.