博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android 崩溃捕获_Android使用FileProvider捕获图像相机图库
阅读量:2533 次
发布时间:2019-05-11

本文共 10256 字,大约阅读时间需要 34 分钟。

android 崩溃捕获

In this tutorial, we’ll be developing an application which displays images captured from camera or gallery using FileProvider. We’ve already developed a in the past. But with the introduction of Android Nougat, it gives a runtime crash saying FileUriExposedException.

在本教程中,我们将开发一个应用程序,该应用程序显示使用FileProvider从相机或画廊捕获的图像。 过去我们已经开发了 。 但是随着Android Nougat的引入,它给出了FileUriExposedException这样的运行时崩溃信息。

文件提供者 (FileProvider)

FileProvider is a special subclass of ContentProvider which allows sharing of files between application through content URI instead of file:// URI.

FileProvider是ContentProvider的特殊子类,它允许通过内容URI(而不是file:// URI)在应用程序之间共享文件。

Using file:// URI is not the best idea. It gives all apps the permission to access the files once the Storage Permissions are granted.

使用file:// URI并不是最好的主意。 授予存储权限后,它将为所有应用程序授予访问文件的权限。

We somehow need to restrict this such that the user knows the applications with which it would be sharing the files.

我们需要以某种方式进行限制,以使用户知道与之共享文件的应用程序。

For this, we use FileProviders which allow temporary access permissions to the files. Otherwise, we were able to access files from other apps by simply getting their URI from Uri.parse()

为此,我们使用FileProviders ,它们允许对文件的临时访问权限。 否则,我们只需从Uri.parse()获取其URI,便能够从其他应用访问文件。

WRITE_EXTERNAL_STORAGE permission everytime.
WRITE_EXTERNAL_STORAGE权限。

定义FileProvider (Defining FileProvider)

To define a FileProvider in our android application, we need to do the following things:

要在我们的android应用程序中定义FileProvider,我们需要做以下事情:

  • Define the FileProvider in your AndroidManifest file

    在您的AndroidManifest文件中定义FileProvider
  • Create an XML file that contains all paths that the FileProvider will share with other applications

    创建一个XML文件,其中包含FileProvider将与其他应用程序共享的所有路径

Create an xml folder inside the res directory.

Add the provider_paths.xml file in it:

在res目录中创建一个xml文件夹。

在其中添加provider_paths.xml文件:

Depending on the storage we need to access, we pass the value in the external-path.

Example of other values that can be passed – sdcard

根据我们需要访问的存储,我们在外部路径中传递值。

可以传递的其他值的示例– sdcard

Now let’s write our Version 2.0 Application of Capturing Image from Camera And Gallery that works on Android Nougat and above.

现在,让我们编写适用于Android Nougat及更高版本的从Camera and Gallery捕获图像的2.0版应用程序。

项目结构 (Project Structure)

The AndroidManifest.xml with all the permissions looks like:

具有所有权限的AndroidManifest.xml如下所示:

(Code)

The code for the activity_main.xml layout is:

activity_main.xml布局的代码为:

The code for the MainActivity.java is given below:

MainActivity.java的代码如下:

package com.journaldev.androidfileprovidercameragallery;import android.annotation.TargetApi;import android.app.Activity;import android.content.ComponentName;import android.content.DialogInterface;import android.content.Intent;import android.content.pm.PackageManager;import android.content.pm.ResolveInfo;import android.database.Cursor;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.net.Uri;import android.os.Build;import android.os.Bundle;import android.os.Parcelable;import android.provider.MediaStore;import android.support.design.widget.FloatingActionButton;import android.support.v7.app.AlertDialog;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.ImageView;import java.io.File;import java.util.ArrayList;import java.util.List;import static android.Manifest.permission.CAMERA;import static android.Manifest.permission.READ_EXTERNAL_STORAGE;import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;public class MainActivity extends AppCompatActivity {    Uri picUri;    private ArrayList
permissionsToRequest; private ArrayList
permissionsRejected = new ArrayList<>(); private ArrayList
permissions = new ArrayList<>(); private final static int ALL_PERMISSIONS_RESULT = 107; private final static int IMAGE_RESULT = 200; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FloatingActionButton fab = findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startActivityForResult(getPickImageChooserIntent(), IMAGE_RESULT); } }); permissions.add(CAMERA); permissions.add(WRITE_EXTERNAL_STORAGE); permissions.add(READ_EXTERNAL_STORAGE); permissionsToRequest = findUnAskedPermissions(permissions); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (permissionsToRequest.size() > 0) requestPermissions(permissionsToRequest.toArray(new String[permissionsToRequest.size()]), ALL_PERMISSIONS_RESULT); } } public Intent getPickImageChooserIntent() { Uri outputFileUri = getCaptureImageOutputUri(); List
allIntents = new ArrayList<>(); PackageManager packageManager = getPackageManager(); Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); List
listCam = packageManager.queryIntentActivities(captureIntent, 0); for (ResolveInfo res : listCam) { Intent intent = new Intent(captureIntent); intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name)); intent.setPackage(res.activityInfo.packageName); if (outputFileUri != null) { intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); } allIntents.add(intent); } Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT); galleryIntent.setType("image/*"); List
listGallery = packageManager.queryIntentActivities(galleryIntent, 0); for (ResolveInfo res : listGallery) { Intent intent = new Intent(galleryIntent); intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name)); intent.setPackage(res.activityInfo.packageName); allIntents.add(intent); } Intent mainIntent = allIntents.get(allIntents.size() - 1); for (Intent intent : allIntents) { if (intent.getComponent().getClassName().equals("com.android.documentsui.DocumentsActivity")) { mainIntent = intent; break; } } allIntents.remove(mainIntent); Intent chooserIntent = Intent.createChooser(mainIntent, "Select source"); chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, allIntents.toArray(new Parcelable[allIntents.size()])); return chooserIntent; } private Uri getCaptureImageOutputUri() { Uri outputFileUri = null; File getImage = getExternalFilesDir(""); if (getImage != null) { outputFileUri = Uri.fromFile(new File(getImage.getPath(), "profile.png")); } return outputFileUri; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) { ImageView imageView = findViewById(R.id.imageView); if (requestCode == IMAGE_RESULT) { String filePath = getImageFilePath(data); if (filePath != null) { Bitmap selectedImage = BitmapFactory.decodeFile(filePath); imageView.setImageBitmap(selectedImage); } } } } private String getImageFromFilePath(Intent data) { boolean isCamera = data == null || data.getData() == null; if (isCamera) return getCaptureImageOutputUri().getPath(); else return getPathFromURI(data.getData()); } public String getImageFilePath(Intent data) { return getImageFromFilePath(data); } private String getPathFromURI(Uri contentUri) { String[] proj = {MediaStore.Audio.Media.DATA}; Cursor cursor = getContentResolver().query(contentUri, proj, null, null, null); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putParcelable("pic_uri", picUri); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); // get the file url picUri = savedInstanceState.getParcelable("pic_uri"); } private ArrayList
findUnAskedPermissions(ArrayList
wanted) { ArrayList
result = new ArrayList
(); for (String perm : wanted) { if (!hasPermission(perm)) { result.add(perm); } } return result; } private boolean hasPermission(String permission) { if (canMakeSmores()) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { return (checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED); } } return true; } private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) { new AlertDialog.Builder(this) .setMessage(message) .setPositiveButton("OK", okListener) .setNegativeButton("Cancel", null) .create() .show(); } private boolean canMakeSmores() { return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1); } @TargetApi(Build.VERSION_CODES.M) @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case ALL_PERMISSIONS_RESULT: for (String perms : permissionsToRequest) { if (!hasPermission(perms)) { permissionsRejected.add(perms); } } if (permissionsRejected.size() > 0) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (shouldShowRequestPermissionRationale(permissionsRejected.get(0))) { showMessageOKCancel("These permissions are mandatory for the application. Please allow access.", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(permissionsRejected.toArray(new String[permissionsRejected.size()]), ALL_PERMISSIONS_RESULT); } } }); return; } } } break; } }}

Following is are the methods which get the content uri from the filepath provided that the FileProvider has granted the appropriate permissions:

以下是在FileProvider授予适当权限的情况下从文件路径获取内容uri的方法:

The output of the above application in action is given below:

上面应用程序的输出如下:

This brings an end to this tutorial. You can download the project from the link below:

本教程到此结束。 您可以从下面的链接下载项目:

翻译自:

android 崩溃捕获

转载地址:http://zcqzd.baihongyu.com/

你可能感兴趣的文章
UI基础--烟花动画
查看>>
2018. 2.4 Java中集合嵌套集合的练习
查看>>
精通ASP.NET Web程序测试
查看>>
vue 根据不同属性 设置背景
查看>>
51Nod1601 完全图的最小生成树计数 Trie Prufer编码
查看>>
Codeforces 1110D. Jongmah 动态规划
查看>>
android驱动在win10系统上安装的心酸历程
查看>>
优雅的程序员
查看>>
oracle之三 自动任务调度
查看>>
Android dex分包方案
查看>>
ThreadLocal为什么要用WeakReference
查看>>
删除本地文件
查看>>
FOC实现概述
查看>>
base64编码的图片字节流存入html页面中的显示
查看>>
这个大学时代的博客不在维护了,请移步到我的新博客
查看>>
GUI学习之二十一——QSlider、QScroll、QDial学习总结
查看>>
nginx反向代理docker registry报”blob upload unknown"解决办法
查看>>
gethostbyname与sockaddr_in的完美组合
查看>>
kibana的query string syntax 笔记
查看>>
旋转变换(一)旋转矩阵
查看>>