Taking Pictures with Camera on Android Programmatically

Taking pictures with camera on Android programmatically

Look at following demo code.

Here is your XML file for UI,

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<Button
android:id="@+id/btnCapture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Camera" />

</LinearLayout>

And here is your Java class file,

public class CameraDemoActivity extends Activity {
int TAKE_PHOTO_CODE = 0;
public static int count = 0;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// Here, we are making a folder named picFolder to store
// pics taken by the camera using this application.
final String dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/picFolder/";
File newdir = new File(dir);
newdir.mkdirs();

Button capture = (Button) findViewById(R.id.btnCapture);
capture.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {

// Here, the counter will be incremented each time, and the
// picture taken by camera will be stored as 1.jpg,2.jpg
// and likewise.
count++;
String file = dir+count+".jpg";
File newfile = new File(file);
try {
newfile.createNewFile();
}
catch (IOException e)
{
}

Uri outputFileUri = Uri.fromFile(newfile);

Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);

startActivityForResult(cameraIntent, TAKE_PHOTO_CODE);
}
});
}

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

if (requestCode == TAKE_PHOTO_CODE && resultCode == RESULT_OK) {
Log.d("CameraDemo", "Pic saved");
}
}
}

Note:

Specify the following permissions in your manifest file,

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

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

Capture Image from Camera and Display in Activity

Here's an example activity that will launch the camera app and then retrieve the image and display it.

package edu.gvsu.cis.masl.camerademo;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class MyCameraActivity extends Activity
{
private static final int CAMERA_REQUEST = 1888;
private ImageView imageView;
private static final int MY_CAMERA_PERMISSION_CODE = 100;

@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.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)
{
if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
{
requestPermissions(new String[]{Manifest.permission.CAMERA}, MY_CAMERA_PERMISSION_CODE);
}
else
{
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
}
});
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
{
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == MY_CAMERA_PERMISSION_CODE)
{
if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(this, "camera permission granted", Toast.LENGTH_LONG).show();
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
else
{
Toast.makeText(this, "camera permission denied", Toast.LENGTH_LONG).show();
}
}
}

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

Note that the camera app itself gives you the ability to review/retake the image, and once an image is accepted, the activity displays it.

Here is the layout that the above activity uses. It is simply a LinearLayout containing a Button with id button1 and an ImageView with id imageview1:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/photo"></Button>
<ImageView android:id="@+id/imageView1" android:layout_height="wrap_content" android:src="@drawable/icon" android:layout_width="wrap_content"></ImageView>

</LinearLayout>

And one final detail, be sure to add:

<uses-feature android:name="android.hardware.camera"></uses-feature> 

and if camera is optional to your app functionality. make sure to set require to false in the permission. like this

<uses-feature android:name="android.hardware.camera" android:required="false"></uses-feature>

to your manifest.xml.

Android using front facing camera to take a picture

I solved the problem. After reading some other posts and tutorials seems like that the camera needs a "dummy" surface to preview, even if we don't want the preview to be shown.

Here's my final code in case anyone needs it. Notice that by "hasCamera" I mean a front facing camera:

   public class CameraController {

private Context context;

private boolean hasCamera;

private Camera camera;
private int cameraId;

public CameraController(Context c){
context = c.getApplicationContext();

if(context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
cameraId = getFrontCameraId();

if(cameraId != -1){
hasCamera = true;
}else{
hasCamera = false;
}
}else{
hasCamera = false;
}
}

public boolean hasCamera(){
return hasCamera;
}

public void getCameraInstance(){
camera = null;

if(hasCamera){
try{
camera = Camera.open(cameraId);
prepareCamera();
}
catch(Exception e){
hasCamera = false;
}
}
}

public void takePicture(){
if(hasCamera){
camera.takePicture(null,null,mPicture);
}
}

public void releaseCamera(){
if(camera != null){
camera.stopPreview();
camera.release();
camera = null;
}
}

private int getFrontCameraId(){
int camId = -1;
int numberOfCameras = Camera.getNumberOfCameras();
CameraInfo ci = new CameraInfo();

for(int i = 0;i < numberOfCameras;i++){
Camera.getCameraInfo(i,ci);
if(ci.facing == CameraInfo.CAMERA_FACING_FRONT){
camId = i;
}
}

return camId;
}

private void prepareCamera(){
SurfaceView view = new SurfaceView(context);

try{
camera.setPreviewDisplay(view.getHolder());
}catch(IOException e){
throw new RuntimeException(e);
}

camera.startPreview();

Camera.Parameters params = camera.getParameters();
params.setJpegQuality(100);

camera.setParameters(params);
}

private PictureCallback mPicture = new PictureCallback(){
@Override
public void onPictureTaken(byte[] data, Camera camera){
File pictureFile = getOutputMediaFile();

if(pictureFile == null){
Log.d("TEST", "Error creating media file, check storage permissions");
return;
}

try{
Log.d("TEST","File created");
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
}catch(FileNotFoundException e){
Log.d("TEST","File not found: "+e.getMessage());
} catch (IOException e){
Log.d("TEST","Error accessing file: "+e.getMessage());
}
}
};

private File getOutputMediaFile(){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.

File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"MyCameraApp");

// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.

// Create the storage directory if it does not exist
if(!mediaStorageDir.exists()){
if(!mediaStorageDir.mkdirs()){
return null;
}
}

// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());

File mediaFile;
mediaFile = new File(mediaStorageDir.getPath()+File.separator+"IMG_"+timeStamp+".jpg");

return mediaFile;
}
}

Taking picture from camera without preview

it is really weird that camera on android platform can't stream video until it given valid preview surface. it seems that the architects of the platform was not thinking about 3rd party video streaming applications at all. even for augmented reality case the picture can be presented as some kind of visual substitution, not real time camera stream.

anyway, you can simply resize preview surface to 1x1 pixels and put it somewhere in the corner of the widget (visual element). please pay attention - resize preview surface, not camera frame size.

of course such trick does not eliminate unwanted data streaming (for preview) which consumes some system resources and battery.

Is it possible to programmatically take photo with native Camera app on Android device without physically tapping the capture button?

is it possible to programmatically interact/configure with native Camera app on Android device?

Not from an ordinary Android app.

Also, please note that there are several thousand Android device models. There are hundreds of different "native Camera app" implementations across those device models, as device manufacturers often implement their own. Your question implies that you think that there is a single "native Camera app", which is not the case.

For an individual device model, or perhaps a closely related family of devices, with a rooted device, you might be able to work something out with simulated user input. However, the myriad of camera apps means that you would need different rules for each app.

Also, if you are only concerned about your own device, you can use the uiautomator test system to control third-party apps, but that requires a connection to your development machine, as the tests are run from there.

How to access photos and camera in android using one intent

To access camera and photos using one intent

populate a custom dialog's listview with intents from apps that can either take pictures using camera or access photos in the storage like this

private void acquirePicture(){
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");

Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

final Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
WindowManager.LayoutParams WMLP = dialog.getWindow().getAttributes();
WMLP.gravity = Gravity.CENTER;
dialog.getWindow().setAttributes(WMLP);
dialog.getWindow().setBackgroundDrawable(
new ColorDrawable(android.graphics.Color.TRANSPARENT));
dialog.setCanceledOnTouchOutside(true);
dialog.setContentView(R.layout.about_dialog);
dialog.setCancelable(true);
lv=(ListView)dialog.findViewById(R.id.listView1);

populateDialogsListView();

dialog.show();
}

Poputate dialog's listview (lv) with apps that can perform the two actions

public void populateDialogListView(){

PackageManager pm=getPackageManager();

List<ResolveInfo> photoIntents = new ArrayList<>();

final List<ResolveInfo> listCam = packageManager.queryIntentActivities(
captureIntent, PackageManager.GET_RESOLVED_FILTER);

final List<ResolveInfo> listGalley = packageManager.queryIntentActivities(photoPickerIntent, PackageManager.GET_RESOLVED_FILTER);

for (ResolveInfo activity : listCam) {
photoIntents.add(activity);
}

for (ResolveInfo activity : listGalley) {
photoIntents.add(activity);
}

Collections.sort(photoIntents,
new ResolveInfo.DisplayNameComparator(pm));

AppAdapter appAdapter = new AppAdapter(pm, photoIntents);

lv.setAdapter(appAdapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
// TODO Auto-generated method stub
ResolveInfo launchable=appAdapter.getItem(position);
ActivityInfo activity=launchable.activityInfo;
ComponentName name=new ComponentName(activity.applicationInfo.packageName,
activity.name);

IntentFilter filter = launchable.filter;

int actioncode;
Intent intent = new Intent();
Uri uri;
if(filter.hasAction(Intent.ACTION_PICK)){
actioncode = 1;
uri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
intent.setData(uri);
}else{
actioncode = 0;
}
intent.setComponent(name);
startActivityForResult(intent,actioncode);
}
});

}

Since you are creating a custom dialog with a listview, you have to create adapter for that listview(lv) which will fill the listview with app's name and app's icon

class AppAdapter extends ArrayAdapter<ResolveInfo> {
private PackageManager pm=null;

AppAdapter(PackageManager pm, List<ResolveInfo> apps) {
super(Custom_chooser.this, R.layout.row, apps);
this.pm=pm;
}

@Override
public View getView(int position, View convertView,
ViewGroup parent) {
if (convertView==null) {
convertView=newView(parent);
}

bindView(position, convertView);

return(convertView);
}

private View newView(ViewGroup parent) {
return(getLayoutInflater().inflate(R.layout.row, parent, false));
}

private void bindView(int position, View row) {
TextView label=(TextView)row.findViewById(R.id.label);

label.setText(getItem(position).loadLabel(pm));

ImageView icon=(ImageView)row.findViewById(R.id.icon);

icon.setImageDrawable(getItem(position).loadIcon(pm));
}

Any problem, let me know

Capture Image programmatically in android

Try something like this:

public void takePictureNoPreview(Context context){
// open back facing camera by default
Camera myCamera=Camera.open();

if(myCamera!=null){
try{
//set camera parameters if you want to
//...

// here, the unused surface view and holder
SurfaceView dummy=new SurfaceView(context)
myCamera.setPreviewDisplay(dummy.getHolder());
myCamera.startPreview();

myCamera.takePicture(null, null, getJpegCallback()):

} finally {
myCamera.close();
}

} else {
//booo, failed!
}

private PictureCallback getJpegCallback(){
PictureCallback jpeg=new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream fos;
try {
fos = new FileOutputStream("test.jpeg");
fos.write(data);
fos.close();
} catch (IOException e) {
//do something about it
}
}
};
}
}

Or try some solutions from this post: Taking pictures with camera on Android programmatically

Taking picture while recording video on Android

Edit:

With the clarification:

The old camera API supports calling takePicture() while video is being recorded, if Camera.Parameters.isVideoSnapshotSupported reports true on the device is question.

Just hold on to the same camera instance you're passing into the MediaRecorder, and call Camera.takePicture() on it.

Camera2 also supports this with more flexibility, by creating a session with preview, recording, and JPEG outputs at the same time.

Original answer:

If you mean taking pictures with the back camera, while recording with the front camera - that's device-dependent. Some devices have enough hardware resources to run multiple cameras at once, but most won't (they share processing hardware between the two cameras).

The only way to tell if multiple cameras can be used at once is to try opening a second camera when one is already open. If it works, you should be good to go; if not, that device doesn't support multiple cameras at once.



Related Topics



Leave a reply



Submit