2014-04-21 18 views
5

Tôi đang sử dụng DownloadManager để tải hình ảnh xuống thư viện của hệ thống và sau đó trong Bộ thu phát sóng (khi tải xuống thành công) bằng Intent để đặt hình ảnh làm hình nền.Nhận URI nội dung từ URI tệp?

Mọi thứ đều hoạt động tốt nhưng sau đó gần đây trên 4.4 tôi bắt đầu có ngoại lệ trong ứng dụng Ảnh/Google + vì ứng dụng mong đợi URI nội dung chứ không phải URI tệp.

Vì vậy, câu hỏi của tôi là nếu có ai biết cách chuyển đổi đường dẫn tệp/URI đầy đủ (tệp: //) thành URI kiểu nội dung (content: //)?

Xin lỗi vì thiếu mã nguồn, tôi rời khỏi máy tính có nguồn, nhưng tôi hy vọng câu hỏi có ý nghĩa mà không có nó, lấy uri kiểu nội dung từ một đường dẫn đầy đủ.

EDIT:

Những hình ảnh được sao chép vào thư viện hoặc media gallery của hệ thống, không được lưu trong ứng dụng của tôi storeage nội bộ.

Dưới đây là một ví dụ về những gì tôi muốn chuyển đổi:

file:///storage/emulated/0/Pictures/Rockstar/image.jpg 

để

content://media/internal/images/media/445 

EDIT 2:

Đây là lỗi mà tôi nhận được từ ứng dụng Google+ :

04-21 10:50:35.090: E/AndroidRuntime(7220): FATAL EXCEPTION: main 
04-21 10:50:35.090: E/AndroidRuntime(7220): Process: com.google.android.apps.plus, PID: 7220 
04-21 10:50:35.090: E/AndroidRuntime(7220): java.lang.RuntimeException: Unable to resume activity 
{com.google.android.apps.plus/com.google.android.apps.photos.phone.SetWallpaperActivity}: 
java.lang.IllegalArgumentException: Image URI must be of the content scheme type 

Đây là mã mà tôi sử dụng để cho phép người dùng thiết lập các hình nền:

String uriString = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)); 
Uri u = Uri.parse(uriString); 
Intent wall_intent = new Intent(Intent.ACTION_ATTACH_DATA); 
wall_intent.setDataAndType(u, "image/*"); 
wall_intent.putExtra("mimeType", "image/*"); 
Intent chooserIntent = Intent.createChooser(wall_intent, 
    "Set As"); 
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
try { 
    context.startActivity(chooserIntent); 
} 

đâu uriString là:

file:///storage/emulated/0/Pictures/Rockstar/image.jpg 
+0

thx cho bạn post – NickUnuchek

Trả lời

4

Tôi đã có thể tìm ra. Đó là sự kết hợp của mã được tìm thấy ở đây: Converting android image URI và quét tệp phương tiện sau khi tải xuống.

Vì vậy, sau khi các tập tin hoàn tất tải tôi nhận được đường dẫn và làm như sau:

String uriString = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)); 

//Update the System 
Uri u = Uri.parse(uriString);      
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, u)); 

//Get the abs path using a file, this is important   
File wallpaper_file = new File(u.getPath()); 
Uri contentURI = getImageContentUri(context, wallpaper_file.getAbsolutePath()); 

Đối với một số lý do bắt đầu quét phương tiện truyền thông, newing tập tin, và nhận được đường dẫn tuyệt đối là rất quan trọng, tôi không chắc chắn tại sao nhưng tôi không thể dành thêm thời gian cho việc này nữa!

Cách để chuyển đổi từ một file URI đến một nội dung URI được như sau (trích từ bài luồng StackOver liên kết:.

public static Uri getImageContentUri(Context context, String absPath) { 
    Log.v(TAG, "getImageContentUri: " + absPath); 

    Cursor cursor = context.getContentResolver().query(
     MediaStore.Images.Media.EXTERNAL_CONTENT_URI 
     , new String[] { MediaStore.Images.Media._ID } 
     , MediaStore.Images.Media.DATA + "=? " 
     , new String[] { absPath }, null); 

    if (cursor != null && cursor.moveToFirst()) { 
     int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID)); 
     return Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI , Integer.toString(id)); 

    } else if (!absPath.isEmpty()) { 
     ContentValues values = new ContentValues(); 
     values.put(MediaStore.Images.Media.DATA, absPath); 
     return context.getContentResolver().insert(
      MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); 
    } else { 
     return null; 
    } 
} 

Có lẽ điều này sẽ giúp một người nào đó trong tương lai

+0

c ở đây là gì? Tôi có nghĩa là whats defination của con trỏ này. – user4057066

1

Vì vậy, câu hỏi của tôi là nếu có ai biết làm thế nào để chuyển đổi một tập tin đầy đủ path/URI (file: //) vào URI kiểu nội dung (content: //)?

Triển khai ContentProvider. FileProvider cung cấp giải pháp out-of-the-box để phục vụ các tệp cục bộ.

+0

Tôi đang tải hình ảnh (sử dụng trình quản lý tải xuống) xuống thư viện phương tiện của hệ thống và không lưu trữ các tệp trong bộ nhớ trong của ứng dụng của tôi. file: ///sdcard/media/images/myimage.png và tôi muốn chuyển sang: content: // media/internal/images/media/445 – selsine

1

Tôi không chắc chắn về kỹ thuật bạn đang sử dụng để đặt hình nền nhưng cách dễ nhất có thể là sử dụng WallpaperManager.setStream() không yêu cầu bất kỳ URI nào.

Cũng lưu ý rằng URI tệp chỉ hoạt động giữa các ứng dụng nếu tệp có thể truy cập công khai để URI nội dung là giải pháp tổng quát hơn.

Sử dụng URI nội dung ngụ ý rằng ContentProvider sẽ phân phối tệp. Cái nào phụ thuộc vào vị trí tệp của bạn.

Nếu ứng dụng của bạn có quyền truy cập đọc trực tiếp vào tệp, bạn có thể triển khai nhà cung cấp nội dung trong ứng dụng của mình bằng cách sử dụng lớp FileProvider của thư viện hỗ trợ, nhưng điều này chỉ thực sự được sử dụng nếu tệp được đặt lưu trữ dữ liệu riêng tư của ứng dụng của bạn.

Nếu hình ảnh được thêm vào thư viện phương tiện hệ thống, có thể bạn nên sử dụng URI do MediaStore cung cấp.

+0

Có, tập tin được tải xuống vào thư viện phương tiện của hệ thống (sử dụng trình quản lý tải xuống), nhưng tất cả những gì tôi có quyền truy cập vào bộ thu phát qua cột DownloadManager.COLUMN_LOCAL_URI là đường dẫn đầy đủ đến tệp. Làm cách nào để có được URI từ MediaStore dựa trên đường dẫn đầy đủ đó? Ngoài ra tôi đang sử dụng ý định và URI để ứng dụng Thư viện hoặc Ảnh có thể cắt hình ảnh. – selsine

+0

Tôi chưa thử bản thân, nhưng hãy xem cột [DownloadManager.COLUMN_MEDIAPROVIDER_URI] (http://developer.android.com/reference/android/app/DownloadManager.html#COLUMN_MEDIAPROVIDER_URI) và kiểm tra xem nó có chứa nội dung không URI sau khi tải xuống hoàn tất. Nếu nó có vẻ quá phức tạp, bạn vẫn có thể triển khai nhà cung cấp nội dung của riêng bạn, nhưng nó cảm thấy như một hack với tôi. – BladeCoder

+0

Tôi đã thử rằng ngày hôm qua và nó trả về NULL đáng buồn. – selsine

Các vấn đề liên quan