2012-12-13 19 views
7

Galeride açılacak bir ImageView ayarlanmış ve tıklatılabilen bir uygulamam var. Varsayılan olarakDahili bellekte saklanan görüntüleri paylaşma

, benim jpegler saklamak için harici depolama alanındaki bir dosya dizini almak için aşağıdaki kodu kullanın:

File picsDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"MyCameraApp"); 

Ama! Harici depolama biriminin monte edilmediğini veya mevcut olmadığını (Galaxy Nexus) varsayalım, bu işe yaramıyor. Bu yüzden etrafında bir if-cümlesi yazdım ve dahili önbellek dirseği geri dönüş olarak aldım.

String state = Environment.getExternalStorageState() 
if(Environment.MEDIA_MOUNTED.equals(state)){ 
    File picsDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"MyCameraApp");  
}else{ 
    context.getCacheDir(); 
} 

Resimler, ImageView öğesinde düzgün görünüyor, ancak amacım başlatıldığında ortaya çıkmıyor.

Intent intent = new Intent();    
intent.setAction(android.content.Intent.ACTION_VIEW); 
intent.setDataAndType(Uri.fromFile(imgFile), "image/jpeg"); 
startActivity(intent); 

Galeri yüklenir, ancak siyah bir ekran gösterir. Muhtemelen galeri uygulamanızın önbellek dizinindeki dosyalara erişemediği için. Bir alternatif olarak

, ben MediaStore.Images.Media.INTERNAL_CONTENT_URI kullanan medya içeriği sağlayıcısı kullanarak çalıştı, ancak inser görüntüyü çalışırken bu hataya yol açar:

java.lang.UnsupportedOperationException: Writing to internal storage is not supported. 

ne yapmalıyım?

+0

ben niyet ile birlikte bitmap ambalaj deneyebilirsiniz tam olarak sorununuzu çözdü bu şekilde kodunu değiştirebilir? Intent.putExtra ("BitmapImage", bitmap); gibi. Resimlerim genellikle yaklaşık 5 MB. – Maarten

+0

Görüntüleri uygulamanın özel deposunda saklayabilir ve genel olarak bunlara HAZIR OKUYUNUZ. Ancak, google yerleşiklerinin bir kısmı da dahil olmak üzere birçok uygulama bunlara bir yol verildiğinde bunlara erişip erişemeyeceğini kontrol etmekten rahatsız olmaz, ancak Sahip olma başvurusu aslında küresel okuma erişimi sağlasa bile, başaramayacaklarını ve başarısız olduklarını varsayalım. –

cevap

3

burada sorun galerinin bellek özel bir alanda kaydedilen bir dosya ile açık çalışmaktır varsayalım

(getCacheDir o hafıza yoluna erişebilir uygulamanıza ve sadece uygulama göreceli bir yol dönmek) Harici belleğe kaydedemezseniz, genel bir yola kaydetmeye çalışabilirsiniz (ancak bu şekilde medya dosyalarınız her uygulama tarafından yönetilebilir ve uygulamanızı kaldırırsanız, kaydettiğiniz oluşturulmuş ortamı temizlemez).

Özel iç belleği kullanmak isterseniz, ContentProvider

Ben söylediğimi tamamlamak için kullandığım bir içerik sağlayıcısı göndermek için düzenleyin.o

<provider 
     android:name=".contentproviders.MediaContentProvider" 
     android:authorities="com.way.srl.HandyWay.contentproviders.media" > 
    </provider> 

ve sonra benim durumda, tezahür içinde ContentProvider referansı ihtiyaç ardından

public class MediaContentProvider extends ContentProvider { 
private static final String TAG = "MediaContentProvider"; 

// name for the provider class 
public static final String AUTHORITY = "com.way.srl.HandyWay.contentproviders.media"; 

private MediaData _mediaData; 

// UriMatcher used to match against incoming requests 
private UriMatcher _uriMatcher; 

@Override 
public int delete(Uri uri, String selection, String[] selectionArgs) { 
    // TODO Auto-generated method stub 
    return 0; 
} 

@Override 
public String getType(Uri uri) { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public Uri insert(Uri uri, ContentValues values) { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public boolean onCreate() { 
    uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 

    // Add a URI to the matcher which will match against the form 
    // 'content://com.stephendnicholas.gmailattach.provider/*' 
    // and return 1 in the case that the incoming Uri matches this pattern 
    _uriMatcher.addURI(AUTHORITY, "*", 1); 

    return true; 
} 

@Override 
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 
    // TODO Auto-generated method stub 
    return 0; 
} 

@Override 
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { 

    Log.v(TAG, "Called with uri: '" + uri + "'." + uri.getLastPathSegment()); 

    // Check incoming Uri against the matcher 
    switch (_uriMatcher.match(uri)) { 

    // If it returns 1 - then it matches the Uri defined in onCreate 
     case 1: 

      // The desired file name is specified by the last segment of the 
      // path 
      // E.g. 
      // 'content://com.stephendnicholas.gmailattach.provider/Test.txt' 
      // Take this and build the path to the file 
      // String fileLocation = getContext().getCacheDir() + File.separator + uri.getLastPathSegment(); 
      Integer mediaID = Integer.valueOf(uri.getLastPathSegment()); 

      if (_mediaData == null) { 
       _mediaData = new MediaData(); 
      } 
      Media m = _mediaData.get(mediaID); 

      // Create & return a ParcelFileDescriptor pointing to the file 
      // Note: I don't care what mode they ask for - they're only getting 
      // read only 
      ParcelFileDescriptor pfd = ParcelFileDescriptor.open(new File(m.filePath), ParcelFileDescriptor.MODE_READ_ONLY); 
      return pfd; 

      // Otherwise unrecognised Uri 
     default: 
      Log.v(TAG, "Unsupported uri: '" + uri + "'."); 
      throw new FileNotFoundException("Unsupported uri: " + uri.toString()); 
    } 
} 

: bu benim içerik sağlayıcısıdır (ben sadece ihtiyacınız ilgili kısmını yayınlanmıştır) benim durumumda m bu

Intent intent = new Intent(); 
intent.setAction(Intent.ACTION_VIEW); 
intent.setDataAndType(Uri.parse("content://" + MediaContentProvider.AUTHORITY + "/" + m.id), "image/jpg"); 

gibi kullanabilirsiniz _ sqlite db işaret bir id saklamak bir varlıktır ve ben (tekrar nesneyi doldurmak için veri almaya bir sınıf kullanmak mediaData), sadece ihtiyaçlarınızı

uyacak şekilde benim uygulamanın Belki

+0

Bu iyi bir yanıt, ancak Google bu yayından bu yana bir '' FileProvider '' sağladı. İşte bir öğretici: http://developer.android.com/reference/android/support/v4/content/FileProvider.html – DaMachk

0

Bu geri dönüşün gerekli olmadığını anladım. Google Play’e sahip olan cihazların, Environment.getExternalStorageDirectory()’da en az 2 GB’lık olması garanti edilir.

Galaxy Nexus'ta bu, harici olarak işaretlenen dahili bellekte bir bölümdür. Kullanılamıyorsa sadece bir uyarı göstereceğim.

+2

Sıralaması. Galaxy Nexus'un, dahili ve çıkarılmasa bile, kesinlikle "harici depolama" özelliği vardır. Bununla birlikte, çıkarılmış depolama alanına sahip cihazlarda mevcut olmayabilir; ve USB yığın depolama yapan cihazlarda harici bir bilgisayara monte edilirken kullanılamaz. –

İlgili konular