经过一个小时的不断试错,发现网上说的什么mutiDex那些简直是瞎扯。
真正的解决办法是在AndroidManifest.xml中的provider的android:name设置为"androidx.core.content.FileProvider",不要再傻傻的去加什么compile鬼东西了。
下面附上一个调用相机获取图片的完整可用程序。
界面布局:一个ImageView和一个Button。只有一个Activity叫MainActivity。
在res文件夹下创建一个xml文件夹,里面创建一个名字叫file_paths.xml的文件
file_paths.xml
注意:
如果图片位置是在getFilesDir()下任意位置的话(我这个程序就是),节点类型就是files-path;
如果图片位置是在getFilesDir()下任意位置的话,节点类型就是external-path。
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="external_files" path="." />
</paths>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cyy.camera">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.cyy.camera.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths">
</meta-data>
</provider>
</application>
</manifest>
MainActivity.java
package com.cyy.camera;
import android.Manifest;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import static androidx.core.content.PermissionChecker.PERMISSION_GRANTED;
public class MainActivity extends AppCompatActivity {
private ImageView imageView;
private static int GET_PHOTO=0;
private Uri fileUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
button.setOnClickListener(new TakePhoto());
imageView=findViewById(R.id.imageView);
RequestPermission();
}
private void RequestPermission(){
String[] permissions=new String[]{
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.INTERNET,
Manifest.permission.READ_EXTERNAL_STORAGE
};
for (String permission : permissions) {
if ((ContextCompat.checkSelfPermission(this, permission) != PERMISSION_GRANTED)) {
ActivityCompat.requestPermissions(this, permissions, 0);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
for (int i=0;i<permissions.length;i++){
String permission=permissions[i];
if(!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,permission)){
AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this);
builder.setTitle("提醒");
builder.setMessage("请去往设置页为本程序授予权限,否则将无法使用");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
System.exit(0);
}
});
AlertDialog alertDialog=builder.create();
alertDialog.setCanceledOnTouchOutside(false);
return;
}
else if(grantResults[i]!=PERMISSION_GRANTED){
AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this);
builder.setTitle("提醒");
builder.setMessage("请授予权限,否则将无法使用程序");
builder.setPositiveButton("确定",null);
builder.create().show();
return;
}
}
}
private class TakePhoto implements View.OnClickListener{
@Override
public void onClick(View v) {
File imageFile=new File(getFilesDir(),"CameraApp/abc.jpg");
try {
File dir=new File(getFilesDir(),"CameraApp");
if(!dir.exists()){
if(!dir.mkdirs()){
Toast.makeText(MainActivity.this, "无法创建缓存文件", Toast.LENGTH_LONG).show();
return;
}
}
Toast.makeText(MainActivity.this,dir.toString(),Toast.LENGTH_LONG).show();
while(!imageFile.createNewFile()){
if(!imageFile.delete()){
Toast.makeText(MainActivity.this, "无法创建缓存文件", Toast.LENGTH_LONG).show();
return;
}
}
Intent intent=new Intent("android.media.action.IMAGE_CAPTURE");
fileUri= FileProvider.getUriForFile(MainActivity.this,"com.cyy.camera.provider",imageFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT,fileUri);
startActivityForResult(intent,GET_PHOTO);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (requestCode == GET_PHOTO) {
try {
Bitmap bitmap= BitmapFactory.decodeStream(getContentResolver().openInputStream(fileUri));
imageView.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
}
谷歌越更新越复杂,适配的版本越多,真希望统一一下标准,以后就别改了。