这个问题包含几个子问题。我从这个问题开始分叉这些。我最终会通过删除这个问题来清理。
以下程序理论上将共享一个 hello-world 文本文件。代码运行,但共享到 Dropbox 或 Gmail(仅通过两个具体示例)失败。
public class MainActivity extends Activity {
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String filename = "hellow.txt";
String fileContents = "Hello, World!\n";
byte[] bytes = fileContents.getBytes();
FileOutputStream fos = null;
try {
fos = this.openFileOutput(filename, MODE_PRIVATE);
fos.write(bytes);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
File file = new File(filename);
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
shareIntent.setType("application/txt");
startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.send_to)));
file.delete();
}
}
除了send_to
在 res/values/strings.xml 中添加值之外,我对 Eclipse 创建的泛型所做的唯一另一对更改是在 AndroidManifest.xmlHello, World
中添加以下标记:<provider>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.mycorp.helloworldtxtfileprovider.MainActivity"
android:exported="false"
android:grantUriPermissions="true" >
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/my_paths" />
</provider>
<activity
android:name="com.mycorp.helloworldtxtfileprovider.MainActivity"
...
...并在 res/xml/my_paths.xml 中添加以下内容
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="files" path="." />
</paths>
我的主要问题是第一个,但是当你在这个话题上时,对问题 2-4 的讨论也会很有趣。
- 为什么上面的程序会失败?
- 确实是这样的情况,如果一个人需要一个 custom
ContentProvider
,那么一个人需要扩展那个类,但是如果一个人只需要一个FileProvider
,那么一个人可以在没有派生的情况下使用那个类? - 在这段代码中,我需要使用
filename
两次——一次 withopenFileOutput
,另一次 withnew File()
。有没有办法避免这种重复(这可以保证引用的是同一个文件)? - 在调用后立即删除文件是否安全
startActivity(..)
,或者是否有必要设计一个回调来等待得知文件已上传/共享。(实际文件可能需要一些时间才能共享/上传。)
编辑
该代码运行良好,并显示了要发送到的应用程序列表。
如果我选择 Dropbox,我可以很好地选择位置。Dropbox 发送通知“上传到 Dropbox”,然后是“上传失败:my_file.txt”。
如果我选择 Gmail,我可以填写收件人并且文件似乎已附加,但在“发送消息..”之后我得到“无法发送附件”。