2011-08-12 27 views
12

Tôi đang tạo bộ chọn địa chỉ liên hệ của riêng mình, vì tôi cần hỗ trợ đa lựa chọn. Mọi thứ đều hoạt động tốt, ngoại trừ một vấn đề nhỏ với hình ảnh liên lạc.Làm cách nào để xác minh URI hình ảnh có hiệu lực trong Android?

Đối với những người liên hệ không có hình ảnh, tôi đang hiển thị hình ảnh "không có hình ảnh". Điều này làm việc tốt cho các số liên lạc trong sổ địa chỉ của điện thoại. Tôi đang gặp một vấn đề tuy nhiên khi nói đến hình ảnh từ địa chỉ liên lạc google của tôi.

Hầu hết các địa chỉ liên hệ trên google của tôi không có ảnh. Tuy nhiên, khi tôi truy vấn cơ sở dữ liệu hệ cho hình ảnh, nó vẫn trả về một URI cho họ về hình thức content://com.android.contacts/contacts/657/photo (đó là định dạng tương tự như đối với danh bạ người làm có một bức ảnh.

Sau đó, khi tôi cố gắng để gán ảnh vào QuickContactBadge, sử dụng bdg.setImageURI(pic); nó đặt nó về cơ bản một bức tranh trống, và ghi lại một thông điệp INFO im lặng trong đó nêu:

INFO/System.out(3968): resolveUri failed on bad bitmap uri: 
content://com.android.contacts/contacts/657/photo 

tôi cần phải biết làm thế nào tôi có thể một trong hai
a) xác nhận URI hoặc
b) bắt được thông báo INFO trên
c) truy vấn ImageView/huy hiệu để xem nếu nó tìm thấy một hình ảnh hợp lệ

để tôi có thể gán các địa chỉ liên lạc của tôi "không có hình ảnh" hình ảnh .
Làm cách nào để tôi thực hiện việc này?

EDIT 20110812,0044

Tôi đã thử thêm này để mã của tôi theo đề nghị của Laurence (mà anh ấy kể từ khi bị loại bỏ):

// rv is my URI variable 
if(rv != null) { 
    Drawable d = Drawable.createFromPath(rv.toString()); 
    if (d == null) rv = null; 
} 

Trong khi các điểm tiếp xúc google bây giờ có được tôi "không có hình ảnh" hình ảnh , ... do đó, hãy thực hiện tất cả các địa chỉ liên hệ khác, kể cả những địa chỉ liên hệ do thực tế có hình ảnh.

+0

Bạn có biết nơi những hình ảnh tiếp xúc được lưu trữ trên SDcard/bộ nhớ trong? Có lẽ nếu bạn có thể xác định vị trí thư mục, sau đó lặp qua tất cả các thành viên bạn có thể xác nhận nếu hình ảnh được chọn tồn tại hay không. –

+0

Vâng, URI duy nhất tôi nhận được là U nội dung: //com.android.contacts/... 'URI được đề cập, chỉ đơn giản đề cập đến một trường trong tệp' Contacts2.db' trong kho lưu trữ db. Nhìn vào khung nhìn PHOTOS trong SQLLite Editor, có vẻ như các bức ảnh được lưu trữ trực tiếp trong db dưới dạng dữ liệu nhị phân thô (trường dữ liệu 'không hiển thị đường dẫn, nhưng chỉ hiển thị' (dữ liệu) '). Một trong các địa chỉ liên hệ được đề cập KHÔNG hiển thị '(dữ liệu)' cho ảnh của họ, nhưng hiển thị một trường trống. Có bằng cách nào đó tôi có thể truy vấn URI để xem nếu nó trả về NULL? – eidylon

+0

Câu hỏi thực sự là: tại sao những bản ghi hình ảnh giả được lưu trữ trong cơ sở dữ liệu ở tất cả? – xnagyg

Trả lời

11

OK, tôi đã tìm ra cách thực hiện việc này sau khi xem qua mã nguồn của ImageView. Nó thực sự đang sử dụng các phương thức riêng của QuickContactBadge, nhưng nếu cần thiết, người ta luôn có thể trích xuất the relevant code from the Badge/ImageView control here.

Sau khi thiết lập hình ảnh của QCB, tôi kiểm tra xem nó có thể vẽ được không, thay vì cố gắng của riêng tôi (theo đề xuất của Laurence). Điều này hoạt động tốt hơn, bởi vì thực sự có một loạt kiểm tra mã mà tiện ích ImageView sử dụng.

Đây là mã cuối cùng của tôi:

bdg.setImageURI(pic); 
if(bdg.getDrawable() == null) bdg.setImageResource(R.drawable.contactg); 

này hoạt động hoàn hảo như tôi đã hy vọng và mong đợi.

+0

Điều này là tốt, nhưng nếu bạn sử dụng Bộ điều hợp, bạn không thể kiểm tra theo cách này. Vì vậy, bạn nên kiểm tra uri trước – xnagyg

+0

điều này thực sự là xấu, đặc biệt là khi ở chế độ xem lưới hoặc danh sách. – Olayinka

+0

@Olayinka - chăm sóc để giải thích thêm một chút và thêm vào cuộc trò chuyện? "Thật tệ." không thực sự giải thích nhiều. Làm thế nào nó nên được thực hiện sau đó? – eidylon

3

Chỉ cần để trả lời những câu hỏi về cách kiểm tra (dữ liệu) giá trị trong MediaStore:

ContentResolver cr = getContentResolver(); 
String[] projection = {MediaStore.MediaColumns.DATA} 
Cursor cur = cr.query(Uri.parse(contentUri), projection, null, null, null); 
if(cur != null) { 
    cur.moveToFirst(); 
    String filePath = cur.getString(0); 

    if (filePath == null || filePath.isEmpty()) { 
     // data not set 
    } else if((new File(filePath)).exists()){ 
     // do something if it exists 
    } else { 
     // File was not found 
     // this is binary data 
    } 
} else { 
    // content Uri was invalid or some other error occurred 
} 

Inspiration lấy từ: https://stackoverflow.com/a/7649784/621690 và những người khác.

Ngoài ra còn có cột SIZE có thể được kiểm tra: http://developer.android.com/reference/android/provider/MediaStore.MediaColumns.html#SIZE Có vẻ như nó phải chứa 0 nếu không có giá trị dữ liệu. Nhưng tôi sẽ không biết nó chứa gì nếu dữ liệu là một đường dẫn tập tin.

0

Dựa trên mã (http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/widget/ImageView.java) giải pháp của tôi để kiểm tra Uri:

public static Uri checkUriExists (Context mContext,Uri mUri) { 
    Drawable d = null; 
    if (mUri != null) { 
     if ("content".equals(mUri.getScheme())) { 
      try { 
       d = Drawable.createFromStream(
         mContext.getContentResolver().openInputStream(mUri), 
         null); 
      } catch (Exception e) { 
       Log.w("checkUriExists", "Unable to open content: " + mUri, e); 
       mUri = null; 
      } 
     } else { 
      d = Drawable.createFromPath(mUri.toString()); 
     } 

     if (d == null) { 
      // Invalid uri 
      mUri = null; 
     } 
    } 

    return mUri; 
} 
1

Có thể là những hình ảnh không được tải về. Tôi phải đối mặt với một vấn đề tương tự với hình ảnh whatsapp. Một cách để đi về vấn đề này có thể giống như dưới đây:

InputStream is = null; 
try { 
    is = context.getContentResolver().openInputStream(myuri); 
}catch (Exception e){ 
    Log.d("TAG", "Exception " + e); 
} 

if(is==null) 
    //Assign to "no image" 
0

Tôi đang sử dụng mã này cho Uri có file: // quyền

Uri resimUri = Uri.parse(path_str); 
File imgFile = new File(resimUri.getPath()); 
if (imgFile.exists()) { 
    // file exists 
}else { 
    // file is not there 
} 
Các vấn đề liên quan