2017-12-13 100 views
5

tôi không thể lưu một tập tin hình ảnh trong oreo android (8,0) api 26.
Mã này được làm việc một cách hoàn hảo trong mức api 25 (7.0) và tôi đã không tìm thấy bất kỳ thay đổi trong tài liệu "Android 8.0 Behavior Changes"Không thể lưu tệp hình ảnh trong bản cập nhật Android oreo. Làm thế nào để làm nó?

Đây là mã của tôi

String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString(); 
File myrootDir = new File(root); 
if (!myrootDir.exists()) { 
    myrootDir.mkdir(); 
} 

File myDir = new File(root + "/Myimages"); 
if (!myDir.exists()) { 
    myDir.mkdir(); 
} 
final String fname = System.currentTimeMillis()+"myimage.png"; 
File file = new File(myDir, fname); 
if (file.exists()) 
    file.delete(); 
try { 
    FileOutputStream out = new FileOutputStream(file); 
    b.compress(Bitmap.CompressFormat.PNG, 100, out); 
    out.flush(); 
    out.close(); 
}catch (Exception e){ 
    Log.e("MYAPP", "exception", e); 
} 

Ngoại lệ là FileNotFoundException, Không có tệp hoặc thư mục nào. (Nhưng Tại sao không ở android n?)

java.io.FileNotFoundException: /storage/emulated/0/Pictures/Myimages/1513151272243myimage.png (No such file or directory) 
12-13 13:17:52.243 5839-5839/com.package.package W/System.err:  at java.io.FileOutputStream.open0(Native Method) 
12-13 13:17:52.243 5839-5839/com.package.package W/System.err:  at java.io.FileOutputStream.open(FileOutputStream.java:287) 
12-13 13:17:52.243 5839-5839/com.package.package W/System.err:  at java.io.FileOutputStream.<init>(FileOutputStream.java:223) 
12-13 13:17:52.243 5839-5839/com.package.package W/System.err:  at java.io.FileOutputStream.<init>(FileOutputStream.java:171) 
12-13 13:17:52.243 5839-5839/com.package.package W/System.err:  at com.package.package.DetailPage$12.run(DetailPage.java:737) 
12-13 13:17:52.244 5839-5839/com.package.package W/System.err:  at android.os.Handler.handleCallback(Handler.java:789) 
12-13 13:17:52.244 5839-5839/com.package.package W/System.err:  at android.os.Handler.dispatchMessage(Handler.java:98) 
12-13 13:17:52.244 5839-5839/com.package.package W/System.err:  at android.os.Looper.loop(Looper.java:164) 
12-13 13:17:52.244 5839-5839/com.package.package W/System.err:  at android.app.ActivityThread.main(ActivityThread.java:6541) 
12-13 13:17:52.244 5839-5839/com.package.package W/System.err:  at java.lang.reflect.Method.invoke(Native Method) 
12-13 13:17:52.244 5839-5839/com.package.package W/System.err:  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
12-13 13:17:52.244 5839-5839/com.package.package W/System.err:  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 
+2

Bạn có ngoại lệ nào không? Vui lòng đăng nó ở đây – Rinav

+3

Oohh Tôi thấy bạn có một khối catch trống, Vui lòng thêm một số đăng nhập vào khối catch. Thực hành tốt nhất, ** không bao giờ để trống khối catch. Luôn xử lý nó ** – Rinav

+1

tôi có thể lưu hình ảnh bằng mã này trong android n. nhưng trong android o, nop :( –

Trả lời

5

Có, trên thực tế, một chút, thay đổi tinh tế trong Quyền cho các ứng dụng chạy trên và nhắm mục tiêu API 26.

Trước đây, các ứng dụng được tự động cấp tất cả các quyền trong một nhóm nhất định nếu ít nhất một quyền trong nhóm đó đã được người dùng cấp. Điều này có nghĩa là một ứng dụng đã được cấp READ_EXTERNAL_STORAGE cũng sẽ có ngay WRITE_EXTERNAL_STORAGE ngay cả khi được yêu cầu rõ ràng là WRITE_EXTERNAL_STORAGE.

Kể từ Oreo, đối với ứng dụng nhắm mục tiêu API 26+, điều này đã được sửa chữa và chỉ những quyền được yêu cầu rõ ràng mới được cấp. Nếu người dùng đã cấp quyền trong cùng một nhóm, thì sẽ không có lời nhắc cho quyền mới nhưng vẫn phải được yêu cầu.

Đó là vấn đề, trong trường hợp này. Khi sự cho phép của READ_EXTERNAL_STORAGE được cấp cho ứng dụng của bạn trên Nougat trở xuống, bạn cũng sẽ tự động nhận được WRITE_EXTERNAL_STORAGE mà không phải yêu cầu cụ thể. Khi bạn thử cùng một thủ tục lưu tệp trong Oreo, bạn không tự động nhận được WRITE_EXTERNAL_STORAGE, vì vậy việc ghi cuối cùng không thành công.

Chỉ cần thêm yêu cầu cụ thể cho WRITE_EXTERNAL_STORAGE. Nếu người dùng đã cấp READ_EXTERNAL_STORAGE, họ sẽ không bị làm phiền với lời nhắc khác. Ngoài ra, bạn chỉ có thể yêu cầu WRITE_EXTERNAL_STORAGE ngay từ đầu, trong đó ngầm bao gồm READ_EXTERNAL_STORAGE và sẽ giúp bạn tiết kiệm được hai yêu cầu riêng biệt.

+1

Cảm ơn bạn rất nhiều :) –

1

Tôi cũng gặp sự cố tương tự và tôi bị kẹt với vấn đề này từ 2 tháng. Tôi đã cho phép WRITE_EXTERNAL_STORAGE trong tệp kê khai đầu tiên và cũng kiểm tra lại là nó có quyền ghi. Tôi nghĩ rằng nó không phải là một vấn đề cho phép. Bởi vì khi tôi thử nghiệm với oreo thư mục đang tạo và có một tệp hình ảnh bị hỏng trong thư mục tôi đang tạo. Bởi vì nó không phải là đến thư viện và sau đó lưu nó trả về cho tôi Hình ảnh không bị bắt. Tôi nhận được vấn đề này chỉ trong Android 7.1.1 và oreo. Upto android 7.0 nó hoạt động tốt. Tôi đã kiểm tra với các thiết bị samsung galaxy note 8 và google điểm ảnh xl 2. Tôi đang sử dụng một máy ảnh tùy chỉnh với với gps và dưới chức năng

public void onImageAvailable(ImageReader reader) { 
        Image image = null; 
        try { 
         image = reader.acquireLatestImage(); 
         ByteBuffer buffer = image.getPlanes()[0].getBuffer(); 
         byte[] bytes = new byte[buffer.capacity()]; 
         buffer.get(bytes); 
         save(bytes); 

cho byte hình ảnh tiết kiệm và tiết kiệm năng chứa mã dưới đây

OutputStream output = null; 
        try { 
         output = new FileOutputStream(finalFile); 
         output.write(bytes); 
        } finally { 
         if (null != output) { 
          output.close(); 
         } 
        } 
Các vấn đề liên quan