0

有人告诉我,这可能是因为如果 targetSdkVersion >= Android 6.0(API 级别 23),开发人员需要在运行时添加一些代码来请求用户的相关权限。

“如果你还想实现‘打开相机/拍照’功能,你应该在运行时请求CAMERA的拍照权限和存储相关的图片保存权限。也许可以使用FileProvider来存储图片。”

如何在我的项目中实施这个建议?

这是我的 SelectImageActivity,其中 TAKEPICTURE 的代码涉及

package com.microsoft.projectoxford.face.samples.ui;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;

import com.microsoft.projectoxford.face.samples.R;

import java.io.File;
import java.io.IOException;

// The activity for the user to select a image and to detect faces in the image.
public class SelectImageActivity extends AppCompatActivity {
    // Flag to indicate the request of the next task to be performed
    private static final int REQUEST_TAKE_PHOTO = 0;
    private static final int REQUEST_SELECT_IMAGE_IN_ALBUM = 1;

    // The URI of photo taken with camera
    private Uri mUriPhotoTaken;

    // When the activity is created, set all the member variables to initial state.
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_select_image);
    }

    // Save the activity state when it's going to stop.
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable("ImageUri", mUriPhotoTaken);
    }

    // Recover the saved state when the activity is recreated.
    @Override
    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        mUriPhotoTaken = savedInstanceState.getParcelable("ImageUri");
    }

    // Deal with the result of selection of the photos and faces.
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode)
        {
            case REQUEST_TAKE_PHOTO:
            case REQUEST_SELECT_IMAGE_IN_ALBUM:
                if (resultCode == RESULT_OK) {
                    Uri imageUri;
                    if (data == null || data.getData() == null) {
                        imageUri = mUriPhotoTaken;
                    } else {
                        imageUri = data.getData();
                    }
                    Intent intent = new Intent();
                    intent.setData(imageUri);
                    setResult(RESULT_OK, intent);
                    finish();
                }
                break;
            default:
                break;
        }
    }

    // When the button of "Take a Photo with Camera" is pressed.
    public void takePhoto(View view) {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if(intent.resolveActivity(getPackageManager()) != null) {
            // Save the photo taken to a temporary file.
            File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
            try {
                File file = File.createTempFile("IMG_", ".jpg", storageDir);
                mUriPhotoTaken = Uri.fromFile(file);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, mUriPhotoTaken);
                startActivityForResult(intent, REQUEST_TAKE_PHOTO);
            } catch (IOException e) {
                setInfo(e.getMessage());
            }
        }
    }

    // When the button of "Select a Photo in Album" is pressed.
    public void selectImageInAlbum(View view) {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("image/*");
        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(intent, REQUEST_SELECT_IMAGE_IN_ALBUM);
        }
    }

    // Set the information panel on screen.
    private void setInfo(String info) {
        TextView textView = (TextView) findViewById(R.id.info);
        textView.setText(info);
    }
}

这是我的构建 gradle (:app)

apply plugin: 'com.android.application'

android {

    compileSdkVersion 28


    defaultConfig {
        applicationId "com.microsoft.projectoxford.faceapisample"
        minSdkVersion 22
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
    }


    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')

    // Include local lib mostly for debug purpose.
    // implementation project(':lib')

    // Use the following line to include client library for Face API from Maven Central Repository

    implementation 'com.microsoft.projectoxford:face:1.4.4'
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.google.code.gson:gson:2.8.5'
    implementation 'com.android.support.constraint:constraint-layout:2.0.4'

    compile project(':voicetwo')
    implementation project(':voicetwo')


}

我的错误日志:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.microsoft.projectoxford.faceapisample, PID: 16272
    java.lang.IllegalStateException: Could not execute method for android:onClick
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:390)
        at android.view.View.performClick(View.java:7167)
        at android.view.View.performClickInternal(View.java:7140)
        at android.view.View.access$3500(View.java:813)
        at android.view.View$PerformClick.run(View.java:27597)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:224)
        at android.app.ActivityThread.main(ActivityThread.java:7519)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
        at android.view.View.performClick(View.java:7167) 
        at android.view.View.performClickInternal(View.java:7140) 
        at android.view.View.access$3500(View.java:813) 
        at android.view.View$PerformClick.run(View.java:27597) 
        at android.os.Handler.handleCallback(Handler.java:883) 
        at android.os.Handler.dispatchMessage(Handler.java:100) 
        at android.os.Looper.loop(Looper.java:224) 
        at android.app.ActivityThread.main(ActivityThread.java:7519) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995) 
     Caused by: android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/com.microsoft.projectoxford.faceapisample/files/Pictures/IMG_2029674407291738623.jpg exposed beyond app through ClipData.Item.getUri()
        at android.os.StrictMode.onFileUriExposed(StrictMode.java:2089)
        at android.net.Uri.checkFileUriExposed(Uri.java:2388)
        at android.content.ClipData.prepareToLeaveProcess(ClipData.java:977)
        at android.content.Intent.prepareToLeaveProcess(Intent.java:10780)
        at android.content.Intent.prepareToLeaveProcess(Intent.java:10765)
        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1710)
        at android.app.Activity.startActivityForResult(Activity.java:5258)
        at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:767)
        at android.app.Activity.startActivityForResult(Activity.java:5216)
        at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:754)
        at com.microsoft.projectoxford.face.samples.ui.SelectImageActivity.takePhoto(SelectImageActivity.java:103)
        at java.lang.reflect.Method.invoke(Native Method) 
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385) 
        at android.view.View.performClick(View.java:7167) 
        at android.view.View.performClickInternal(View.java:7140) 
        at android.view.View.access$3500(View.java:813) 
        at android.view.View$PerformClick.run(View.java:27597) 
        at android.os.Handler.handleCallback(Handler.java:883) 
        at android.os.Handler.dispatchMessage(Handler.java:100) 
        at android.os.Looper.loop(Looper.java:224) 
        at android.app.ActivityThread.main(ActivityThread.java:7519) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995) 
E/MQSEventManagerDelegate: failed to get MQSService.
D/OOMEventManagerFK: checkEventAndDumpForJE: 0
E/MQSEventManagerDelegate: failed to get MQSService.

com.microsoft.projectoxford.face.samples.ui.SelectImageActivity.takePhoto(SelectImageActivity.java:103) 错误日志中的行是

startActivityForResult(intent, REQUEST_TAKE_PHOTO);
4

0 回答 0