简体   繁体   English

Android使用Content Provider从Assets文件夹发送图像?

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

Hello~ I'm trying to send an image from the assets folder in an application via a general intent (so the user can send an image to any other application which accepts such an intent, including SMS, Facebook, and Twitter). 您好,我正在尝试通过通用意图从应用程序中的Assets文件夹发送图像(以便用户可以将图像发送到接受此类意图的任何其他应用程序,包括SMS,Facebook和Twitter)。

After looking around for a while, I found this StackOverflow question . 环顾了一会后,我发现了这个StackOverflow问题 It seemed to work quite well, and after following the comments for a bit, the method doesn't seem to be deprecated. 它似乎工作得很好,并且在遵循了一些评论之后,该方法似乎并未被弃用。 My issue, however, is that I can't get it to work. 但是,我的问题是我无法使用它。 What occurs is that I successfully choose an application from the intent chooser dialogue, but once the application, I get a toast that says "Can't find photo." 发生的事情是我从意图选择器对话框中成功选择了一个应用程序,但是一旦该应用程序出现,我就会吐司说“找不到照片”。

Here is my current code... 这是我当前的代码...

AndroidManifest.xml: 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: 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: 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);
}

I'm not sure what I'm doing wrong. 我不确定自己在做什么错。 The images I'm trying to send are in subfolders (ie, "folder/image1.png"). 我尝试发送的图像位于子文件夹中(即“ folder / image1.png”)。 However, I've tried using an image outside of any subfolders (ie, simply "image1.png" for the file path after copying the image to be outside of any asset subfolders). 但是,我尝试使用任何子文件夹之外的图像(例如,将图像复制到任何资产子文件夹之外后,将文件路径简称为“ image1.png”)。 Furthermore, in the comments in the original SO question, it seemed I had to use a different way to get the file path from the Uri. 此外,在原始SO问题的注释中,似乎我不得不使用另一种方法来从Uri获取文件路径。 Neither the original nor the new method (pointed out in the comments in the AssetsProvider class) worked. 原始方法和新方法(在AssetsProvider类的注释中指出)均无效。

Thank you for any and all help! 感谢您提供的所有帮助!

Edit: After looking around some more, I found a similar posting of the issue here with no replies. 编辑:看了更多之后,我在这里发现了类似的问题发布,但没有回复。 I then looked at my logcat more in depth, and found an error: 然后,我更深入地查看了我的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)

I'm still not sure how to fix this (although I'm still continuing to tinker with it), so any help would still be appreciated! 我仍然不确定如何解决此问题(尽管我仍在继续修补),因此仍将不胜感激! Thanks! 谢谢!

Thanks to CommonsWare, I realized the issue here. 感谢CommonsWare,我在这里意识到了这个问题。 The problem is where the provider is supposed to be declared within the manifest- specifically, between the application tags. 问题在于应该在清单中,特别是在应用程序标记之间声明提供者。

So, the manifest should look like this... 所以清单应该看起来像这样...

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

Notice that in the code I posted within the question, the provider was between the manifest tags yet outside the application tags (similar to where permissions are declared). 请注意,在我在问题内发布的代码中,提供程序位于清单标签之间,但位于应用程序标签之外(类似于声明权限的位置)。 Instead, the provider declaration must be between the application tags, just like where Activities are declared. 相反,提供者声明必须在应用程序标记之间,就像在声明活动的位置一样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM