android.os.FileUriExposedException:通过 Intent.getData() 异常暴露在应用程序之外,同时共享 VCFile

Posted

技术标签:

【中文标题】android.os.FileUriExposedException:通过 Intent.getData() 异常暴露在应用程序之外,同时共享 VCFile【英文标题】:android.os.FileUriExposedException: exposed beyond app through Intent.getData() Exception , While sharing VCFile 【发布时间】:2021-11-28 03:11:14 【问题描述】:

问题陈述

我正在尝试制作 VCardfile,它已成功创建,但我想分享创建的文件

例外

android.os.FileUriExposedException: file:///storage/emulated/0/vcf_demonuts/android_1633671182515.vcf 通过 Intent.getData() 暴露在应用之外

我的代码

            var vdfdirectory = File(
                Environment.getExternalStorageDirectory().toString() + VCF_DIRECTORY
            );
            // have the object build the directory structure, if needed.
            if (!vdfdirectory.exists()) 
                vdfdirectory.mkdirs();
            

            vcfFile =
                File(vdfdirectory, "android_" + Calendar.getInstance().getTimeInMillis() + ".vcf");

            val fw: FileWriter = FileWriter(vcfFile);
            fw.write("BEGIN:VCARD\r\n");
            fw.write("VERSION:3.0\r\n");
            // fw.write("N:" + p.getSurname() + ";" + p.getFirstName() + "\r\n");
            fw.write("FN:" + "Sibtain" + "\r\n");
            //  fw.write("ORG:" + p.getCompanyName() + "\r\n");
            //  fw.write("TITLE:" + p.getTitle() + "\r\n");
            fw.write("TEL;TYPE=WORK,VOICE:" + "+923155022905" + "\r\n");
            //   fw.write("TEL;TYPE=HOME,VOICE:" + p.getHomePhone() + "\r\n");
            //   fw.write("ADR;TYPE=WORK:;;" + p.getStreet() + ";" + p.getCity() + ";" + p.getState() + ";" + p.getPostcode() + ";" + p.getCountry() + "\r\n");
            fw.write("EMAIL;TYPE=PREF,INTERNET:" + "abc@gmail.com" + "\r\n");
            fw.write("END:VCARD\r\n");
            fw.close();


            val txtIntent = Intent(Intent.ACTION_SEND)
            txtIntent.setDataAndType(Uri.fromFile(vcfFile), "text/x-vcard");
            startActivity(Intent.createChooser(txtIntent, "Share"))
            Toast.makeText(this, "Created!", Toast.LENGTH_SHORT).show();

*我已经尝试关注&solution available on ***

我已经创建了 provider_path.xml 文件

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths> 

清单

<provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.example.testapp.provider"
            android:exported="false"
            android:grantUriPermissions="true"
            tools:replace="android:authorities">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"
                tools:replace="android:resource" />
        </provider> 

【问题讨论】:

【参考方案1】:

试试下面的代码,它适用于共享 VCFile:

 private void shareContact(ContactsModal modal) 

    String lookupKey = null;
    Cursor cur = ((Activity)context).getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, new String[]
             ContactsContract.Contacts.LOOKUP_KEY ,
            ContactsContract.Contacts._ID + " = " + modal.getContactID(), null, null);

    if (cur.moveToFirst()) 
         lookupKey = cur.getString(0);
    
    if(lookupKey!=null)
        Uri vcardUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType(ContactsContract.Contacts.CONTENT_VCARD_TYPE);
        intent.putExtra(Intent.EXTRA_STREAM, vcardUri);
        intent.putExtra(Intent.EXTRA_SUBJECT, "Contact Name");
        ((Activity)context).startActivity(intent);
    

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。【参考方案2】:

onCreate 方法中您的应用程序文件。放置以下代码

StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());

这将使异常消失。但是,这主要用作诊断工具,并不是合适的解决方案。

使用 fileProvider 方法的另一个解决方案是将 FLAG_GRANT_READ_URI_PERMISSION 标志添加到您的意图中。

Intent intent = new Intent(Intent.ACTION_VIEW, FileProvider.getUriForFile(this, AUTHORITY, f));
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);

【讨论】:

是的,您的解决方案有助于消除异常,但我仍然无法使用 Intent 共享 .vcf 格式文件。请您解释一下我们如何共享 .vcf 文件

以上是关于android.os.FileUriExposedException:通过 Intent.getData() 异常暴露在应用程序之外,同时共享 VCFile的主要内容,如果未能解决你的问题,请参考以下文章