Android Camera Intent not working - Launching gall

2019-09-16 17:36发布

问题:

I am trying to launch the Android camaera via an intent, take a picture and have returned the URI. Should be quite simple right, after all there are loads and loads of posts on how to do this on SO.

However, I am using a galaxy S3 with ICS, and find that when I call the camera intent it takes me to the gallery not the camera.

Here is the code I have tried.

Firstly a simple one:

public static final int REQUEST_CODE_CAMERA = 1337;
.
.
. 
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
startActivityForResult(intent, REQUEST_CODE_CAMERA); 

This did not work. SoI tried the example from Vogella.com

private static final int REQUEST_CODE = 1;
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, REQUEST_CODE);

I have also read people suggesting different request codes such as 1888, 1337 and 2500. Is there not a universal request code or framework based static int I can use? Or are these code one of the many SO red herrings, and therefore one can use any code?

BTW I am aware of the bug in which the S3 does not work with the MediaStore.EXTRA_OUTPUT. It's not help with this that I need. I already know how to overcome that hurdle.

[EDIT]

**PLEASE NOTE

For those reading this orientation can be a serious problem that needs to be taken care of when using the Camera intent. Although the activity launching the camera has it's orientation locked in the manifest. When the device was in portrait mode it would call OnCreate before and after OnActivityResult; thus class global variables are wiped. The solution was to save all the class global variables via the *onSaveInstanceStat*e method, and in the OnCreate use these to reload and display the images in the view. From the information gleaned from SO not all devices will do this but it tends to be consistent per device. My guess is memory management of activities is dependant on available hardware and Android platform. I really wish this was not the case, but Android is Android.

[/EDIT]

回答1:

MainActivity.java

public class MainActivity extends Activity {
private static final int CAMERA_REQUEST = 1888; 
private ImageView imageView;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    this.imageView = (ImageView)this.findViewById(R.id.imageView1);
    Button photoButton = (Button) this.findViewById(R.id.button1);
    photoButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
            startActivityForResult(cameraIntent, CAMERA_REQUEST); 
            File imagesFolder = new File(Environment.getExternalStorageDirectory(), "MyCameraImages");
            imagesFolder.mkdirs();   
            File image = new File(imagesFolder, "image.jpg");
            Uri uriSavedImage = Uri.fromFile(image);
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);

        }
    });
}

protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
    if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {  
        Bitmap photo = (Bitmap) data.getExtras().get("data"); 
        imageView.setImageBitmap(photo);        
} 
}
}

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >

<ImageView
    android:id="@+id/imageView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:layout_marginBottom="79dp" />

<Button
    android:id="@+id/button1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:layout_marginBottom="26dp"
    android:text="StartCamera" />

</RelativeLayout>

Snap Shot of image saved in Gallery



回答2:

For using the camera I use the following intent:

Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");


回答3:

android.media.action.IMAGE_CAPTURE

and

android.provider.MediaStore.ACTION_IMAGE_CAPTURE

are one and the same thing. the variable android.provider.MediaStore.ACTION_IMAGE_CAPTURE refers to the string above.the reason to refer to the variable instead of the string is to be sure that there is no change in string .in case the string changes the android people shall also change the constant and you shall be able to know that you are referring to the wrong constant but for a string no error will come while compiling. i hope it clears.



回答4:

Code for choose photo from gallery and take a new picture also supported in SDK 24 or later

Activity

private File filePathImageCamera;
private Uri imagePath;
private static final int IMAGE_GALLERY_REQUEST = 2;
private static final int IMAGE_CAMERA_REQUEST = 3;
private String imageFilePath;

private void selectImage() {


        final CharSequence[] options = {"Take Photo", "Choose from Gallery", "Cancel"};

        AlertDialog.Builder builder = new AlertDialog.Builder(DocumentActivity.this);

        builder.setTitle("Upload Photo!");

        builder.setItems(options, new DialogInterface.OnClickListener() {

            @Override

            public void onClick(DialogInterface dialog, int item) {

                if (options[item].equals("Take Photo")) {
                    photoCameraIntent();
                } else if (options[item].equals("Choose from Gallery")) {
                    photoGalleryIntent();
                } else if (options[item].equals("Cancel")) {
                    dialog.dismiss();
                }

            }

        });

        builder.show();

    }

 private void photoCameraIntent() {

        Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        Uri uri = null;

        try {
            filePathImageCamera = createImageFile();
        } catch (IOException ex) {
            // Error occurred while creating the File

        }


        if (pictureIntent.resolveActivity(getPackageManager()) != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

                //Create a file to store the image

                if (filePathImageCamera != null) {
                    Uri photoURI = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", filePathImageCamera);
                    pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                            photoURI);
                    startActivityForResult(pictureIntent,
                            IMAGE_CAMERA_REQUEST);
                }


            } else {


                if (filePathImageCamera != null) {
                    uri = Uri.fromFile(filePathImageCamera);

                    pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
                    startActivityForResult(pictureIntent, IMAGE_CAMERA_REQUEST);
                }


            }
        }

    }

    private File createImageFile() throws IOException {
        String timeStamp =
                new SimpleDateFormat("yyyyMMdd_HHmmss",
                        Locale.getDefault()).format(new Date());
        String imageFileName = "IMG_" + timeStamp + "_";
        File storageDir =
                getExternalFilesDir(Environment.DIRECTORY_PICTURES);

        // Create the storage directory if it does not exist
        if (!storageDir.exists() && !storageDir.mkdirs()){
            Log.d("error", "failed to create directory");
        }

        File image = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );

        imageFilePath = image.getAbsolutePath();
        return image;
    }

    private void photoGalleryIntent() {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Get Image From"), IMAGE_GALLERY_REQUEST);
    }

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {


        if (requestCode == IMAGE_GALLERY_REQUEST) {
            if (resultCode == RESULT_OK) {

                imagePath = data.getData();


                Glide.with(MainActivity.this).load(imagePath).into(imageview);







            }
        } else if (requestCode == IMAGE_CAMERA_REQUEST) {
            if (resultCode == RESULT_OK) {
                if (filePathImageCamera != null && filePathImageCamera.exists()) {

                    imagePath = Uri.fromFile(filePathImageCamera);


                    Glide.with(MainActivity.this).load(imagePath).into(imageview);




                } 
            }
        }

    }

Manifest

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

 <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>

create new file provider_paths.xml in res/xml directory

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

    <external-path name="my_images"
        path="Android/data/your_package_name/files/Pictures" />

</paths>

Note - Application permission required