2013-06-13 31 views
10

我正在開發一個Android應用程序,該應用程序是一個圖像庫,其中圖像從互聯網上下載並顯示在smathphone的屏幕上。圖像一次顯示一個,應用程序有一個按鈕可共享顯示的圖像。在Android應用程序中與內容提供商共享圖像

按照我在某些StackOverflow文章中發現的指示,指出共享圖像的正確方式是使用ContentProvider我實現了以下代碼,用於共享某些應用程序(例如Twitter,Gmail)的圖像。 ..)但不適用於其他人(Facebook,Yahoo,MMS ...)。

然後我顯示了所用的代碼,希望您可以幫助我正確實現在所有應用程序中共享圖像。

最初我捕捉按鈕按下共享:

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 

    if (item.getItemId() == R.id.menu_share) { 

     // I get the image being displayed on the screen 
     View root = getView(); 
     ImageView imageView = (ImageView) root.findViewById(R.id.image); 
     Drawable imageToShareDrawable = imageView.getDrawable(); 

     if (imageToShareDrawable instanceof BitmapDrawable) { 

      // I convert the image to Bitmap 
      Bitmap imageToShare = ((BitmapDrawable) imageToShareDrawable).getBitmap(); 

      // Name of de image extracted from a bean property 
      String fileName = quote.getImage(); 

      // I keep the image in the folder "files" of internal storage application 
      TempInternalStorage.createCachedFile(fileName, imageToShare, getActivity().getApplicationContext()); 

      // I start the Activity to select the application to share the image after the intent Built with the method "getDefaultShareIntent" 
      startActivity(getDefaultShareIntent(fileName)); 
     } else { 
      Toast.makeText(getActivity().getApplicationContext(), "Please wait, the quote is being downloaded", Toast.LENGTH_SHORT).show(); 
     } 
    } 

    return true; 
} 

用於將圖像保存到應用程序的內部存儲器中的方法如下:

public static void createCachedFile(String fileName, Bitmap image, Context context) { 

    try { 
     File file = new File(context.getFilesDir(), fileName); 

     if (!file.exists()) { 
      FileOutputStream fos = new FileOutputStream(file); 
      image.compress(Bitmap.CompressFormat.JPEG, 100, fos); 
      fos.flush(); 
      fos.close(); 
     } 
    } catch (Exception e) { 
     Log.e("saveTempFile()", "**** Error"); 
    } 
} 

該構造意圖的方法分享它:

private Intent getDefaultShareIntent(String fileName) { 
    final Intent shareIntent = new Intent(); 
    shareIntent.setAction(Intent.ACTION_SEND); 
    shareIntent.setType("image/jpeg"); 
    shareIntent.putExtra(Intent.EXTRA_TEXT, "Test text"); 
    shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" + CachedFileProvider.AUTHORITY + File.separator + "img" + File.separator + fileName)); 
    shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 

    return shareIntent; 
} 

最後ContentProvider代碼如下:

public class CachedFileProvider extends ContentProvider { 

private static final String CLASS_NAME = "CachedFileProvider"; 

public static final String AUTHORITY = "com.example.appname.cachefileprovider"; 

private UriMatcher uriMatcher; 

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

    uriMatcher.addURI(AUTHORITY, "img/*", 1); 

    return true; 
} 

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

    String LOG_TAG = CLASS_NAME + " - openFile"; 

    Log.i(LOG_TAG, "Called with uri: '" + uri + "'." + uri.getLastPathSegment()); 

    switch (uriMatcher.match(uri)) { 

    case 1: 

     String fileLocation = getContext().getFilesDir() + File.separator + uri.getLastPathSegment(); 

     ParcelFileDescriptor image = ParcelFileDescriptor.open(new File(fileLocation), ParcelFileDescriptor.MODE_READ_ONLY); 

     return image; 

    default: 
     Log.i(LOG_TAG, "Unsupported uri: '" + uri + "'."); 
     throw new FileNotFoundException("Unsupported uri: " + uri.toString()); 
    } 
} 

@Override 
public int update(Uri uri, ContentValues contentvalues, String s, String[] as) { 
    return 0; 
} 

@Override 
public int delete(Uri uri, String s, String[] as) { 
    return 0; 
} 

@Override 
public Uri insert(Uri uri, ContentValues contentvalues) { 
    return null; 
} 

@Override 
public String getType(Uri uri) { 
    return null; 
} 

@Override 
public Cursor query(Uri uri, String[] projection, String s, String[] as1, String s1) { 

    MatrixCursor c = null; 

    Log.i(">>>> projection", java.util.Arrays.toString(projection)); 

    String fileLocation = getContext().getFilesDir() + File.separator + uri.getLastPathSegment(); 

    File file = new File(fileLocation); 

    long time = System.currentTimeMillis(); 

    c = new MatrixCursor(new String[] { "_id", "_data", "orientation", "mime_type", "datetaken", "_display_name" }); 

    c.addRow(new Object[] { 0, file, 0, "image/jpeg", time, uri.getLastPathSegment() }); 

    return c; 
} 

@Override 
public String[] getStreamTypes(Uri uri, String mimeTypeFilter) { 
    return null; 
} 

}

我發現,當圖像被共享一些應用程序只調用方法「查詢」(這是哪裏的代碼不能正常工作,我不能將影像分享的),而有其他人也稱爲「查詢」的方法也稱爲「openFile」方法,這些工作,我可以分享圖像。

我希望你能幫助我,非常感謝你提前。

+0

您是否找到解決方案?順便說一句,這個鏈接可能會讓你感興趣:https://github.com/xperimental/BinaryContent – rekire

+0

你成功地分享了你的圖像嗎?你能幫我嗎?我怎樣才能從可繪製文件夾共享圖像? – Erum

+1

@Mike你可以分享一下你的代碼中的錯誤嗎? – Erum

回答

0

作爲@孫寧的評論指出,一些「共享目標應用程序」可以處理您已經實施的以「content:// ..」開頭的URI-s。

其他應用程序處理文件URI-S開頭「文件:// ......」所以你必須實行第二股menue「共享爲文件」

private Intent getFileShareIntent(String fullPathTofile) { 
    final Intent shareIntent = new Intent(); 
    shareIntent.setAction(Intent.ACTION_SEND); 
    shareIntent.setType("image/jpeg"); 
    shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + fullPathTofile)); 
    shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 

    return shareIntent; 
} 

可以使用android app intentintercept來了解其他「共享源應用程序」提供了哪些內容。