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