为啥我的 FileProvider 在 android studio 中不起作用

Posted

技术标签:

【中文标题】为啥我的 FileProvider 在 android studio 中不起作用【英文标题】:Why my FileProvider not works in android studio为什么我的 FileProvider 在 android studio 中不起作用 【发布时间】:2020-01-16 15:56:57 【问题描述】:

https://developer.android.com/training/camera/photobasics.html

res/xml/file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="Android/data/com.apsm.package.name/files/Pictures" />
</paths>

我首先尝试了这个 Manifest(Old Android Manifest):

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

在该清单中,content.FileProvider 出现错误

我添加了所有的实现:

implementation 'com.android.support:support-v4:26.1.0'
implementation 'com.android.support:support-compat:28.0.0'
implementation 'com.android.support:support-core-ui:28.0.0'
implementation 'com.android.support:support-core-utils:28.0.0'
implementation 'com.android.support:support-media-compat:28.0.0'
implementation 'com.android.support:support-fragment:28.0.0'

但不起作用

现在尝试为此更改清单(新清单)

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="$applicationId.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

但我收到了错误:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.apsm, PID: 3254
java.lang.IllegalStateException: Could not execute method for android:onClick
    at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:390)
    at android.view.View.performClick(View.java:6297)
    at android.view.View$PerformClick.run(View.java:24797)
    at android.os.Handler.handleCallback(Handler.java:790)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6626)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)
 Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invoke(Native Method)
    at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
    at android.view.View.performClick(View.java:6297) 
    at android.view.View$PerformClick.run(View.java:24797) 
    at android.os.Handler.handleCallback(Handler.java:790) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:164) 
    at android.app.ActivityThread.main(ActivityThread.java:6626) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811) 
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference
    at androidx.core.content.FileProvider.parsePathStrategy(FileProvider.java:605)
    at androidx.core.content.FileProvider.getPathStrategy(FileProvider.java:579)
    at androidx.core.content.FileProvider.getUriForFile(FileProvider.java:417)
    at com.apsm.CadastrarNovaLocalizacao.tirarFoto(CadastrarNovaLocalizacao.java:99)
    at java.lang.reflect.Method.invoke(Native Method)
    at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385) 
    at android.view.View.performClick(View.java:6297) 
    at android.view.View$PerformClick.run(View.java:24797) 
    at android.os.Handler.handleCallback(Handler.java:790) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:164) 
    at android.app.ActivityThread.main(ActivityThread.java:6626) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811) 

static final int REQUEST_IMAGE_CAPTURE = 1;
static final int REQUEST_TAKE_PHOTO = 1;
String currentPhotoPath;

private File createImageFile() throws IOException 
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "POSTO_" + timeStamp + "_";
        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );

        // Save a file: path for use with ACTION_VIEW intents
        currentPhotoPath = image.getAbsolutePath();
        return image;
    

public void tirarFoto(View v) 
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) 
        // Create the File where the photo should go
        File photoFile = null;
        try 
            photoFile = createImageFile();
         catch (IOException ex) 
            // Error occurred while creating the File
        
        // Continue only if the File was successfully created
        if (photoFile != null) 
            Uri photoURI = FileProvider.getUriForFile(this, // ERROR HERE
                    "com.apsm.android.fileprovider",
                    photoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
        
    

【问题讨论】:

看看这个***.com/questions/43425131/… 【参考方案1】:

您的android:authorities 值与您提供给FileProvider.getUriForFile() 的值不匹配。

在您最初的尝试中,com.example.android.fileprovidercom.apsm.android.fileprovider 不同。

在您的第二次尝试中,$applicationId.fileprovider 显然与 com.apsm.android.fileprovider 不同。

通常,我们采用第二种方法($applicationId.fileprovider 代表 android:authorities)。为确保您的 Java 代码匹配,请使用 BuildConfig.APPLICATION_ID + ".fileprovider" 获取等效值以传递给 FileProvider.getUriForFile()

FWIW,this sample app(来自this book)展示了如何设置FileProvider

【讨论】:

以上是关于为啥我的 FileProvider 在 android studio 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

ClassNotFoundException:在 androidx 迁移后找不到类“android.support.v4.content.FileProvider”

FileProvider在GetUriForFile上抛出异常

Intent 常用场景 FileProvider 拍照 裁剪

FileProvider.getUriForFile返回null对象引用

使用 FileProvider 共享缓存的图像

java.lang.ClassNotFoundException:在Adone AIR本机扩展中未找到类“android.support.v4.content.FileProvider”错误(示例代码