2015-04-06 79 views
0

你好〜我試圖通過一般意圖從應用程序中的資產文件夾發送圖像(因此用戶可以將圖像發送到接受這種意圖的任何其他應用程序,包括SMS,Facebook和Twitter)。我找到了StackOverflow question。它似乎工作得很好,並且在遵循了一些評論之後,該方法似乎不被棄用。然而,我的問題是我無法實現它的工作。發生的事情是,我成功地從意向選擇器對話中選擇了一個應用程序,但是一旦應用程序出現「我找不到照片」的祝酒詞。Android使用Content Provider從資產文件夾發送圖像?

這裏是我當前的代碼...

的AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.mdstudios.diabeticons" > 

<provider 
    android:name="com.mdstudios.diabeticons.Utils.AssetsProvider" 
    android:authorities="com.mdstudios.diabeticons" 
    android:grantUriPermissions="true" 
    android:exported="true" /> 

<application 
... 

AssetsProvider.java:

package com.mdstudios.diabeticons.Utils; 

import android.content.ContentProvider; 
import android.content.ContentValues; 
import android.content.res.AssetFileDescriptor; 
import android.content.res.AssetManager; 
import android.database.Cursor; 
import android.net.Uri; 
import android.os.CancellationSignal; 
import android.util.Log; 

import java.io.FileNotFoundException; 
import java.io.IOException; 

/** 
* Created by jawad on 06/04/15. 
*/ 
public class AssetsProvider extends ContentProvider { 
    private static final String LOGTAG = "MD/AssetsProvider"; 

    @Override 
    public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException 
    { 
    Log.v(LOGTAG, "AssetsGetter: Open asset file"); 

    AssetManager am = getContext().getAssets(); 

    String file_name = uri.getPath().substring(1, uri.getPath().length()); 
    //String file_name = uri.getLastPathSegment(); 
    // Neither of the two lines above work for me 

    if(file_name == null) 
     throw new FileNotFoundException(); 

    AssetFileDescriptor afd = null; 

    try 
    { 
     afd = am.openFd(file_name); 
    } 
    catch(IOException e) 
    { 
     e.printStackTrace(); 
    } 

    return afd;//super.openAssetFile(uri, mode); 
    } 

    @Override 
    public String getType(Uri p1) 
    { 
    // TODO: Implement this method 
    return null; 
    } 

    @Override 
    public int delete(Uri p1, String p2, String[] p3) 
    { 
    // TODO: Implement this method 
    return 0; 
    } 

    @Override 
    public Cursor query(Uri p1, String[] p2, String p3, String[] p4, String p5) 
    { 
    // TODO: Implement this method 
    return null; 
    } 

    @Override 
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal) 
    { 
    // TODO: Implement this method 
    return super.query(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal); 
    } 

    @Override 
    public Uri insert(Uri p1, ContentValues p2) 
    { 
    // TODO: Implement this method 
    return null; 
    } 

    @Override 
    public boolean onCreate() 
    { 
    // TODO: Implement this method 
    return false; 
    } 

    @Override 
    public int update(Uri p1, ContentValues p2, String p3, String[] p4) 
    { 
    // TODO: Implement this method 
    return 0; 
    } 
} 

SendActivity.java:

// Sends an intent to share the image that was passed to this Activity 
private void sendImage() { 
    Log.d(LOGTAG, mFilePath); 
    Uri theUri = Uri.parse("content://com.mdstudios.diabeticons/" + mFilePath); 
    // Tried file path with subfolder and non-subfolder images 

    Intent theIntent = new Intent(Intent.ACTION_SEND); 
    theIntent.setType("image/*"); 
    theIntent.putExtra(Intent.EXTRA_STREAM,theUri); 
    theIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,"Subject for message"); 
    theIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Body for message"); 
    startActivity(theIntent); 
} 

我我不知道我在做什麼翁。我試圖發送的圖像在子文件夾中(即「folder/image1.png」)。但是,我試過在任何子文件夾之外使用圖像(即將圖像複製到任何資產子文件夾之外後,文件路徑只是「image1.png」)。此外,在原始SO問題的評論中,似乎我不得不用不同的方式從Uri獲取文件路徑。原始方法和新方法(在AssetsProvider類的註釋中指出)都不起作用。

謝謝你的幫助!

編輯: 環顧更多後,我在這裏發現了一個類似的帖子,沒有回覆。然後我看了看我的更深入的logcat,並發現了一個錯誤:

04-06 14:30:54.773 18883-19532/? E/Babel﹕ java.io.FileNotFoundException: No content provider: content://com.mdstudios.diabeticons/Banana.png 
     at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1060) 
     at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:914) 
     at android.content.ContentResolver.openInputStream(ContentResolver.java:639) 
     at ajz.a(SourceFile:5280) 
     at ajz.doInBackgroundTimed(SourceFile:5066) 
     at dsn.doInBackground(SourceFile:65) 
     at android.os.AsyncTask$2.call(AsyncTask.java:288) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
     at java.lang.Thread.run(Thread.java:841) 

我仍然不知道如何解決這個問題(雖然我仍然繼續鼓搗出來),所以任何幫助仍然會不勝感激!謝謝!

+0

嗯......堆棧跟蹤會顯示您的權限已丟失,但似乎與您的清單中的內容相符。 FWIW,[我的'StreamProvider'提供](https://github.com/commonsguy/cwac-provider)一個開箱即用的解決方案。 – CommonsWare

+0

謝謝!我會研究它(並且很可能會使用它),儘管希望有人會爲他人回答這個問題以及我的好奇心; D – MDragon00

+0

其實,謝謝@CommonsWare!如果沒有鏈接到您的解決方案,我就不會在這裏找到問題(查看您的演示,瞭解如何實現它,注意到我在做例子時做錯了什麼) – MDragon00

回答

1

感謝CommonsWare,我意識到這個問題。問題在於提供程序應該在清單中聲明的​​地方 - 特別是應用程序標記之間。

因此,清單應該是這樣的......

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.mdstudios.diabeticons" > 

    <application> 
     <provider 
      android:name="com.mdstudios.diabeticons.Utils.AssetsProvider" 
      android:authorities="com.mdstudios.diabeticons" 
      android:grantUriPermissions="true" 
      android:exported="true" /> 
    </application> 

</manifest> 

請注意,在我張貼的問題中的代碼,提供者是明顯的標記之間尚未應用標籤外(類似於地方權限被宣佈)。相反,提供程序聲明必須位於應用程序標記之間,就像聲明「活動」的位置一樣。

相關問題