【问题标题】:Sending a renamed file using Intent.ACTION_SEND使用 Intent.ACTION_SEND 发送重命名文件
【发布时间】:2023-04-05 00:45:02
【问题描述】:

假设我有一个保存文件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 工作(我可能没有掌握他们的充分发挥作用):

ma​​nifest.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 类

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);
    }
}

如果我能在这里得到启发,我将不胜感激。

【问题讨论】:

  • I now want to be able to rename the attached file。什么大惊小怪。首先重命名文件。然后附上它。
  • 发送意图不需要指定名称。
  • @greenapps 也许我不清楚。我希望附件具有不同的名称,但我不想更改我的文件名,也不想有剩余文件

标签: android android-intent android-contentprovider


【解决方案1】:

你可能想试试这个方法

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);
}

希望这会有所帮助。

【讨论】:

  • 感谢您的回答。我试过getUriForFile,遗憾的是无济于事。另外,将文件复制到分机中。缓存确实可以工作,但我想避免在其中留下无用的文件,所以我会保留它作为最后的选择
  • 另外,getUriForFile 不会抛出异常,因此无需从中捕获
【解决方案2】:

我找到了一种比FileProvider 更清洁的方法(感觉太矫枉过正,无论如何我无法让它工作),使用startActivityForResultonSaveInstanceState

将文件复制到所需的名称:

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

使用startActivityForResult 启动意图的活动:

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

在活动状态下保存临时文件名:

@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();
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-30
    • 2014-06-04
    • 2016-05-29
    相关资源
    最近更新 更多