【问题标题】:Cannot Upload Image From Gallery in Android Studio无法从 Android Studio 中的图库上传图片
【发布时间】:2017-06-13 10:54:52
【问题描述】:

我想在我的 Android 应用中从图库中上传图片。当我点击按钮时,画廊应该被打开。 选择图片后,我想打开另一个名为 UploadActivity 的活动。此处应预览图像的缩略图。上传按钮将在缩略图下方。

但是当我从图库中选择照片时,图像的缩略图没有预览。我也无法上传照片。我的代码在这里:(Scan.Java)

 private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
public static final int MEDIA_TYPE_IMAGE = 1;
private static final int SELECT_IMAGE = 2;
private Uri fileUri; // file url to store image/video
ImageView dummy;
private Button btnCapturePicture;
private Button btnGallery;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.scan);
    dummy = (ImageView) findViewById(R.id.dummyphoto);
    btnCapturePicture = (Button) findViewById(R.id.btnCapturePicture);
    btnGallery = (Button) findViewById(R.id.btnGallery);
    /**
     * Capture image button click event
     */
    btnCapturePicture.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // capture picture
            captureImage();
        }
    });

    btnGallery.setOnClickListener(new View.OnClickListener(){

        @Override
        public void onClick(View v){
            openGallery();
        }

    });

    // Checking camera availability
    if (!isDeviceSupportCamera()) {
        Toast.makeText(getApplicationContext(),
                "Sorry! Your device doesn't support camera",
                Toast.LENGTH_LONG).show();
        // will close the app if the device does't have camera
        finish();
    }
}

/**
 * Checking device has camera hardware or not
 * */
private boolean isDeviceSupportCamera() {
    if (getApplicationContext().getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_CAMERA)) {
        // this device has a camera
        return true;
    } else {
        // no camera on this device
        return false;
    }
}

/**
 * Launching camera app to capture image
 */
private void captureImage() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);

    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

    // start the image capture Intent
    startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}

/**
 * Launching Gallery to Choose Image
 */
private void openGallery(){
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
    startActivityForResult(Intent.createChooser(intent, "Select Image"),SELECT_IMAGE);
}

/**
 * Here we store the file url as it will be null after returning from camera
 * app
 */
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    // save file url in bundle as it will be null on screen orientation
    // changes
    outState.putParcelable("file_uri", fileUri);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);

    // get the file url
    fileUri = savedInstanceState.getParcelable("file_uri");
}



/**
 * Receiving activity result method will be called after closing the camera
 * */
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // if the result is capturing Image
    if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
        if (resultCode == RESULT_OK) {

            // successfully captured the image
            // launching upload activity
            launchUploadActivity(true);


        } else if (resultCode == RESULT_CANCELED) {

            // user cancelled Image capture
            Toast.makeText(getApplicationContext(),
                    "User cancelled image capture", Toast.LENGTH_SHORT)
                    .show();

        } else {
            // failed to capture image
            Toast.makeText(getApplicationContext(),
                    "Sorry! Failed to capture image", Toast.LENGTH_SHORT)
                    .show();
        }

    }

    else if (requestCode == SELECT_IMAGE)
    {
        if (resultCode == Activity.RESULT_OK)
        {
            if (data != null)
            {
                    launchUploadActivity(true);
            }
        } else if (resultCode == Activity.RESULT_CANCELED)
        {
            Toast.makeText(getApplicationContext(), "Cancelled", Toast.LENGTH_SHORT).show();
        }
    }

}

private void launchUploadActivity(boolean isImage){
    Intent i = new Intent(Scan.this, UploadActivity.class);
    i.putExtra("filePath", fileUri.getPath());
    i.putExtra("isImage", isImage);
    startActivity(i);
}

UploadActivity.Java 代码放在这里:

private ProgressBar progressBar;
private String filePath = null;
private TextView txtPercentage;
private ImageView imgPreview;
private Button btnUpload;
long totalSize = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_upload);
    txtPercentage = (TextView) findViewById(R.id.txtPercentage);
    btnUpload = (Button) findViewById(R.id.btnUpload);
    progressBar = (ProgressBar) findViewById(R.id.progressBar);
    imgPreview = (ImageView) findViewById(R.id.imgPreview);

    // Receiving the data from previous activity
    Intent i = getIntent();

    // image path that is captured in previous activity
    filePath = i.getStringExtra("filePath");

    // boolean flag to identify the media type, image
    boolean isImage = i.getBooleanExtra("isImage", true);

    if (filePath != null) {
        // Displaying the image on the screen
        previewMedia(isImage);
    } else {
        Toast.makeText(getApplicationContext(),
                "Sorry, file path is missing!", Toast.LENGTH_LONG).show();
    }

    btnUpload.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // uploading the file to server
            new UploadFileToServer().execute();
        }
    });

}

/**
 * Displaying captured image on the screen
 * */
private void previewMedia(boolean isImage) {
    // Checking whether captured media is image
    if (isImage) {
        imgPreview.setVisibility(View.VISIBLE);
        // bimatp factory
        BitmapFactory.Options options = new BitmapFactory.Options();

        // down sizing image as it throws OutOfMemory Exception for larger
        // images
        options.inSampleSize = 8;

        final Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);

        imgPreview.setImageBitmap(bitmap);
    } else {
        imgPreview.setVisibility(View.GONE);
    }
}

/**
 * Uploading the file to server
 * */
private class UploadFileToServer extends AsyncTask<Void, Integer, String> {
    @Override
    protected void onPreExecute() {
        // setting progress bar to zero
        progressBar.setProgress(0);
        super.onPreExecute();
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        // Making progress bar visible
        progressBar.setVisibility(View.VISIBLE);

        // updating progress bar value
        progressBar.setProgress(progress[0]);

        // updating percentage value
        txtPercentage.setText(String.valueOf(progress[0]) + "%");
    }

    @Override
    protected String doInBackground(Void... params) {
        return uploadFile();
    }

    @SuppressWarnings("deprecation")
    private String uploadFile() {
        String responseString = null;

        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost(Config.FILE_UPLOAD_URL);

        try {
            AndroidMultiPartEntity entity = new AndroidMultiPartEntity(
                    new ProgressListener() {

                        @Override
                        public void transferred(long num) {
                            publishProgress((int) ((num / (float) totalSize) * 100));
                        }
                    });

            File sourceFile = new File(filePath);

            // Adding file data to http body
            entity.addPart("image", new FileBody(sourceFile));

这里是 Logcat:

E/MainActivity: Response from server: java.io.FileNotFoundException: /mnt/sdcard/Pictures/master/IMG_20170127_152930.jpg: open failed: ENOENT (No such file or directory)

【问题讨论】:

    标签: android android-studio upload image-uploading


    【解决方案1】:

    在下面我建议的这些更改之后,希望您的问题能够得到解决:

    1. openGallery() 中删除这两行,因为我认为它们是多余的。
    fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
    

    当我们使用 Intent.ACTION_PICK 时需要它们。所以编辑后 openGallery() 看起来像:

    private void openGallery(){
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Select Image"),SELECT_IMAGE);
    }
    
    1. 在您的 onActivityResult() 中添加此语句:

    fileUri = data.getData();

    看起来是这样的:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    ...
    else if (requestCode == SELECT_IMAGE)
    {
        if (resultCode == Activity.RESULT_OK)
        {
            if (data != null)
            {
                    fileUri = data.getData(); //added this line
                    launchUploadActivity(true);
            }
        } else if (resultCode == Activity.RESULT_CANCELED)
        {
            Toast.makeText(getApplicationContext(), "Cancelled",     Toast.LENGTH_SHORT).show();
        }
    }
    }
    
    1. 同样适用于相机意图。

    2. 如果您的目标 Android 版本为 6.0 或更高版本,则请求 EXTERNAL_STORAGE 权限和运行时权限。

    编辑:

    很抱歉,我没有提到这些是必需的:

    1. 您可能希望以这种方式发送 Uri 而不是路径:

      private void launchUploadActivity(boolean isImage){ Intent i = new Intent(this, UploadActivity.class); i.setData(fileUri); // i.putExtra("filePath", fileUri.getPath()); i.putExtra("isImage", isImage); startActivity(i); }

    2. 然后在 UploadActivity 中执行以下操作:

      ... private InputStream mInputStream; // Use this stream to create bitmap and upload to server @Override protected void onCreate(Bundle savedInstanceState) { ... // Receiving the data from previous activity Intent i = getIntent(); try { mInputStream = getContentResolver().openInputStream(i.getData()); } catch (FileNotFoundException e) { e.printStackTrace(); } ... } ...

      ... private void previewMedia(boolean isImage){ if (isImage) { imgPreview.setVisibility(View.VISIBLE); BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 8; Bitmap bitmap = BitmapFactory.decodeStream(mInputStream,null,options); imgPreview.setImageBitmap(bitmap); } else { imgPreview.setVisibility(View.GONE); } } ...

      这对我有用,希望对你也有用。

    【讨论】:

    • 编辑了我的答案。请检查一下。
    【解决方案2】:
    File path = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES);
    File file = new File(path, "IMG_20170127_152930.jpg");
    

    //试试这个。

    【讨论】:

    • 我不会一直使用同一张图片。那么,具体的“IMG_20170127_152930.jpg”文件是什么原因呢?
    • 这只是一个例子,用你自己的文件名替换那个字符串(文件名)。
    猜你喜欢
    • 2020-11-08
    • 2012-06-30
    • 2017-02-23
    • 2018-06-25
    • 2014-07-17
    • 1970-01-01
    • 1970-01-01
    • 2018-12-14
    • 2014-06-24
    相关资源
    最近更新 更多