簡體   English   中英

Android使用Content Provider從Assets文件夾發送圖像?

[英]Android Sending image from assets folder using Content Provider?

您好,我正在嘗試通過通用意圖從應用程序中的Assets文件夾發送圖像(以便用戶可以將圖像發送到接受此類意圖的任何其他應用程序,包括SMS,Facebook和Twitter)。

環顧了一會后,我發現了這個StackOverflow問題 它似乎工作得很好,並且在遵循了一些評論之后,該方法似乎並未被棄用。 但是,我的問題是我無法使用它。 發生的事情是我從意圖選擇器對話框中成功選擇了一個應用程序,但是一旦該應用程序出現,我就會吐司說“找不到照片”。

這是我當前的代碼...

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)

我仍然不確定如何解決此問題(盡管我仍在繼續修補),因此仍將不勝感激! 謝謝!

感謝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>

請注意,在我在問題內發布的代碼中,提供程序位於清單標簽之間,但位於應用程序標簽之外(類似於聲明權限的位置)。 相反,提供者聲明必須在應用程序標記之間,就像在聲明活動的位置一樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM