SolutionCouldn’t find meta-data for provider with authority

Today, when I reused the code related to installing the APK that I wrote before, an error occurred. That is because the higher version of Android requires a new FileProvider.

New file_paths

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- <root-path
            name="root"
            path="" />-->
    <files-path
        name="files"
        path="files" />
    <cache-path
        name="cache"
        path="files" />
<!-- <external-path
        name="external"
        path="files" />-->
    <external-files-path
        name="externalfiles"
        path="files" />
    <!-- This tag requires support 25.0.0 or above to be used -->
    <external-cache-path
        name="externalcache"
        path="files" />
    <external-path
        name="external_storage_root"
        path="." />

</paths>

Other writing methods






The address corresponding to the tag

The physical path is equivalent to Context.getFilesDir() + /path/
The physical path is equivalent to Context.getCacheDir() + /path/

The physical path is equivalent to Environment.getExternalStorageDirectory() + /path/

The physical path is equivalent to **Context.getExternalFilesDir(String) ** + /path/

The physical path is equivalent to Context.getExternalCacheDir() + /path/
The physical path is equivalent to /path/
Example:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <!-- /storage/emulated/0/Android/data/com.test.dust/files/resources/map/tiles/1.0.8.rar
===> content://com.test.dust.provider/map_tiles/1.0.8.rar-->
    <external-files-path
        name="map_tiles"
        path="resources/map/tiles" />
</paths>

The file path corresponding to external-files-path is /storage/emulated/0/Android/data/[packageName]/files
The entire external-files-path tag is equivalent to formatting the absolute path /storage/emulated/0/Android/data/[packageName]/files/[path]/filename into content://[authorities]/[name] /filename form.

New provider
Add the following code in of Manifest.xml

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

Quote

APK installation

 public static void installApk(Context context,String downloadApk) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        File file = new File(downloadApk);
        //L.i("Installation path==" + downloadApk);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            Uri apkUri = FileProvider.getUriForFile
(Objects.requireNonNull(context), BuildConfig.APPLICATION_ID +
BuildConfig.APPLICATION_ID + ".utilcode.fileProvider", file);//This sentence is very important
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        } else {
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            Uri uri = Uri.fromFile(file);
            intent.setDataAndType(uri, "application/vnd.android.package-archive");
        }
        context.startActivity(intent);

    }

Adaptation

 private void installApp() {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        File file = new File(FileUtils.mkdirs(DirKeys.DIR_APP_UPDATE) + "/test.apk");
        Uri apkUri = FileProvider.getUriForFile(this,
                BuildConfig.APPLICATION_ID + ".utilcode.fileProvider", file);//This sentence is very important
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            LogUtils.e("lcb", "sdk:" + Build.VERSION.SDK_INT + "Go here");
            intent.setAction(Intent.ACTION_INSTALL_PACKAGE);
            intent.setData(apkUri);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
            intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true);
            intent.putExtra(Intent.EXTRA_ALLOW_REPLACE, true);
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        } else {
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            Uri uri = Uri.fromFile(file);
            intent.setDataAndType(uri, "application/vnd.android.package-archive");
        }
        startActivity(intent);
    }

android11 calls camera

The camera code that needs to be used in the project is as follows:

public static void startCarmera(Fragment fragment) {
    Uri uri;
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        uri = FileProvider.getUriForFile(fragment.getActivity(),
BuildConfig.APPLICATION_ID + ".utilcode.fileProvider", getFile());
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
    } else {
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getFile()));
    }
    fragment.startActivityForResult(intent, RESULT_CAMERA);
}

File newFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+ “/images/” + System.currentTimeMillis() + “.jpg”);
if (!newFile.exists()) {
newFile.getParentFile().mkdirs();
}
mCurrentPhotoPath = newFile.getAbsolutePath();
return newFile;
}

The album code that needs to be used in the project is as follows:

public static void startGallery(Activity activity) {
    Intent intentGallery = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    activity.startActivityForResult(intentGallery, RESULT_GALLERY);
}

Processing the returned image in onActivityResult():

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
       if (requestCode == RESULT_CAMERA) {
            upload(CarmeraUtil.mCurrentPhotoPath);
        } else if (requestCode == RESULT_GALLERY & amp; & amp; data != null) {
            //Process photos from the gallery
            Uri selectedImage = data.getData();
            String[] filePathColumn = {MediaStore.Images.Media.DATA};
            Cursor cursor = getContentResolver().query(selectedImage,
                    filePathColumn, null, null, null);
            cursor.moveToFirst();
            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String picturePath = cursor.getString(columnIndex);
            cursor.close();
            upload(picturePath);
        }
    }
}

Remember to add installation permissions