2012-03-30 27 views
14

我打電話意圖分享圖像。這適用於大多數提供商,但與Google+。 Google+會在沒有圖片的情況下打開帖子活動,並顯示「您只能發佈存儲在您設備上的照片」。與此同時。分享Google+的意圖無法訪問圖像

File f = storeImage(image); // f = /data/data/com.myapp/files/1333070776978.jpg 
    Uri uri = Uri.fromFile(f); 

    Intent share = new Intent(Intent.ACTION_SEND); 
    share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 
    share.setType("image/jpeg"); 
    share.putExtra(Intent.EXTRA_STREAM, uri); 
    share.putExtra(Intent.EXTRA_TITLE,"Share that title"); 
    share.putExtra(Intent.EXTRA_SUBJECT,"Share that subject"); 
    share.putExtra(Intent.EXTRA_TEXT,"Check that out..."); 
    share.putExtra("sms_body", "sms body"); 
    startActivity(Intent.createChooser(share, "Share Image")); 

我保存圖像與

Context.openFileOutput(fileName, Context.MODE_WORLD_READABLE); 

我的理解是,通過設置FLAG_GRANT_READ_URI_PERMISSION,我給Google+的這個文件具體的訪問。

它工作時,我將圖像存儲到MediaStore,但我其實不想混亂用戶圖像庫。

ContentValues values = new ContentValues(2); 
    values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); 
    values.put(MediaStore.Images.Media.DATA, f.getAbsolutePath()); 
    Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); 

任何建議表示讚賞

西蒙

+0

你總是可以檢查什麼權限的文件和文件夾的擁有,尋找到使用調試工具在Eclipse中的文件系統。只是爲了確保你沒有缺乏權限。 – erbsman 2012-03-30 10:24:28

+0

文件權限看起來不錯(-rw-rw-r--)。無論如何,其他應用程序,如短信應用程序或Facebook可以訪問和共享圖像就好了。 – SimonSays 2012-03-30 18:14:57

+0

如果使用Context.getCacheDir()將圖像存儲在緩存目錄中,該怎麼辦? – Freddroid 2012-03-31 17:17:00

回答

6

Google+不能從另一個應用程序的私人文件夾訪問file:// Uris。並且FLAG_GRANT_READ_URI_PERMISSION在這種情況下不起作用,因爲它僅適用於意向的「數據」部分中的Uris,但不適用於額外配置。

一個常見的解決方法是將其添加到畫廊(通過MediaStore),但沒有必要這樣做。在這種情況下,正確的解決辦法是使用FileProvider

FileProvider是ContentProvider的一個特殊的子類,通過一個文件而不是file:///烏里創建 content://烏里利於 與應用程序相關的文件安全共享。

首先將以下內容放置在您的AndroidManifest中。XML

<provider 
    android:name="android.support.v4.content.FileProvider" 
    android:authorities="com.myapp.testshare.fileprovider" 
    android:grantUriPermissions="true" 
    android:exported="false"> 
    <meta-data 
     android:name="android.support.FILE_PROVIDER_PATHS" 
     android:resource="@xml/filepaths" /> 
</provider> 

那麼這個文件中res\xml\filepaths.xml

<?xml version="1.0" encoding="utf-8"?> 
<paths> 
    <files-path name="shared_images" path="shared_images/" /> 
</paths> 

然後,共享圖像文件時,請確保它在上面指定的路徑(即getFilesDir()shared_images)和建立的意圖如下:

File file = getImageFileToShare(); 
Uri fileUri = FileProvider.getUriForFile(this, "com.myapp.testshare.fileprovider", file); 

Intent intent = new Intent(Intent.ACTION_SEND); 
intent.putExtra(Intent.EXTRA_STREAM, fileUri); 
intent.setType("image/png"); 
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 

startActivity(intent); 

(確保在getUriForFile()法規定的權力相匹配的在清單)。

這將產生content:// Uri(例如content://com.myapp.testshare.fileprovider/shared_images/img1.png,Google+應用將能夠訪問,因此包括在帖子中)。

+0

哇,這看起來像一個很好的解決方案。現在真的驗證了這一點,但我認爲你已經做到了這一點,它的工作原理,所以我將它標記爲解決方案。謝謝你,我等了2年這個:-) – SimonSays 2014-06-02 17:23:17

+0

我想分享從Unity UnityGame的屏幕截圖我是將圖像捕獲到「data/data/com.mypackage.name/files/ScreenShot.png」。我遵循相同的程序,但我得到NullPointerException。你可以分享Sample項目嗎? – Prasanna 2014-07-25 11:46:26

+1

多好的答案。我已經測試過它,它完美地工作。唯一的挑戰是將文件複製到'shared_images'文件夾,我使用此代碼的幫助:http://stackoverflow.com/a/11327789/1617737 – 2015-01-29 13:13:24

2

西蒙,

好像它的工作原理設置的URI後設置的權限。

share.putExtra(Intent.EXTRA_STREAM, uri); 
share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 
+1

nope,這也不起作用... – SimonSays 2012-04-01 21:14:05

+1

達恩。也沒有爲我工作 – Doug 2012-04-29 17:11:25

+0

我正在使用自定義的ContentProvider共享從我的緩存中的圖像目錄下添加這個標記* finally *允許我在google +中附加圖片,而不必求助於將文件複製到圖片庫。 – Mark 2012-09-05 13:47:12

1

如果您使用的是自定義ContentProvider,則必須檢查圖像的MIME類型是否正確。 jpeg的正確MIME是「image/jpeg」。如果您在重寫的getType(Uri uri)中返回「image/jpg」;方法,那麼Google+無法附加它們。其他大部分工作,例如消息和電子郵件。 「圖像/ JPG」不是一個有效的IANA MIME類型:

http://www.iana.org/assignments/media-types/image

的getType的規格是清楚這一點,但它是很容易錯過(我做了)。解決了這個問題之後,我想確保其他人發現這個問題,因爲它非常不方便。

0

您可以使用此:

Drawable drawable; 
File file; 
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) { 
    drawable = getResources().getDrawable(imgResId); 
} else { 
    drawable = getResources().getDrawable(imgResId, null); 
} 

if (drawable != null) { 
    Bitmap bm = ((BitmapDrawable) drawable).getBitmap(); 

    String path = Environment.getExternalStorageDirectory() 
      .toString(); 
    OutputStream fOut = null; 
    file = new File(path, "pic.jpg"); // the File to save to 
    try { 
     file.createNewFile(); 
     fOut = new FileOutputStream(file); 

     // obtaining the Bitmap 
     bm.compress(Bitmap.CompressFormat.JPEG, 100, fOut); 
     fOut.flush(); 
     fOut.close(); 
     return file; 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
}