2

为Adobe Flex应用程序的一部分中,我写了Android原生的扩展,允许我发送电子邮件使用从生成的文件的文件附件flex代码。但是,我不希望该文件具有世界可读性,因为它可能包含敏感数据。因此我想从应用程序的内部存储区/缓存中发送文件。我正在使用Intents与其他应用程序(如Gmail)通信以发送电子邮件。可以使用共享的内部文件(例如使用FileProvider)柔性原生扩展到其他应用

做了一些研究之后,我发现的FileProviders功能应该做的正是我想要的。然而静态方法FileProvider.getUriForFile()默默地失效/崩溃本机扩展。原生扩展停止并返回null,并且没有错误或LogCat输出。

如果我手动解析字符串创建开放的,Gmail会抱怨说,它不能将文件附加到电子邮件,和电子邮件没有附件发送。

守则FREObject()调用:

//... (Deal with params from flex app) ... 

//Setup Intent, and attach email data send from flex application: 
Intent intent = new Intent(Intent.ACTION_SEND); 
intent.setType("message/rfc822"); 
intent.putExtra(Intent.EXTRA_EMAIL, toArray); 
intent.putExtra(Intent.EXTRA_CC, ccArray); 
intent.putExtra(Intent.EXTRA_BCC, bccArray); 
intent.putExtra(Intent.EXTRA_SUBJECT, subject); 
intent.putExtra(Intent.EXTRA_TEXT, message); 

Log.d("emaildebug", filePath); 
//Check we can read our email attachment from flex app 
//filePath is a temporary cache location. 
File appFile = new File(filePath); 
if (appFile.exists() && appFile.canRead()) { 
    Log.d("emaildebug", "file successfully read"); 
} else { 
    return null; 
} 

//Get a handle on the android Context instead of FREContext. 
Context androidContext = (Context) context.getActivity(); 

//Get the location of the root files directory. 
File attachPath = androidContext.getFilesDir(); 
File attachFile = new File(attachPath, "attachment.pdf"); 

//Copy file to root of files directory, so that our FileProvider can access it. 
try { 
    copyFileUsingChannel(appFile, attachFile); 
} catch (Exception e) { 
    Log.d("emaildebug", e.getMessage()); 
} 

Log.d("emaildebug", "attachFile exists: " + attachFile.exists()); 
Log.d("emaildebug", "attachFile path: " + attachFile.getAbsolutePath()); 

//This line will silently crash the native extension, instantly returning null, even in try catch. 
//Uri contentUri = FileProvider.getUriForFile(androidContext, "com.example.androidextensiontest.provider", attachFile); 

//Therefore manually create the Uri from a string. 
Uri contentUri = Uri.parse("content://com.example.androidextensiontest.provider/files/attachment.pdf"); 

Log.d("emaildebug", "uri created"); 
Log.d("emaildebug", contentUri.toString()); 

//Grant permisions for all apps that can handle given intent 
//Courtesy of: http://stackoverflow.com/questions/18249007/how-to-use-support-fileprovider-for-sharing-content-to-other-apps 
List<ResolveInfo> resInfoList = androidContext.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); 
for (ResolveInfo resolveInfo : resInfoList) { 
    String packageName = resolveInfo.activityInfo.packageName; 
    Log.d("emaildebug", "package: " + packageName); 
    androidContext.grantUriPermission(packageName, contentUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); 
} 

intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); 
intent.putExtra(Intent.EXTRA_STREAM, contentUri); 

context.getActivity().startActivity(Intent.createChooser(intent, "Send mail using...")); 

清单文件:

<provider 
    android:name="android.support.v4.content.FileProvider" 
    android:authorities="com.example.androidextensiontest.provider" 
    android:exported="false" 
    android:grantUriPermissions="true" > 
    <meta-data 
     android:name="android.support.FILE_PROVIDER_PATHS" 
     android:resource="@xml/my_paths" /> 
</provider> 

在my_paths.xml:

<paths xmlns:android="http://schemas.android.com/apk/res/android"> 
    <files-path name="files" path="." /> 
</paths> 

logcat的输出:

11-01 10:58:09.971: D/emaildebug(17013): /data/data/air.com.example.MyAppName.debug/cache/FlashTmp.V17013/attachment.pdf 
11-01 10:58:09.971: D/emaildebug(17013): file successfully read 
11-01 10:58:09.991: D/emaildebug(17013): attachFile exists: true 
11-01 10:58:09.991: D/emaildebug(17013): attachFile path: /data/data/air.com.example.MyAppName.debug/files/attachment.pdf 
11-01 10:58:09.991: D/emaildebug(17013): uri created 
11-01 10:58:09.991: D/emaildebug(17013): content://com.example.androidextensiontest.provider/files/attachment.pdf 
11-01 10:58:09.991: D/emaildebug(17013): package: com.android.email 
11-01 10:58:09.991: D/emaildebug(17013): package: com.google.android.gm 

如果我尝试从外部存储器发送的文件使用一个文件://乌里文件附件完美的作品。但是,如前所述,文件附件可能包含敏感数据,因此我希望避免使用外部存储。

我相信我看到的是,FileProviders没有原生扩展内工作。我也尝试使用ContentProvider,但是无论是构造函数还是onCreate方法都未被调用。

的ContentProvider清单:

<provider 
    android:name="com.example.androidextensiontest.provider.MyContentProvider" 
    android:authorities="com.example.androidextensiontest.provider"> 
</provider> 

MyContentProvider:

public class MyContentProvider extends ContentProvider implements PipeDataWriter<InputStream> { 

public MyContentProvider() { 
    // Never Output 
    Log.d("emaildebug", "Constructor"); 
} 

@Override 
public boolean onCreate() { 
    // Never Output 
    Log.d("emaildebug", "OnCreate"); 
    return false; 
} 

//.. Rest of class 
} 

上午我做错了什么或者ContentProviders/FileProviders只是不挠原生扩展中支持?或者,是否有其他解决方案将位于内部存储的文件附加到电子邮件中。我在SO和谷歌搜索没有遇到任何其他人有类似的经验,特别是关于FileProvider.getUriForFile()。任何帮助/意见表示赞赏。

对不起,文字的墙,我想记录的一切到目前为止,我已经试过了,什么可行,什么不可行。

tldr; ContentProviders /文件提供程序是否在Flex本机扩展中工作?有没有其他方法将内部文件作为电子邮件附件发送?

回答

2

所以我终于有时间回来看看这个问题。我更多地了解了Flex扩展构建过程和一般的Android开发。

我现在在adobe flex扩展中有一个完全可用的fileprovider。

解决方案的第一部分是.ane中的清单被忽略用于伸缩扩展。相反,任何活动或供应商必须在应用程序的名字-app.xml中提供的flashbuilder清单扩展下:

<android> 
    <colorDepth>16bit</colorDepth> 
    <manifestAdditions><![CDATA[ 
     <manifest android:installLocation="auto"> 
      <application android:enabled="true" 
       android:launchMode="singleInstance"> 
       <provider 
        android:name="android.support.v4.content.FileProvider" 
        android:authorities="com.example.androidextensiontest.files" 
        android:exported="false" 
        android:grantUriPermissions="true"> 
        <meta-data 
         android:name="android.support.FILE_PROVIDER_PATHS" 
         android:resource="@xml/file_paths" /> 
       </provider> 
      </application> 
     </manifest> 
    ]]></manifestAdditions> 
</android> 

这将导致flashbuilder抱怨说,它不能找到@ XML/file_paths资源。

因此,您需要将android扩展中的整个res /文件夹复制到构建ane的ane build/android文件夹中。

所以build文件夹结构如下:

-BuildFolder 
    -android 
     -libs 
     -res 
      -otherfolders 
      -xml 
       file_paths.xml 
     androidLib.jar 
     library.swf 
    -default 
    -ios 

构建ANE正常。在此之后,我的文件提供者开始工作,这意味着您可以使用此行生成文件提供程序uri:

Uri contentUri = FileProvider.getUriForFile(androidContext, "com.example.androidextensiontest.files", attachFile); 
相关问题