1

I'm trying to activate camera with intent by the following codes :

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.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private ImageView mImageView;
    static final int REQUEST_IMAGE_CAPTURE = 1;
    static final int REQUEST_TAKE_PHOTO = 1;

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

        Button button = (Button) findViewById(R.id.button);
        mImageView = findViewById(R.id.imageView);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "clicked", Toast.LENGTH_SHORT).show();
                dispatchTakePictureIntent();
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d(TAG, "onActivityResult: 0");
        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
            Log.d(TAG, "onActivityResult: 1");

            Bundle extras = data.getExtras();
            Bitmap imageBitmap = (Bitmap) extras.get("data");
            mImageView.setImageBitmap(imageBitmap);
        }
    }

    private void dispatchTakePictureIntent() {
        Log.d(TAG, "dispatchTakePictureIntent: 0");
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            Log.d(TAG, "dispatchTakePictureIntent: 1");
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
        }
    }
}

The app crashes every time I click the button(it's supposed to open the camera). I can get "dispatchTakePictureIntent: 1" from logcat, so takePictureIntent.resolveActivity(getPackageManager()) isn't returning null. I think it's startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE) that causes the app to crash.

The codes are replicated from the official documents : https://developer.android.com/training/camera/photobasics#java.

I've tried dispatchTakePictureIntent(View v), but the app still crashed. I've also replaced dispatchTakePictureIntent() with the method below and it still crashed.

private void TakePicture(){
    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
    startActivityForResult(intent, 0);
}

I've been trying other solutions I found on the internet, non of them helped. What could be the problem that causes my app to crash?

Jerry Chen
  • 11,595
  • 5
  • 13
  • 16
  • Check whether you have mentioned camera permission in manifest file. – Raj Dec 01 '18 at 10:17
  • Use Logcat to examine the Java stack trace associated with your crash, rather than guessing: https://stackoverflow.com/q/23353173/115145 – CommonsWare Dec 01 '18 at 12:43

3 Answers3

2

I think you have not used any permission check because for an android device below 23 need not to ask for permssion but above 23 you need to declare or ask user to access features of an android.

If the device is running Android 6.0 (API level 23) or higher, and the app's targetSdkVersion is 23 or higher, the user isn't notified of any app permissions at install time. Your app must ask the user to grant the dangerous permissions at runtime. When your app requests permission, the user sees a system dialog (as shown in figure 1, left) telling the user which permission group your app is trying to access. The dialog includes a Deny and Allow button.

According to this Doc..

https://developer.android.com/guide/topics/permissions/overview


 if (ContextCompat.checkSelfPermission(thisActivity,    Manifest.permission.WRITE_CALENDAR)
        != PackageManager.PERMISSION_GRANTED) {
    // Permission is not granted
}


    // Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
        Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {

    // Permission is not granted
    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {
        // Show an explanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.
    } else {
        // No explanation needed; request the permission
        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);

        // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
} else {
    // Permission has already been granted
}

Sample code from Android doc https://developer.android.com/training/permissions/requesting#java

Karsh Soni
  • 170
  • 1
  • 12
  • I have in my Manifest.xml, or should I need to add something to achieve permission check? – Jerry Chen Dec 01 '18 at 09:50
  • as @KarshSoni already mentioned you have to ask the user for camera permission rather than just declaring it in your manifest. Here you can read more about it: https://developer.android.com/training/permissions/requesting – Mohammed Dec 01 '18 at 10:25
1

Please try to give the permission of camera in android manifest file. <uses-permission android:name="android.permission.CAMERA"> </uses-permission>. and then try replace your intent code with this Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); startActivity(intent);

if you don't want to use device camera then you can also make you own Custom camera with the help of this library https://github.com/natario1/CameraView

Atul Chaudhary
  • 1,491
  • 2
  • 15
  • 23
0

you can use this way

public static final int REQUEST_PICTURE_FROM_GALLERY = 10001;
public static final int REQUEST_PICTURE_FROM_CAMERA = 10002;

private File tempFileFromSource = null;
private Uri tempUriFromSource = null;
    
public void selectImageFromGallery() {
        
        try {

            tempFileFromSource  = File.createTempFile("choose", "png", context.getExternalCacheDir());
            tempUriFromSource   = Uri.fromFile(tempFileFromSource);

            Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, tempUriFromSource);
            intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            
            context.startActivityForResult(intent, REQUEST_PICTURE_FROM_GALLERY);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

 
    public void takePhotoWithCamera() {
        
        try {

            tempFileFromSource  = File.createTempFile("choose_", ".png", context.getExternalCacheDir());
            tempUriFromSource = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", tempFileFromSource);

            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, tempUriFromSource);
            intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            
            context.startActivityForResult(intent, REQUEST_PICTURE_FROM_CAMERA);

        } catch (IOException e) {
            e.printStackTrace();
        }


    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        
        if ((requestCode == REQUEST_PICTURE_FROM_GALLERY) && (resultCode == Activity.RESULT_OK)) {
            Log.d(TAG, "Image selected from gallery");
            prepareImage(data.getData(), tempFileFromSource);
        } else if ((requestCode == REQUEST_PICTURE_FROM_CAMERA) && (resultCode == Activity.RESULT_OK)) {
            Log.d(TAG, "Image selected from camera");
            prepareImage(tempUriFromSource, tempFileFromSource);
        }
    }

    private void prepareImage(Uri uri, File imageFile) {
        try {

            if (uri == null)
                return;

            Bitmap bitmap = BitmapUtils.decodeBitmap(context, uri, 300, 300);

            if (bitmap == null)
                return;
            
            // now you have bitmap
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static Bitmap decodeBitmap(Context context, Uri uri, int maxWidth, int maxHeight) throws IOException {

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        InputStream imageStream = context.getContentResolver().openInputStream(uri);
        BitmapFactory.decodeStream(imageStream, null, options);
        if (imageStream != null)
            imageStream.close();

        // Calculate inSampleSize
        options.inSampleSize = calculateSize(options, maxWidth, maxHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        imageStream = context.getContentResolver().openInputStream(uri);
        Bitmap img = BitmapFactory.decodeStream(imageStream, null, options);

        img = rotateImageIfRequired(context, img, uri);
        return img;
    }
Rasoul Miri
  • 11,234
  • 1
  • 68
  • 78