Android:如何在android牛轧糖

时间:2017-03-30 05:29:44

标签: android android-intent camera android-7.0-nougat

在我的Android应用程序中,我必须使用相机按钮单击拍摄图像。它在所有Android版本中工作完美除了android 7(Nougat)。当我点击相机选项时,即使权限打开,应用程序也会退出。我认为问题出在相机调用intent.Below是我的代码。

    camera = (ImageView) dialog.findViewById(R.id.camera);

camera.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        clickCamera();
        dialog.dismiss();
    }
});

private void clickCamera() { // 1 for icon and 2 for attachment
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.CAMERA},MY_REQUEST_CODE);
    }else {
        if (ActivityCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_REQUEST_CODE_STORAGE);
        }else{
            currentImageUri = getImageFileUri();
            Intent intentPicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            intentPicture.putExtra(MediaStore.EXTRA_OUTPUT, currentImageUri); // set the image file name
            // start the image capture Intent
            startActivityForResult(intentPicture, REQUEST_CAMERA);  // 1 for REQUEST_CAMERA and 2 for REQUEST_CAMERA_ATT
        }
    }
}

private static Uri getImageFileUri(){
    // Create a storage directory for the images
    // To be safe(er), you should check that the SDCard is mounted
    // using Environment.getExternalStorageState() before doing this

    imagePath = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyProject");
    if (! imagePath.exists()){
        if (! imagePath.mkdirs()){
            return null;
        }else{
            //create new folder
        }
    }

    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File image = new File(imagePath,"MyProject_"+ timeStamp + ".jpg");

    if(!image.exists()){
        try {
            image.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // Create an File Uri
    return Uri.fromFile(image);
}


@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_REQUEST_CODE: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // permission was granted, yay! Do the
            // contacts-related task you need to do.
                if (ActivityCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_REQUEST_CODE_STORAGE);
                }else{
                    currentImageUri = getImageFileUri();
                    Intent intentPicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    intentPicture.putExtra(MediaStore.EXTRA_OUTPUT, currentImageUri); // set the image file name
                    // start the image capture Intent
                    startActivityForResult(intentPicture, REQUEST_CAMERA);
                }
            } else {
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
                Toast.makeText(this,"Doesn't have permission... ", Toast.LENGTH_SHORT).show();
            }
            return;
        }
        case MY_REQUEST_CODE_STORAGE : {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                currentImageUri = getImageFileUri();
                Intent intentPicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                intentPicture.putExtra(MediaStore.EXTRA_OUTPUT, currentImageUri); // set the image file name
                // start the image capture Intent
                startActivityForResult(intentPicture, REQUEST_CAMERA);
            } else {
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
                Toast.makeText(this,"Doesn't have permission...", Toast.LENGTH_SHORT).show();
            }
            return;
        }
    }
}

Nougat的问题是什么。是因为getImageFileUri()返回的uri?请帮我解决这个问题。

5 个答案:

答案 0 :(得分:6)

嘿,请关注this thread作为参考。当您将targetSDK设置为24并更改以下内容时,它将向您展示如何使用文件提供程序。在private static Uri getImageFileUri()方法

更改此行

return Uri.fromFile(image);

FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", createImageFile());

希望这可以帮助您解决问题。
更多信息,请访问 - Setting Up File Sharing - Offical documentation

答案 1 :(得分:5)

尝试这不是创造问题的意图,一旦你拍照并保存到SD卡并且回到uri在Nougat中是不同的....

在您的应用程序上实现FileProvider非常容易。首先,您需要在AndroidManifest.xml中的标签下添加一个FileProvider标签,如下所示:AndroidManifest.xml

select [Pers#No#], 
        stuff(( Select distinct ', ' + 
                        cast( [Bank Account] as varchar(20) ) +  ' ' + 
                        cast( [Bank Keys] as varchar(20) )      
                FROM     [DATA].[dbo].[PA0009]                  as      S
                where   S.[Pers#No#] = T.[Pers#No#]
                For     XML PATH('')),1,1,''    )  as whatever
from    [DATA].[dbo].[PA0009]  
group by [Pers#No#] 

然后在res文件夹下的xml文件夹中创建一个provider_paths.xml文件。如果文件夹不存在,可能需要创建文件夹。

RES / XML / provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    <application
        ...
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>
    </application>
</manifest>

完成! FileProvider现已声明并可以使用。

最后一步是在MainActivity.java中更改下面的代码行

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

Uri photoURI = Uri.fromFile(createImageFile());

......完成了!您的应用程序现在可以在包括Android Nougat在内的任何Android版本上完美运行。干杯!

答案 2 :(得分:4)

Android的工作就是让每个更新都让开发人员过上生活的地狱:)

googlers,这是一个循序渐进的指南,供开发人员(比如问题)使用Android文档中的示例;

1-在您使用的部分

Uri.fromFile(image)

您需要使用此代码段:

Uri photoURI = FileProvider.getUriForFile(mContext,
                        "com.sample.test.fileprovider",
                        image);

当然不用说,您必须将com.sample.test更改为您的包名。

2-现在您需要在AndroidManifest.xml中声明您的提供者,在Application标签下粘贴此标记:

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

3-注意android:resource="@xml/file_paths"您需要在file_paths文件夹下创建一个名称为res/xml/的xml文件并将其放入其中:

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

关于网络上的其他几个片段,以及文档本身,它说你需要写这个

<external-path name="my_images" path="Android/data/com.example.package.name/files/Pictures" />

而不是我们的,它实际上取决于您的代码,如果您使用Environment.getExternalStorageDirectory().getPath()创建文件而您不需要它,但如果您完全按照文档进行操作,则需要坚持使用文档

答案 3 :(得分:1)

此处修复了7.0版本中的相机意图问题

file://不允许(Android N)与Intent连接或者它将会附加 抛出FileUriExposedException,这可能会导致您的应用程序立即被调用崩溃。

请检查问题的全部细节&amp;溶液

Soltution

答案 4 :(得分:-1)

使用文件提供程序,它会帮助您