I want to call onPreviewCallback in my app but it wont start. For now there is nothing useufull on onPreviewCallback, i just want it to work. I tried to put callback in Camerapreview.java and still nothing. Can anyone tell me where i made my mistake? Here is my code:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.nikola.camera.MainActivity">
<FrameLayout
android:id="#+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</RelativeLayout>
MainActivity.java
package com.example.nikola.camera;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.FrameLayout;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
public Camera mCamera;
private CameraPreview mPreview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(checkCameraHardware(this)==false){
Toast.makeText(MainActivity.this, "This device does not have camera", Toast.LENGTH_LONG).show();
finish();
}
mCamera = getCameraInstance();
mCamera.setPreviewCallback(new Camera.PreviewCallback() {
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
Log.d("Camera1","data lenght is:"+data.length);
}
});
if(mCamera==null){
Toast.makeText(MainActivity.this, "Can't access camera", Toast.LENGTH_LONG).show();
finish();
}
Camera.Parameters cameraParametars = mCamera.getParameters();
cameraParametars.setPreviewSize(640,480);
cameraParametars.setPreviewFormat(ImageFormat.RGB_565);
mCamera.setParameters(cameraParametars);
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
}
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
}
CameraPreview.java
package com.example.nikola.camera;
/**
* Created by Nikola on 8/4/2016.
*/
import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("Camera_app", "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d("Camera_app", "Error starting camera preview: " + e.getMessage());
}
}
}
First permission add for camera and take image in sdcard
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
On click on preview Photo is click and preview You get path in callback
preview.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCamera.takePicture(null, null, mPicture);
}
});
Take In class Imagepath your path of image take this in your class
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
// Replacing the button after a photho was taken.
// File name of the image that we just took.
String fileName = "IMG_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()).toString() + ".jpg";
// Creating the directory where to save the image. Sadly in older
// version of Android we can not get the Media catalog name
File sdRoot = Environment.getExternalStorageDirectory();
// have the object build the directory structure, if needed.
String dir = "/Capture/path/";
File mkDir = new File(sdRoot, dir);
mkDir.mkdirs();
// Main file where to save the data that we recive from the camera
File pictureFile = new File(sdRoot, dir + fileName);
String imagePath=pictureFile.getPath();
System.out.print("imagePath"+imagePath);
try {
FileOutputStream purge = new FileOutputStream(pictureFile);
purge.write(data);
purge.close();
} catch (FileNotFoundException e) {
Log.d("DG_DEBUG", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("DG_DEBUG", "Error accessing file: " + e.getMessage());
}
// Adding Exif data for the orientation. For some strange reason the
// ExifInterface class takes a string instead of a file.
try {
exif = new ExifInterface("/sdcard/" + dir + fileName);
exif.setAttribute(ExifInterface.TAG_ORIENTATION, "" + orientation);
exif.saveAttributes();
} catch (IOException e) {
e.printStackTrace();
}
}
};
But I recommended you the Camera2Basic... Which have tons of example because this is deprecated
I recommeded you to do this example which run in marashmallow or all devices work properly...
https://github.com/googlesamples/android-Camera2Basic
For face Detaction
You must register a FaceDetectionListener and then call camera.startFaceDetection().
Please see the link for face detaction..
https://docs.google.com/open?id=0B2Nu5U2Cz81qZExGQ25sWVdRd21IOExUUTZsZzFoZw
Related
This are my permissions in AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
This is my MainActivity.java:
import android.hardware.Camera;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.FrameLayout;
public class MainActivity extends AppCompatActivity {
private Camera mCamera;
private CameraPreview mPreview;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create an instance of Camera
mCamera = getCameraInstance();
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
}
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
}
That is my activity_main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<FrameLayout
android:id="#+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
/>
<Button
android:id="#+id/button_capture"
android:text="Capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</LinearLayout>
And that's my CameraPreview.java:
import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("Error:", "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d("Error:", "Error starting camera preview: " + e.getMessage());
}
}
}
When I open the app it crashes and this Error will come:
05-16 16:17:55.694 14553-14553/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.test.badubadu.test, PID: 14553
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.Camera.setPreviewDisplay(android.view.SurfaceHolder)' on a null object reference
at com.test.badubadu.test.CameraPreview.surfaceCreated(CameraPreview.java:31)
at android.view.SurfaceView.updateWindow(SurfaceView.java:622)
at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:161)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2205)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1250)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6311)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
at android.view.Choreographer.doCallbacks(Choreographer.java:683)
at android.view.Choreographer.doFrame(Choreographer.java:619)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:241)
at android.app.ActivityThread.main(ActivityThread.java:6217)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
EDIT Error:
05-16 22:52:39.451 18993-18993/com.test.blaba.test W/CameraBase: An error occurred while connecting to camera 0: Service not available
05-16 22:52:39.451 18993-18993/com.test.blabla.test D/Error:: Error starting camera preview: Fail to connect to camera service
05-16 22:52:39.578 18993-19091/com.test.blaba.test I/Adreno: QUALCOMM build : b6da14b, I47548ba842
Build Date : 11/14/16
OpenGL ES Shader Compiler Version: XE031.09.00.03
Local Branch :
Remote Branch : quic/LA.BF64.1.2.3_rb1.6
Remote Branch : NONE
Reconstruct Branch : NOTHING
So I don't know where the Error is...
Thanks for Help...:)
mCamera is null, because getCameraInstance() is returning null. Most likely, that is because Camera.open() is throwing an exception. Always make sure that you can see exceptions. During early software development, that is mostly through logging those exceptions (e.g., Log.e()).
I am trying to develop an app where the user takes a photo and uploads it to Google Drive automatically (The image is not saved on the phone). I figured out the code for that thanks to a Google Drive tutorial, but I have no idea how I would do that when it comes to upload videoes?
Here is the code for photo uploading:
package com.google.android.gms.drive.sample.quickstart;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender;
import android.content.IntentSender.SendIntentException;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.drive.Drive;
import com.google.android.gms.drive.DriveApi.DriveContentsResult;
import com.google.android.gms.drive.MetadataChangeSet;
/**
* Android Drive Quickstart activity. This activity takes a photo and saves it
* in Google Drive. The user is prompted with a pre-made dialog which allows
* them to choose the file location.
*/
public class VideoCapture extends Activity implements ConnectionCallbacks,
OnConnectionFailedListener {
private static final String TAG = "drive-quickstart";
private static final int REQUEST_CODE_CAPTURE_VIDEO = 1;
private static final int REQUEST_CODE_CREATOR = 2;
private static final int REQUEST_CODE_RESOLUTION = 3;
private GoogleApiClient mGoogleApiClient;
private Byte mVideoToSave;
/**
* Create a new file and save it to Drive.
*/
private void saveFileToDrive() {
// Start by creating a new contents, and setting a callback.
Log.i(TAG, "Creating new contents.");
final Byte video = mVideoToSave;
Drive.DriveApi.newDriveContents(mGoogleApiClient)
.setResultCallback(new ResultCallback<DriveContentsResult>() {
#Override
public void onResult(DriveContentsResult result) {
// If the operation was not successful, we cannot do anything
// and must
// fail.
if (!result.getStatus().isSuccess()) {
Log.i(TAG, "Failed to create new contents.");
return;
}
// Otherwise, we can write our data to the new contents.
Log.i(TAG, "New contents created.");
// Get an output stream for the contents.
OutputStream outputStream = result.getDriveContents().getOutputStream();
// Write the bitmap data from it.
ByteArrayOutputStream mBAOS = new ByteArrayOutputStream();
byte[] mByte = new byte[1024];
try {
outputStream.write(mBAOS.toByteArray());
} catch (IOException e1) {
Log.i(TAG, "Unable to write file contents.");
}
// Create the initial metadata - MIME type and title.
// Note that the user will be able to change the title later.
MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
.setMimeType("video/mp4").setTitle("Android Video.mp4").build();
// Create an intent for the file chooser, and start it.
IntentSender intentSender = Drive.DriveApi
.newCreateFileActivityBuilder()
.setInitialMetadata(metadataChangeSet)
.setInitialDriveContents(result.getDriveContents())
.build(mGoogleApiClient);
try {
startIntentSenderForResult(
intentSender, REQUEST_CODE_CREATOR, null, 0, 0, 0);
} catch (SendIntentException e) {
Log.i(TAG, "Failed to launch file chooser.");
}
}
});
}
#Override
protected void onResume() {
super.onResume();
if (mGoogleApiClient == null) {
// Create the API client and bind it to an instance variable.
// We use this instance as the callback for connection and connection
// failures.
// Since no account name is passed, the user is prompted to choose.
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
// Connect the client. Once connected, the camera is launched.
mGoogleApiClient.connect();
}
#Override
protected void onPause() {
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
super.onPause();
}
#Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_CODE_CAPTURE_VIDEO:
// Called after a photo has been taken.
if (resultCode == Activity.RESULT_OK) {
// Store the image data as a bitmap for writing later.
mVideoToSave = (Byte) data.getExtras().get("data");
}
break;
case REQUEST_CODE_CREATOR:
// Called after a file is saved to Drive.
if (resultCode == RESULT_OK) {
Log.i(TAG, "Image successfully saved.");
mVideoToSave = null;
// Just start the camera again for another photo.
startActivityForResult(new Intent(MediaStore.ACTION_VIDEO_CAPTURE),
REQUEST_CODE_CAPTURE_VIDEO);
}
break;
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// Called whenever the API client fails to connect.
Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());
if (!result.hasResolution()) {
// show the localized error dialog.
GoogleApiAvailability.getInstance().getErrorDialog(this, result.getErrorCode(), 0).show();
return;
}
// The failure has a resolution. Resolve it.
// Called typically when the app is not yet authorized, and an
// authorization
// dialog is displayed to the user.
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
} catch (SendIntentException e) {
Log.e(TAG, "Exception while starting resolution activity", e);
}
}
#Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "API client connected.");
if (mVideoToSave == null) {
// This activity has no UI of its own. Just start the camera.
startActivityForResult(new Intent(MediaStore.ACTION_VIDEO_CAPTURE),
REQUEST_CODE_CAPTURE_VIDEO);
return;
}
saveFileToDrive();
}
#Override
public void onConnectionSuspended(int cause) {
Log.i(TAG, "GoogleApiClient connection suspended");
}
}
Trying to create an android application to record video and capture images. I've followed the tutorials thus far with some success however I must have a lack of knowledge about the android sdk to not be able to get around this issue. No doubt I will feel stupid once someone figures this out but I'm here to learn in the end.
Here is the MainActivity.java
package example.myapplication;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
public MainActivity(Context context) {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
/** Check if this device has a camera */
public boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Here is the CameraPreview.java
package example.myapplication;
import android.content.Context;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.View;
import android.widget.Button;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
/** A basic Camera preview class */
public class CameraPreview extends MainActivity implements SurfaceHolder.Callback {
private android.hardware.Camera.PictureCallback mPicture;
private Camera mCamera;
private CameraPreview mPreview;
private SurfaceHolder mHolder;
private SurfaceHolder holder;
public void setContentView(int activity_camera) {}
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
private static final String TAG = "CameraPreview";
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: ");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
// 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()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HH:mm:ss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
public void onClick() {
// Add a listener to the Capture button
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0){
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
});
}
public SurfaceHolder getHolder() {
return holder;
}
public void setHolder(SurfaceHolder holder) {
this.holder = holder;
}
}
Here is the AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="example.myapplication" >
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera2" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
and the logcat
Process: example.myapplication, PID: 20671
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{example.myapplication/example.myapplication.MainActivity}: java.lang.InstantiationException: can't instantiate class example.myapplication.MainActivity; no empty constructor
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2514)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2653)
at android.app.ActivityThread.access$800(ActivityThread.java:156)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1355)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5872)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:674)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.InstantiationException: can't instantiate class installation04.myapplication.MainActivity; no empty constructor
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1208)
at android.app.Instrumentation.newActivity(Instrumentation.java:1079)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2505)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2653)
at android.app.ActivityThread.access$800(ActivityThread.java:156)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1355)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5872)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:674)
at dalvik.system.NativeStart.main(Native Method)
A couple of things that need to be sorted:
Please remove all constructors from classes that extend Activity. - Activities do not work this way. Please look read how Activity Life cycle works.
Please add the CameraPreview activity to your manifest as well.
delete MainActivity constructor
public MainActivity(Context context) {
}
Please read carefully the stacktrace:
java.lang.RuntimeException: Unable to instantiate activity
ComponentInfo{example.myapplication/example.myapplication.MainActivity}:
java.lang.InstantiationException: can't instantiate class
example.myapplication.MainActivity; no empty constructor
You have created constructor in your Activity. Remove the constructor from your Activities and use the Lifecycle callbacks.
As per android guidelines you should not create constructor in the Activity classes since android OS creates object of Activity classes and it use the default empty constructor of the class to create object.
I have a torch class, when I use ledon() my flashlight turns on.
When I use ledoff() it turns off. But if i try to turn it back on again, I get a force close.
And then it turns on again if I try.
What is the reason for the force close?
import android.hardware.Camera;
import android.util.Log;
import static android.hardware.Camera.*;
/**
* Created by tyler on 8/13/13.
*/
public class Torch {
private static final String TAG = "Light";
private static Camera mCamera;
private static Camera.Parameters mParameters;
public static Camera getCameraInstance() {
Camera c = null;
try {
c = open();
} catch (Exception e) {
}
return c;
}
public static void ledon()
{
mCamera = getCameraInstance();
mParameters = mCamera.getParameters();
mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(mParameters);
Log.d(TAG, "Turn On");
}
public static void ledoff(MainActivity activity) {
String flashMode = mParameters.getFlashMode();
if (Camera.Parameters.FLASH_MODE_OFF.equals(flashMode)) {
mCamera = getCameraInstance();
}
mParameters = mCamera.getParameters();
mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
mCamera.setParameters(mParameters);
Log.d(TAG, "Turn Off");
}
}
EDIT: Here is my updated code, it turns off and on all I want, but when I turn it on and then on again, it Force Closes. Logcat below code.
import android.hardware.Camera;
import android.util.Log;
/**
* Created by tyler on 8/13/13.
*/
public class Torch {
private static final String TAG = "Light";
private static Camera mCamera;
private static Camera.Parameters mParameters;
public static Camera getCameraInstance() {
Camera c = null;
try {
c = mCamera.open();
} catch (Exception e) {
}
return c;
}
public static void ledon() {
mCamera = getCameraInstance();
mParameters = mCamera.getParameters();
String flashMode = mParameters.getFlashMode();
if (! flashMode.equals(Camera.Parameters.FLASH_MODE_TORCH)) {
mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(mParameters);
Log.d(TAG, "Turn On");
}
}
public static void ledoff() {
String flashMode = mParameters.getFlashMode();
if (! flashMode.equals(Camera.Parameters.FLASH_MODE_OFF)) {
mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
mCamera.setParameters(mParameters);
mCamera.release();
Log.d(TAG, "Turn Off");
}
}
}
Logcat:
08-15 12:01:10.502 25951-25951/com.tyler.myapp W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x4170f898)
08-15 12:01:10.522 25951-25951/com.tyler.myapp E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NullPointerException
at com.tyler.myapp.Torch.ledon(Torch.java:28)
Without your logcat, nobody can say for sure what is your problem, but I suspect something. After calling ledon you should call mCamera.release() to tell the android system that you are no longer using the Camera. If you don't call this, on the next call to ledon, you try to allocate a new Camera object, but the Camera with id=0 is used by an application, which is YOUR application, and therefore it throws a RuntimeException. You catch it, and then set the mCamera to null and then later reference mCamera, hence the NullPointerException which I suspect to be the cause.
I'm not sure as I didn't check it but I think because you are updating the mParameters in the ledOff.
try this method
public static void ledSwitch() {
mCamera = getCameraInstance();
mParameters = mCamera.getParameters();
String flashMode = mParameters.getFlashMode();
if (Camera.Parameters.FLASH_MODE_OFF.equals(flashMode)) {
mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
Log.d(TAG, "Turn On");
} else {
mCamera.release()
mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
Log.d(TAG, "Turn Off");
}
}
this method will check if it's on will make it off, if it's off will make it on.
I took .release() from Levente Kurusa :D
updated --
try this, as an HTC user I use different way of camera as I read, so I searched the internet for you.
public static Camera mCameraDevice;
private static List<String> flashModes;
private static String currentFlashMode;
Camera.Parameters param = mCameraDevice.getParameters();
flashModes = param.getSupportedFlashModes();
if (flashModes != null) {
currentFlashMode = param.getFlashMode();
if (currentFlashMode.equals(Parameters.FLASH_MODE_OFF)) {
currentFlashMode = Parameters.FLASH_MODE_ON;
}
else {
currentFlashMode = Parameters.FLASH_MODE_OFF;
}
param.setFlashMode(currentFlashMode);
mCameraDevice.setParameters(param);
}
&& don't forget to use these permissions
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
Can anybody point out the error I am doing? I am trying to record a short video, but somehow it finds a way to crash.
Source Code:
public class Start_recording extends Activity implements SurfaceHolder.Callback
{
MediaRecorder recorder;
SurfaceHolder surfaceHolder;
SurfaceView myVideoView;
Camera camera;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
camera = Camera.open();
camera.unlock();
recorder = new MediaRecorder();
setContentView(R.layout.activity_main_rst);
myVideoView = (SurfaceView)findViewById(R.id.surface_camera);
surfaceHolder = myVideoView.getHolder();
surfaceHolder.addCallback(this);
initMediaRecorder();
boolean exists = (new File(android.os.Environment.getExternalStorageDirectory() + "/Record/")).exists();
if (!exists)
{
new File(android.os.Environment.getExternalStorageDirectory() + "/Record/").mkdirs();
}
try
{
recorder.prepare(); // This is the line of error.
recorder.start();
Thread.sleep(36000);
recorder.stop();
setupActionBar();
}
catch(Exception e)
{
Log.v("Error is there : ",e.toString());
e.printStackTrace();
}
}
public void initMediaRecorder()
{
try
{
recorder.setPreviewDisplay(surfaceHolder.getSurface());
recorder.setCamera(camera);
recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(android.os.Environment.getExternalStorageDirectory()+"/Record/test.3gp");
recorder.setMaxDuration(300000);
}
catch(Exception f)
{
Log.v("Exception here : ",f.toString());
f.printStackTrace();
}
}
}
Error :
E/MediaRecorderJNI(1575): Application lost the surface
V/Error is there :(1575): java.io.IOException: invalid preview surface
W/System.err(1575): java.io.IOException: invalid preview surface
W/System.err(1575): at android.media.MediaRecorder._prepare(Native Method)
W/System.err(1575): at android.media.MediaRecorder.prepare(MediaRecorder.java:666)
W/System.err(1575): at com.example.project.Start_recording.onCreate(Start_recording.java:51)
I have added the permissions correctly in the Manifest file and also set the setPreviewDisplay(). But I get as invalid preview surface.Please correct me.
One has to use SurfaceHolder.Callback to start recording only after the surface really is created.