Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/226.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 仅限Android共享意图选择器电子邮件客户端_Java_Android_Email_Android Intent_Share - Fatal编程技术网

Java 仅限Android共享意图选择器电子邮件客户端

Java 仅限Android共享意图选择器电子邮件客户端,java,android,email,android-intent,share,Java,Android,Email,Android Intent,Share,我正在尝试为用户创建一个选项,以便仅通过电子邮件从我的应用程序发送文件。该文件是应用程序的内部文件,可以通过FileProvider访问 这是contentURI看起来像content://packagename.files/files/somefile.ext 在这里你可以看到,我给用户分享文件的PicsArt,谷歌驱动器,OneDrive和电子邮件 我能够成功地将内容分享给前三位客户,因为他们都是非常特定的应用程序。但说到电子邮件,我需要用户从他安装在手机上的应用程序中选择客户端 以下是我

我正在尝试为用户创建一个选项,以便仅通过电子邮件从我的应用程序发送文件。该文件是应用程序的内部文件,可以通过FileProvider访问

这是contentURI看起来像
content://packagename.files/files/somefile.ext

在这里你可以看到,我给用户分享文件的PicsArt,谷歌驱动器,OneDrive和电子邮件

我能够成功地将内容分享给前三位客户,因为他们都是非常特定的应用程序。但说到电子邮件,我需要用户从他安装在手机上的应用程序中选择客户端

以下是我创建的两组代码:

代码选项1:

Intent EMail=ShareCompat.IntentBuilder.from(此)
.setType(“消息/rfc822”)
.setSubject(“电子邮件发送:文件附件”)
.setText(“你好”)
.setStream(contentUri)
.setChooserTitle(“通过电子邮件发送”).getIntent();
startActivity(Intent.createChooser(电子邮件,“通过电子邮件发送”);
上面的代码向我展示了一个选择器,其中有许多应用程序可以处理如下图所示的文件

如果我选择任何电子邮件客户端应用程序或任何其他应用程序,此应用程序都可以正常工作

但问题是,用户可以选择任何应用程序,这不是应用程序所需的行为。因此,我对代码进行了如下修改:

final Intent\u Intent=新意图(Intent.ACTION\u SENDTO);
_Intent.setType(“text/html”);
_setData(Uri.parse(“mailto:”);
_Intent.addFlags(Intent.FLAG\授予\读取\ URI\权限);
_Intent.putExtra(Intent.EXTRA_流,contentUri);
_Intent.putExtra(android.content.Intent.EXTRA_主题,
“电子邮件:文件附件”);
_Intent.putExtra(android.content.Intent.EXTRA_TEXT,
“你好”);
startActivity(Intent.createChooser(_Intent,“通过电子邮件发送”);
以下是守则的结果:

但是,现在的问题是,我无法从内容提供商(FileProvider)发送文件。选择后,电子邮件客户端将显示以下消息:

它只是不将文件附加到上面列表中任何客户端的电子邮件中

如果有人能帮我的话,我会非常高兴的。我想,我在这里尝试了所有可能的场景,通过更改mime类型、以不同的方式设置内容、设置数据设置流等,但未能获得预期的结果

请让我知道,如果你需要任何其他细节


再次提前感谢。

您需要编写ContentProvider,它将向您已向其传递ContentUri的客户端提供InputStream,或者您可以直接提供文件路径(如果文件路径存在于SD卡或内部存储器中),因为您需要处理uri并传递InputStream。注意:ExtraStream最适合不在要从internet访问的设备中的文件

public class SampleContentProvider extends ContentProvider implements ContentProvider.PipeDataWriter<InputStream> {

    static final UriMatcher uriMatcher;


    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        //Uri matcher for different 

    }

    /**
     * Database specific constant declarations
     */
    private SQLiteDatabase db;


    @Override
    public boolean onCreate() {
        return true;
    }


    @Override
    public Uri insert(Uri uri, ContentValues values) {

        throw new SQLException("Insert operation not supported for  " + uri);
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {

        //condition just for files. You can try something else
        if (uri.toString().contains("files")) {

            //you get the file name
            String lastSegment = uri.getLastPathSegment();

            if (projection == null) {
                projection = new String[]{OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE};
            }

            File file = //Code to read the file as u have the directory, just get the file from the file name obtained from the uri


            if (null == file) {
                throw new IllegalArgumentException("Unknown File for Uri " + uri);
            }
            String[] cols = new String[projection.length];
            Object[] values = new Object[projection.length];
            int i = 0;
            for (String col : projection) {
                if (OpenableColumns.DISPLAY_NAME.equals(col)) {
                    cols[i] = OpenableColumns.DISPLAY_NAME;
                    values[i++] = //file name;
                } else if (OpenableColumns.SIZE.equals(col)) {
                    cols[i] = OpenableColumns.SIZE;
                    values[i++] = //file size;
                }
            }

            cols = copyOf(cols, i);
            values = copyOf(values, i);

            final MatrixCursor cursor = new MatrixCursor(cols, 1);
            cursor.addRow(values);
            return cursor;
        }

        return super.query(uri, projection, selection, selectionArgs, sortOrder);

    }

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

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return super.delete(uri, selection, selectionArgs);

    }


    private static String[] copyOf(String[] original, int newLength) {
        final String[] result = new String[newLength];
        System.arraycopy(original, 0, result, 0, newLength);
        return result;
    }

    private static Object[] copyOf(Object[] original, int newLength) {
        final Object[] result = new Object[newLength];
        System.arraycopy(original, 0, result, 0, newLength);
        return result;
    }

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

        File file = //read the file
        if (file != null) {
            try {
                StrictMode.ThreadPolicy tp = StrictMode.ThreadPolicy.LAX;
                StrictMode.setThreadPolicy(tp);   
                InputStream in = //Code to get the inputstream;
                // Start a new thread that pipes the stream data back to the caller.
                return openPipeHelper(uri, null, null, in, this);
            } catch (IOException e) {
                FileNotFoundException fnf = new FileNotFoundException("Unable to open " + uri);
                throw fnf;
            }
        }

        throw new IllegalArgumentException("Unknown URI " + uri);
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        return super.update(uri, values, selection, selectionArgs);
    }

    @Override
    public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String mimeType,
                                Bundle opts, InputStream args) {
        // Transfer data from the asset to the pipe the client is reading.
        byte[] buffer = new byte[8192];
        int n;
        FileOutputStream fout = new FileOutputStream(output.getFileDescriptor());
        try {
            while ((n = args.read(buffer)) >= 0) {
                fout.write(buffer, 0, n);
            }
        } catch (IOException e) {
        } finally {
            try {
                args.close();
            } catch (IOException e) {
            }
            try {
                fout.close();
            } catch (IOException e) {
            }
        }
    }

}
公共类SampleContentProvider扩展ContentProvider实现ContentProvider.PipeDataWriter{
静态最终UriMatcher UriMatcher;
静止的{
uriMatcher=新的uriMatcher(uriMatcher.NO_匹配);
//不同类型的Uri匹配器
}
/**
*特定于数据库的常量声明
*/
专用数据库数据库;
@凌驾
公共布尔onCreate(){
返回true;
}
@凌驾
公共Uri插入(Uri、ContentValues){
抛出新的SQLException(“插入操作不支持”+uri);
}
@凌驾
公共游标查询(Uri Uri、字符串[]投影、字符串选择、字符串[]selectionArgs、字符串排序器){
//条件仅适用于文件。您可以尝试其他方法
if(uri.toString()包含(“文件”)){
//你得到文件名了吗
字符串lastSegment=uri.getLastPathSegment();
if(投影==null){
projection=新字符串[]{OpenableColumns.DISPLAY_NAME,OpenableColumns.SIZE};
}
File File=//当您拥有目录时读取该文件的代码,只需从从uri获取的文件名中获取该文件即可
if(null==文件){
抛出新的IllegalArgumentException(“Uri的未知文件”+Uri);
}
String[]cols=新字符串[projection.length];
Object[]值=新对象[projection.length];
int i=0;
for(字符串列:投影){
if(OpenableColumns.DISPLAY_NAME.equals(col)){
cols[i]=OpenableColumns.DISPLAY\u NAME;
值[i++]=//文件名;
}else if(OpenableColumns.SIZE.equals(col)){
cols[i]=OpenableColumns.SIZE;
值[i++]=//文件大小;
}
}
cols=副本(cols,i);
值=副本(值,i);
最终矩阵运算器光标=新矩阵运算器(cols,1);
cursor.addRow(值);
返回光标;
}
返回super.query(uri、投影、选择、选择、排序器);
}
@凌驾
公共字符串getType(Uri){
返回null;
}
@凌驾
public int delete(Uri、字符串选择、字符串[]selectionArgs){
返回super.delete(uri、selection、selectionArgs);
}
私有静态字符串[]copyOf(字符串[]原始,int newLength){
最终字符串[]结果=新字符串[newLength];
System.arraycopy(原始,0,结果,0,新长度);
返回结果;
}
私有静态对象[]copyOf(对象[]原始,int newLength){
最终对象[]结果=新对象[newLength];
System.arraycopy(原始,0,结果,0,新长度);
返回结果;
}
@可空
@爱
Intent testIntent = new Intent(Intent.ACTION_VIEW);
                    Uri data = Uri.parse("mailto:?subject=" + "Feedback" + "&body=" + "Write Feedback here....." + "&to=" + "someone@example.com");
                    testIntent.setData(data);
                    startActivity(testIntent);