Это мой первый пост здесь, в Stackoverflow, и я скрещиваю пальцы, чтобы вы могли мне помочь.

Я недавно начал изучать Android и решил, что простое приложение, которое делает снимок, а затем показывает его пользователю в приложении, было бы хорошим местом для начала.

Однако, следуя руководству на сайте разработчиков Android (http://developer.android.com/training/camera/photobasics.html), я просто не могу получить изображение для отображения.

Получаю сообщение об ошибке:

Невозможно декодировать поток: java.io.FileNotFoundException: file: /storage/emulated/0/Pictures/JPEG_20160101_163802_1697759335.jpg: Ошибка открытия: ENOENT (Нет такого файла или каталога)

Я вижу, что фотография была сохранена в папке камеры по умолчанию, а не по указанному мной пути (как скопировано / вставлено из руководства разработчика).

Я был бы безмерно благодарен, если бы кто-нибудь помог мне разобраться, как сохранить фотографию в указанном файле или получить сохраненное местоположение обратно из приложения камеры.

    package uk.co.c2digital.futurefoto;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * The following code is based on the following article: http://developer.android.com/training/camera/photobasics.html
 */

public class MainActivity extends AppCompatActivity {


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

        Log.v("MainActivity", "App Started");
    }





    /**
     * This block of code launches the default camera application
     */

    static final int REQUEST_TAKE_PHOTO = 1;

    public void dispatchTakePictureIntent(View view) {

        Log.v("MainActivity", "dispatchTakePictureIntent() function started");

        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // Ensure that there's a camera activity to handle the intent
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {

            // Out success result to log
            Log.v("MainActivity", "Camera app found");

            // Create the File where the photo should go
            File photoFile = null;
            try {
                photoFile = createImageFile();
                Log.v("MainActivity","Image will be saved to: " + photoFile);
            } catch (IOException ex) {
                // Error occurred while creating the File
                Toast.makeText(this, "Unable to save image", Toast.LENGTH_SHORT).show();
                Log.v("MainActivity", "Error while attempting to run createImageFile()");
            }
            // Continue only if the File was successfully created
            if (photoFile != null) {
                Log.v("MainActivity","File created");
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                        Uri.fromFile(photoFile));
                startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);




            }
        } else {
            Toast.makeText(this, "Unable to launch camera app", Toast.LENGTH_SHORT).show();
            Log.v("MainActivity","Unable to find camera app");
        }
    }

    /**
     * End of camera launch code
     */


    /**
     * This block of code creates a unique file name for captured photos to prevent naming collisions
     */


    String mCurrentPhotoPath;

    public File createImageFile() throws IOException {

        Log.v("MainActivity","createImageFile() functions started");

        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );

        // Save a file: path for use with ACTION_VIEW intents
        mCurrentPhotoPath = "file:" + image.getAbsolutePath();


        return image;
    }


    /**
     * End of unique file name code
     */


    /**
     * This block of code decodes and scales the photo and displays in photoView
     */



    public void setPic() {

        Log.v("MainActivity","setPic() function started");

        ImageView mImageView = (ImageView) findViewById(R.id.imageViewer);

        // Get the dimensions of the View
        int targetW = mImageView.getWidth();
        int targetH = mImageView.getHeight();

        // Get the dimensions of the bitmap
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        bmOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
        int photoW = bmOptions.outWidth;
        int photoH = bmOptions.outHeight;

        // Determine how much to scale down the image
        int scaleFactor = Math.min(photoW/targetW, photoH/targetH);

        // Decode the image file into a Bitmap sized to fill the View
        bmOptions.inJustDecodeBounds = false;
        bmOptions.inSampleSize = scaleFactor;
        bmOptions.inPurgeable = true;

        Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
        mImageView.setImageBitmap(bitmap);
    }

    /**
     * End of photo scaling code
     */


    /**
     * THis block of code allows the created photo to be made available to the photo gallery
     */


    private void galleryAddPic() {

        Log.v("MainActivity", "galleryAddPic() function started");

        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        File f = new File(mCurrentPhotoPath);
        Uri contentUri = Uri.fromFile(f);
        mediaScanIntent.setData(contentUri);
        this.sendBroadcast(mediaScanIntent);
    }


    /**
     * End of gallery code
     */


    /**
     * This block of code handles the responce from the cameras intent
     */

    public void onActivityResult(int RequestCode, int ResultCode, Intent data) {

        Log.v("MainActivity","onActivityResult() function started");

        if (RequestCode == REQUEST_TAKE_PHOTO) {

            Log.v("MainActivity","RequestCode matched REQUEST_TAKE_PHOTO");

            if (ResultCode == RESULT_OK) {

                Log.v("MainActivity","ResultCode was OK");

                 // galleryAddPic();
                  setPic();

            } else {

                Log.v("MainActivity","ResultCode was not OK");
                Log.v("MainActivity","ResultCode was: " + ResultCode);
            }


        } else {

            Log.v("MainActivity","RequestCode did not equal REQUEST_TAKE_PHOTO");
            Log.v("MainActivity","Request Code was: " + RequestCode);
        }


    }
}

Caphson

Ответов: 1

Ответы (1)

Я использую такой подход:

Uri newPhotoUri;
public void takePhoto() {
    // create Intent to take a picture and return control to the calling application
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    newPhotoUri = Uri.fromFile(new File(filename)); // create a file to save the image
    intent.putExtra(MediaStore.EXTRA_OUTPUT, newPhotoUri); // set the image file name

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

а затем:

/**
 * Called when returning from the camera request.
 */
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
        Log.d(TAG, "Received camera activity result");
        if (resultCode == RESULT_OK) {
            String resultPath = "";
            if (data == null) {
                if (this.newPhotoUri != null) {
                    Log.d(TAG, "Intent data is null, trying with uri " + this.newPhotoUri.getPath());
                    resultPath = this.newPhotoUri.getPath();
                } else {
                    Log.d(TAG, "Intent data and photo Uri are null, exiting");
                    return;
                }
            } else {
                // Image captured and saved to fileUri specified in the Intent
                Log.d(TAG, "Image saved to: " + data.getData());
                resultPath = data.getData().toString();
            }
            // process resultPath
        } else if (resultCode == RESULT_CANCELED) {
            // User cancelled the image capture
            Log.d(TAG, "User cancelled");
        } else {
            // Image capture failed
        }
    }
}

With some devices, the media store location is not guaranteed to be used, so this is more of a practical approach.

2022 WebDevInsider