使用 Intent.ACTION_SEND 发送重命名的文件

Sending a renamed file using Intent.ACTION_SEND

假设我有一个存档文件 saves.xyz,我想通过邮件分享它。

Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_SUBJECT, content.getShareSubject());
intent.putExtra(Intent.EXTRA_TEXT, content.getShareText());

File savesFile = new File(Environment.getExternalStorageDirectory(), filePath);
Uri savesUri = Uri.fromFile(savesFile);
intent.putExtra(Intent.EXTRA_STREAM, savesUri);

String fileType = activity.getString(R.string.saves_file_type); //"text/xyz"
intent.setType(fileType);

String chooserMessage = activity.getString(R.string.saves_chooser_message);
activity.startActivity(Intent.createChooser(intent, chooserMessage));

这很好用。


但是,我现在希望能够重命名附件(比如说saves-01-01-2017.xyz)。

我想过复制文件,发送它,然后删除它,但还没有找到一种方法可以在之后彻底删除它(参见 this)。

我也尝试实现我自己的 FileProvider(建议 here)并将 saves-*.xyz 重定向到 saves.xyz,但我无法获得 FileProvider 工作(我可能没有完全掌握它们的功能):

manifest.xml

<manifest 
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mydomain.myapp"
    >
    ...
    <application
        ...
        >
        <provider
            android:name="com.mydomain.myapp.MyFileProvider"
            android:authorities="com.mydomain.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true"
            >
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_provider_paths"
            />
        </provider>
        ...
    </application>
</manifest>

file_provider_paths.xml

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

MyFileProvider class

public class MyFileProvider extends FileProvider {
    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
        //doesn't print anything
        Log.d(MyFileProvider.class.getSimpleName(), uri.toString()); 
        return super.openFile(uri, mode);
    }
}

如能在此开悟,将不胜感激

你可能想试试这个方法

File savesFile = new File(Environment.getExternalStorageDirectory(), filePath);

//rename your file here
File rename = new File(context.getCacheDir(), "renameithere.txt");
if (savesFile.exists()) {
   savesFile.renameTo(rename);
}

此外,如果您使用的是 FileProvider,则使用这种方式获取 Uri。

try {
    return FileProvider.getUriForFile(context, authority, viewFile);
} catch (Exception ex) {
    return Uri.fromFile(viewFile);
}

希望对您有所帮助。

我找到了一种比 FileProvider 更干净的方法(感觉太过分了,而且我无论如何也无法让它工作),使用 startActivityForResultonSaveInstanceState

正在将文件复制到所需名称:

try {
    copyFile(saves_file, saves_tmp_file);
} catch (IOException ex) {
    return false;
}
Uri saves_uri = Uri.fromFile(saves_tmp_file) ;

开始意图的 activity 与 startActivityForResult:

activity.startActivityForResult(Intent.createChooser(intent, chooserMessage), 
                                MY_REQUEST_CODE);

在 activity 的状态下保存临时文件的名称:

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outstate.putCharArray(TO_DELETE_PATH_BUNDLE_KEY, tmpFilePath.toCharArray());
}

正在恢复:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //...
    if (savedInstanceState != null) {
        char[] array = savedInstanceState.getCharArray(TO_DELETE_PATH_BUNDLE_KEY);
        if (array != null)
            tmpFilePath = new String(array);
    {
}

正在删除文件:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == MY_REQUEST_CODE && tmpFilePath != null)
        new File(Environment.getExternalStorageDirectory(), tmpFilePath).delete();
}

我想这个方法不是最安全的,但它应该足够安全和​​干净以供我使用。