2012-01-26 17 views
19

Moja aplikacja generuje obrazy, które użytkownik może zapisać lub udostępnić innym osobom. Poniższy kod działa w przypadku większości aplikacji: Messenger, Facebook, Dropbox, e-mail itp. Oznacza to, że obraz jest ładowany przez wybraną aplikację, a użytkownik może z powodzeniem udostępnić obraz tej aplikacji.Udostępnianie zdjęcia w aplikacji Google+ przy użyciu funkcji Intent.ACTION_SEND i Intent.EXTRA_STREAM

Intent intent = new Intent(Intent.ACTION_SEND); 
intent.setType("image/png"); 
File o = new File(dir, "file.png"); 
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(o)); 
startActivity(Intent.createChooser(intent , "Send options")); 

Po wybraniu aplikacji Google+ na liście aplikacji uruchamiany jest program Google +, ale obraz nie jest wyświetlany w oknie wiadomości. Zamiast google + wyświetla komunikat tosty z:

"You can only post photos stored on your device." 

To jest trochę mylące, ponieważ obraz jest na zewnętrznej karcie SD, tj /mnt/sdcard/AppDir/file.png. Korzystam z najnowszej aktualizacji aplikacji Google+ (2.3.1.242969).

Czy jest jeszcze jedna sztuczka dzielenia się obrazem z Google +?

Dziękuję.

UPDATE:

Moja aplikacja generuje obrazy, które są wspólne, więc próbka poniżej z @ Chirag-Shah nie był bezpośrednio dotyczy. Ale korzystanie z MediaStore wygląda na właściwy pomysł. Oparłem się na podstawowym kodzie poniżej:

void shareImage(int position) { 
    File f = getFileFor(position); 
    ContentValues values = new ContentValues(2); 
    values.put(MediaStore.Images.Media.MIME_TYPE, "image/png"); 
    values.put(MediaStore.Images.Media.DATA, f.getAbsolutePath()); 
    Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); 
    Intent intent = new Intent(Intent.ACTION_SEND); 
    intent.setType("image/png"); 
    intent.putExtra(Intent.EXTRA_STREAM, uri); 
    startActivity(Intent.createChooser(intent , "Send options")); 
} 

Działa z Google+ i wszystkimi innymi aplikacjami, z którymi testowałem. Pozostawiam pytanie otwarte na wypadek, gdyby nie była to najlepsza praktyka. Czy ktoś może potwierdzić, że jest to właściwy sposób?

Odpowiedz

9

Świetny połów! Możesz określić MediaStore Uri (który wygląda jak zawartość: // media/external/images/media/42) zamiast bezwzględnej ścieżki w systemie plików.

Przykład:

public class MyActivity extends Activity { 
    ... 
    static final int IMAGE_REQUEST = 0; 

    protected void pickImage() { 
    Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
    startActivityForResult(intent, IMAGE_REQUEST); 
    } 

    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if (requestCode == IMAGE_REQUEST) { 
     Uri uri = data.getData(); 

     Intent intent = new Intent(Intent.ACTION_SEND); 
     intent.setType("image/png"); 
     // uri looks like content://media/external/images/media/42 
     intent.putExtra(Intent.EXTRA_STREAM, uri); 
     startActivity(Intent.createChooser(intent , "Share")); 
    } 
    } 
} 
+0

Dziękuję za tę wskazówkę. Korzystanie z Media Store wygląda jak właściwa droga, a twój post dał mi ten pomysł. –

2

Powodem otrzymujesz ten błąd jest ze względu „na karcie SD” nie jest „na urządzeniu”.

dyskusja na ten temat można znaleźć tutaj: https://groups.google.com/a/googleproductforums.com/forum/#!topic/google-plus-discuss/pdlOTM8JEXg/discussion

Obejście przez Mediastore wydaje się być jedynym rozwiązaniem, dopóki Google aktualizuje aplikację Google+ z poprawką.

Aktualizacja: powyższe rozwiązanie działa tylko wtedy, gdy zdjęcie ma zostać udostępnione jednorazowo. Jeśli wywołasz ContentResolver.insert (...) wiele razy, skończy się obrazem wyświetlanym wiele razy w twojej galerii. I wymyślił następujące rozwiązanie, które próbuje się istniejący identyfikator obrazu, a jeśli jej nie ma, można go wstawić ...

Cursor c = getActivity().getContentResolver() 
      .query(Images.Media.EXTERNAL_CONTENT_URI, 
        null, 
        Images.Media.DATA + "=?", 
        new String[] { filePath }, null); 
    if (c.getCount() > 0 && c.moveToFirst()) { 
     Uri shareUri = Uri.withAppendedPath(
       Images.Media.EXTERNAL_CONTENT_URI, 
       "" 
         + c.getInt(c 
           .getColumnIndex(Images.Media._ID))); 
     c.close(); 

     startActivity(Intent.createChooser(
       new Intent(Intent.ACTION_SEND) 
         .putExtra(Intent.EXTRA_STREAM, 
           shareUri).setType(
            "image/*"), "")); 
    } else { 
    // ContentResolver.insert(...) and use that uri... 
    } 
+0

Wydaje się, że nie zawsze działa: http: // stackoverflow.com/questions/23324485/android-mediastore-cant-get-insert-image-data –

3

Dzięki za podniesienie na to pytanie!

Wygląda na to, że Google+ akceptuje tylko nośniki od dostawców treści (content: // uris), a nie file: // uris. Dlatego najpierw musimy umieścić obraz w MediaStore. Łatwiejszy sposób to:

MediaStore.Images.Media.insertImage(context.getContentResolver(), tmpFile.getAbsolutePath(), tmpFile.getName(), null); 
Powiązane problemy