【问题标题】:Select picture from gallery function after hitting the 'UPLOAD PICTURE' and display the picture in imageView点击“上传图片”后从图库功能中选择图片并在 imageView 中显示图片
【发布时间】:2020-11-19 08:48:03
【问题描述】:

我想让用户在点击“上传图片”按钮后从图库中选择一张图片,但我的代码似乎无法正常工作。用户选择所需图片后,应用程序立即崩溃。

这是我在 MainActivity 中的 OnCreate 代码:

public static final int RESULT_LOAD_IMAGE = 100;
private final int PICK_IMAGE = 1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

faceServiceClient = new FaceServiceRestClient("INSERT ENDPOINT HERE", 
"INSERT API KEY HERE");

    takePicture = findViewById(R.id.takePic);
    imageView = findViewById(R.id.imageView);
    hidden = findViewById(R.id.hidden);
    imageView.setVisibility(View.INVISIBLE);
    uploadPicture = findViewById(R.id.uploadPic);
    process = findViewById(R.id.processClick);


    takePicture.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
            } else {
                //IMPORTANT: You may notice that the pictures from the camera are low quality.
                //TO FIX THIS: You need to request permission to write external storage that way you can access the full-quality image
                //from the device, rather than a low quality thumbnail.
                if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                        == PackageManager.PERMISSION_GRANTED) {
                    values = new ContentValues();
                    values.put(MediaStore.Images.Media.TITLE, "New Picture");
                    values.put(MediaStore.Images.Media.DESCRIPTION, "From your Camera");
                    imageUri = getContentResolver().insert(
                            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                    startActivityForResult(intent, 100);
                } else {
                    if (counter == 2 || (counter > 2 && counter % 2 == 0)) {
                        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        startActivityForResult(intent, 1);
                    } else                         //Requesting storage permissions so we can get a high quality image.
                        ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
                    counter++;
                    
                }
            }
        }
    });

    uploadPicture.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
            intent.setType("image/*");
            startActivityForResult(Intent.createChooser(
                    intent, "Select Picture"), PICK_IMAGE);
        }


    });

    process.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (ready) {
                detectandFrame(mBitmap);
            } else {
                makeToast("Please take a picture.");
            }
        }
    });
   
}

这是我在 MainActivity 中的 onActivityResult:

Uri imageUri;
ContentValues values;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 100) { //High Quality picture using URI and storage
        if (resultCode == RESULT_OK) {
            imageView.setVisibility(View.VISIBLE);
            try {
                mBitmap = MediaStore.Images.Media.getBitmap(
                        getContentResolver(), imageUri);

                Bitmap rotatedBitmap = mBitmap;
                ExifInterface ei = new ExifInterface(getRealPathFromURI(imageUri));
                int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                        ExifInterface.ORIENTATION_UNDEFINED);

                switch (orientation) {

                    case ExifInterface.ORIENTATION_ROTATE_90:
                        rotatedBitmap = rotateImage(mBitmap, 90);
                        break;

                    case ExifInterface.ORIENTATION_ROTATE_180:
                        rotatedBitmap = rotateImage(mBitmap, 180);
                        break;

                    case ExifInterface.ORIENTATION_ROTATE_270:
                        rotatedBitmap = rotateImage(mBitmap, 270);
                        break;

                    case ExifInterface.ORIENTATION_NORMAL:
                    default:
                        rotatedBitmap = mBitmap;
                }
                imageView.setImageBitmap(rotatedBitmap);

            } catch (IOException e) {
                //Error getting high quality image --> Use low quality thumbnail.
                makeToast("Error: " + e.toString());
                //mBitmap = (Bitmap) data.getExtras().get("data");
                e.printStackTrace();
                imageView.setImageBitmap(mBitmap);
            }
            ready = true;
            hidden.setVisibility(View.INVISIBLE);
        }
    }else if(requestCode == 1 && resultCode == RESULT_OK){
        //Low Quality image
        imageView.setVisibility(View.VISIBLE);
        mBitmap = (Bitmap) data.getExtras().get("data");
        imageView.setImageBitmap(mBitmap);
        ready = true;
        hidden.setVisibility(View.INVISIBLE);
    }

    if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
        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();

    }

    if (requestCode == PICK_IMAGE && resultCode == RESULT_OK &&
            data != null && data.getData() != null) {
        Uri uri = data.getData();
        try {
            imageView.setVisibility(View.VISIBLE);
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(
                    getContentResolver(), uri);
            ImageView imageView = findViewById(R.id.imageView);
            imageView.setImageBitmap(bitmap);
            ready = true;
            hidden.setVisibility(View.INVISIBLE);
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public String getRealPathFromURI(Uri uri) {
    Cursor cursor = getContentResolver().query(uri, null, null, null, null);
    cursor.moveToFirst();
    int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
    return cursor.getString(idx);
}

public static Bitmap rotateImage(Bitmap source, float angle) {
    Matrix matrix = new Matrix();
    matrix.postRotate(angle);
    return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(),
            matrix, true);
}

}

这是我的 AndroidManifest.xml 代码。我意识到,当我在清单中包含“WRITE_EXTERNAL_STORAGE”时,我的从相机拍照功能在点击处理按钮后不起作用。它会在很长一段时间内显示“检测”并在之后崩溃。所以不会显示结果。但是,在我删除清单中的“WRITE_EXTERNAL_STORAGE”后,它可以正常显示结果。但是在用户选择一张图片后,从图库中的选择仍然崩溃。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.anany.emotionrecognition">

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.CAMERA"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>

<application
    android:allowBackup="true"
    android:icon="@drawable/smiling"
    android:label="@string/app_name"
    android:roundIcon="@drawable/smiling"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <uses-library android:name="org.apache.http.legacy" android:required="false" />

    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".ResultActivity"></activity>
</application>

这是我的错误日志。

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.anany.emotionrecognition, PID: 30227
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { dat=content://com.miui.gallery.open/raw//storage/emulated/0/WhatsApp/Media/WhatsApp Images/IMG-20201016-WA0028.jpg typ=image/jpeg flg=0x1 }} to activity {com.example.anany.emotionrecognition/com.example.anany.emotionrecognition.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.os.Bundle.get(java.lang.String)' on a null object reference
    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.os.Bundle.get(java.lang.String)' on a null object reference
    at com.example.anany.emotionrecognition.MainActivity.onActivityResult(MainActivity.java:216)
   

【问题讨论】:

  • The app crashed right after user select desired picture. 那将在 onActivityResult 中。您发布了太多代码。只有这个功能和使用的意图就足够了。发布 logcat 而不是所有不相关的代码。
  • Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.os.Bundle.get(java.lang.String)' on a null object reference at com.example.anany.emotionrecognition.MainActivity.onActivityResult(MainActivity.java:216)216行是什么?
  • 代码还是太多了。
  • getRealPathFromURI(imageUri)该函数将返回null。不要使用这么可怕的功能。
  • @blackapps (MainActivity.java:216) 是 mBitmap = (Bitmap) data.getExtras().get("data");它在 }else if(requestCode == 1 && resultCode == RESULT_OK){

标签: android image android-intent bitmapimage android-external-storage


【解决方案1】:

更改uploadpicture onclicklistner 代码

uploadPicture.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            imageFile = getDefaultFileName(MainActivity.this);
            Intent i = new Intent(Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            startActivityForResult(i, PICK_IMAGE);
        }

 public File getDefaultFileName(Context context) {
        File imageFile1;
        Boolean isSDPresent = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
        if (isSDPresent) { // External storage path
            imageFile1 = new File(Environment.getExternalStorageDirectory() + File.separator + "abc" + System.currentTimeMillis() + ".png");
        } else {  // Internal storage path
            imageFile1 = new File(context.getFilesDir() + File.separator + "abc" + System.currentTimeMillis() + ".png");
        }
        return imageFile1;
    }

我根据您的回答更新了onActivityResult

Uri imageUri;
ContentValues values;

@RequiresApi(api = Build.VERSION_CODES.N)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == Activity.RESULT_OK) {
        imageView.setVisibility(View.VISIBLE);
        switch (requestCode) {
            case PICK_IMAGE:
                try {
                    InputStream inputStream =
                            getContentResolver().openInputStream(data.getData());
                    FileOutputStream fileOutputStream = new FileOutputStream(imageFile);
                    copyStream(inputStream, fileOutputStream);
                    fileOutputStream.close();
                    if (inputStream != null)
                        inputStream.close();
                    String imagePath = Uri.fromFile(imageFile).getPath();

                    // Here Add you image load code
                  //  if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
                   //     Uri selectedImage = data.getData();
                   //     String[] filePathColumn = {MediaStore.Images.Media.DATA};

                    //    Cursor cursor = getContentResolver().query(selectedImage,
                    //            filePathColumn, null, null, null);
                        
                   // }
                    Toast.makeText(MainActivity.this, imagePath, Toast.LENGTH_SHORT).show();
imageView.setImageBitmap(BitmapFactory.decodeFile(imagePath));
                    } catch (Exception e) {
                        e.printStackTrace();

                    }
                ready = true;
                hidden.setVisibility(View.INVISIBLE);
                break;
            default:
                break;
        }
    }
}

private void copyStream(InputStream input, FileOutputStream output) throws IOException {
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = input.read(buffer)) != -1) {
            output.write(buffer, 0, bytesRead);
        }
    }

【讨论】:

  • 请检查更新的评论,并请发起imageFile活动顶部
  • 选择图片并加载它工作正常,但选择的图片没有设置为图像视图,所以它现在确实显示为空白。如何将其设置为 imageView?正如您从我的代码中看到的那样,我有两个 imageView 一个是可见的,一个是隐藏的。我尝试在休息前放置 imageView 行,但似乎没有任何效果,我不确定应该在 imageView 中设置什么图像,是 mBitmap 吗?
  • 它仍然不起作用@Deep Parsania 我认为是因为 setVisibility 但是在我输入代码之后 imageView.setVisibility(View.VISIBLE);准备好=真; hidden.setVisibility(View.INVISIBLE);还是不行
  • 检查您的评论@Deep Parsania。我已经更新了我最新的 onActivityResult
  • 更新了评论。我已在您的 imagePath 中添加了一条 toast 消息,请检查 Toast 消息中显示的内容
【解决方案2】:
            ExifInterface ei = new ExifInterface(getRealPathFromURI(imageUri));

改为:

InputStream is = getContentResolver().openInputStream(data.getData());

ExifInterFace ei = new ExifInterFace(is);

【讨论】:

  • 按照您的代码执行但在选择照片后仍然崩溃。错误日志仍在 mBitmap = (Bitmap) data.getExtras().get("data");在 } else if (requestCode == 1 && resultCode == RESULT_OK) {
  • 你把你的帖子用太多代码弄糊涂了。
猜你喜欢
  • 2014-03-22
  • 2018-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-17
  • 1970-01-01
  • 2021-11-23
相关资源
最近更新 更多