I'm having some errors with my custom recording application using android. I saw most of this code from a book called PRO Android Media. I developed the app using sdk "8" version. However, I am testing the phone on my htc evo 4g which just got updated to gingerbread. So I dont know how much that would have changed. Anyways my app still wasnt working when i tested it on 2.2 version either.
Here is the code below
package com.apapa.vrsixty;
import java.io.File;
import java.io.IOException;
import android.R.string;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
public class record extends Activity implements OnClickListener, SurfaceHolder.Callback{
MediaRecorder recorder;
SurfaceHolder holder;
boolean recording=false;
public static final String TAG = "VIDEOCAPTURE";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
recorder = new MediaRecorder();// Instantiate our media recording object
initRecorder();
setContentView(R.layout.view);
SurfaceView cameraView = (SurfaceView) findViewById(R.id.surface_view);
holder = cameraView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
cameraView.setClickable(true);// make the surface view clickable
cameraView.setOnClickListener((OnClickListener) this);// onClicklistener to be called when the surface view is clicked
}
private void initRecorder() {// this takes care of all the mediarecorder settings
File OutputFile = new File(Environment.getExternalStorageDirectory().getPath());
String video= "/DCIM/100MEDIA/Video";
CamcorderProfile cpHigh = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
recorder.setProfile(cpHigh);
//recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
// default microphone to be used for audio
// recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);// default camera to be used for video capture.
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);// generally used also includes h264 and best for flash
// recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); //well known video codec used by many including for flash
//recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);// typically amr_nb is the only codec for mobile phones so...
//recorder.setVideoFrameRate(15);// typically 12-15 best for normal use. For 1080p usually 30fms is used.
// recorder.setVideoSize(720,480);// best size for resolution.
//recorder.setMaxFileSize(10000000);
recorder.setOutputFile(OutputFile.getAbsolutePath()+video+".3gp");
//recorder.setVideoEncodingBitRate(256000);//
//recorder.setAudioEncodingBitRate(8000);
recorder.setMaxDuration(600000);
}
/*if(record.setMaxDuration>60000){
recorder.stop();
MediaRecorder.OnInfoListener;
Toast display = Toast.makeText(this, "You have exceeded the record time", Toast.LENGTH_SHORT);// toast shows a display of little sorts
display.show();
return true;
}*/
private void prepareRecorder() {
recorder.setPreviewDisplay(holder.getSurface());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
finish();
} catch (IOException e) {
e.printStackTrace();
finish();
}
}
public void onClick(View v) {
if (recording) {
recorder.stop();
recording = false;
// Let's initRecorder so we can record again
initRecorder();
prepareRecorder();
Toast display = Toast.makeText(this, "Stopped Recording", Toast.LENGTH_SHORT);// toast shows a display of little sorts
display.show();
} else {
recorder.start();
Log.v(TAG,"Recording Started");
recording = true;
}
}
public void surfaceCreated(SurfaceHolder holder) {
initRecorder();
Log.v(TAG,"surfaceCreated");
prepareRecorder();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
if (recording) {
recorder.stop();
recording = false;
}
recorder.release();
finish();
}
Its bringing up these errors.
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.apapa.vrsixty/com.apapa.vrsixty.record}: java.lang.IllegalStateException
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1821)
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1842)
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): at android.app.ActivityThread.access$1500(ActivityThread.java:132)
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1038)
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): at android.os.Handler.dispatchMessage(Handler.java:99)
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): at android.os.Looper.loop(Looper.java:143)
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): at android.app.ActivityThread.main(ActivityThread.java:4263)
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): at java.lang.reflect.Method.invokeNative(Native Method)
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): at java.lang.reflect.Method.invoke(Method.java:507)
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): at dalvik.system.NativeStart.main(Native Method)
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): Caused by: java.lang.IllegalStateException
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): at android.media.MediaRecorder.setOutputFormat(Native Method)
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): at android.media.MediaRecorder.setProfile(MediaRecorder.java:293)
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): at com.apapa.vrsixty.record.initRecorder(record.java:67)
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): at com.apapa.vrsixty.record.onCreate(record.java:50)
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1072)
06-09 13:37:52.833: ERROR/AndroidRuntime(27979): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1785)
Please any help will suffice please. I just cant wait to see an actually recording in stead of "The application has stopped unexpectedly."
Update:
Well thanks, recorder.reset(); worked for me but I am having an issue when I start the recorder. I have to click on my phone before it actually shows the preview. Also, how do i make the recorder show numbers in a countdown when the video starts recording? The video doesn't save to my sd card even though i include
recorder.OutPutFile("/sdcard/video.mp4");
And I have the permission WRITE_EXTERNAL_STORAGE in my manifest file.
Another question is how do i save the video in an incrememntal manner. For example, the first video that i record saves as "video1", the second video is "video2" and so on and so forth. I will appreciate any help that I can get with this issue thank you.
You also need to make sure you can write to the SD Card:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
Finally, you MUST set the audio and video source. Try replacing your initRecorder method with the one from the book to see if you get further:
private void initRecorder() {
recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
CamcorderProfile cpHigh = CamcorderProfile
.get(CamcorderProfile.QUALITY_HIGH);
recorder.setProfile(cpHigh);
recorder.setOutputFile("/sdcard/videocapture_example.mp4");
recorder.setMaxDuration(50000); // 50 seconds
recorder.setMaxFileSize(5000000); // Approximately 5 megabytes
}
You didn't know the function setProfile().
The function setProfile() do all of the things below:
setProfile after setOutputFormat.
public void setProfile(CamcorderProfile profile) {
setOutputFormat(profile.fileFormat);
setVideoFrameRate(profile.videoFrameRate);
setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);
setVideoEncodingBitRate(profile.videoBitRate);
setAudioEncodingBitRate(profile.audioBitRate);
setAudioChannels(profile.audioChannels);
setAudioSamplingRate(profile.audioSampleRate);
setVideoEncoder(profile.videoCodec);
setAudioEncoder(profile.audioCodec);
}
Do you have the permission set in AndroidManifest.xml?
<uses-permission android:name="android.permission.CAMERA"></uses-permission>
Also I have had issues like this before try calling:
recorder.reset();
at the start of your initRecorder() method.
Related
I am trying to implement the camera SDK example code from the Android website, but when I try to run the app I get this Null Pointer Exception and logcat doesn't really give me a whole lot of info to go on. I am pretty new to Android development so I am not sure how to proceed in debugging this issue.
06-07 09:48:24.960 927-927/com.luketim.cam.cam2.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.luketim.cam.cam2.app, PID: 927
java.lang.NullPointerException
at com.luketim.cam.cam2.app.CameraPreview.surfaceCreated(CameraPreview.java:34)
at android.view.SurfaceView.updateWindow(SurfaceView.java:572)
at android.view.SurfaceView.access$000(SurfaceView.java:86)
at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:175)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:847)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1871)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5670)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
at android.view.Choreographer.doCallbacks(Choreographer.java:574)
at android.view.Choreographer.doFrame(Choreographer.java:544)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
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:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
Here is the class with the method where this NullPointerException is thrown.
package com.luketim.cam.cam2.app;
import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
/**
* Created by luketimothy on 06/06/2014.
*/
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "";
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(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());
}
}
}
logcat doesn't really give me a whole lot of info to go on
It tells you the line of code on which you crashed (CameraPreview.java:34, in your surfaceCreated() method), and why you crashed (a NullPointerException occurred on that line).
Since there are only two lines in surfaceCreated(), it is clear that mCamera is null. Since that is provided from outside the code that you have listed, you will need to track down where you are opening the camera and determine why that did not work as expected.
FWIW, writing a camera application in Android is rather difficult. It is not something that somebody new to Android should be attempting. I offer a library to try to simplify using the camera from within an app, but even that does not yet handle every oddball thing that device manufacturers do.
I'm am trying to capture an image in the ontouchevent of surfaceview. However, everytime a touch the screen, the app crashes with the following exception:
01-05 21:03:18.500: ERROR/AndroidRuntime(10367): FATAL EXCEPTION: main
java.lang.RuntimeException: takePicture failed
at android.hardware.Camera.native_takePicture(Native Method)
at android.hardware.Camera.takePicture(Camera.java:1126)
at android.hardware.Camera.takePicture(Camera.java:1071)
at com.test.MotionDetector.CameraSurfaceView.onTouchEvent(CameraSurfaceView.java:107)
at android.view.View.dispatchTouchEvent(View.java:7350)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2470)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2212)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2470)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2212)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2470)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2212)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2151)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1480)
at android.app.Activity.dispatchTouchEvent(Activity.java:2469)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2099)
at android.view.View.dispatchPointerEvent(View.java:7535)
at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3492)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3424)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4534)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4512)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4616)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:171)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:125)
at android.os.Looper.loop(Looper.java:124)
at android.app.ActivityThread.main(ActivityThread.java:4921)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
at dalvik.system.NativeStart.main(Native Method)
My code:
package com.nadim.MotionDetector;
import android.content.Context;
import android.hardware.Camera;
import android.os.Environment;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
private Context context;
public CameraSurfaceView(Context context, Camera camera) {
super(context);
this.context = 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("MotionDetector", "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("MotionDetector", "Error starting camera preview: " + e.getMessage());
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
Toast.makeText(context, "Picture taken", Toast.LENGTH_SHORT).show();
//System.gc(); tried this because it was suggested in a stackoverflow question but it didn't help.
mCamera.takePicture(null, mPicture, mPicture);
return true; //processed
}
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d("MotionDetector", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("MotionDetector", "Error accessing file: " + e.getMessage());
}
}
};
private static File getOutputMediaFile() {
File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), "motiondetect");
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_HHmmss").format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir, timeStamp + ".jpg");
return mediaFile;
}
}
Permissions and features used:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.camera.flash" />
I don't know why the crash occurs. Many other topic suggest calling Camera.startPreview first. I am doing that, but it doesn't solve the issue.
LogCat before taking picture:
01-05 21:45:57.667: WARN/ActivityManager(754): No content provider found for permission revoke: file:///data/local/tmp/com.test.MotionDetector
01-05 21:45:57.667: WARN/ActivityManager(754): No content provider found for permission revoke: file:///data/local/tmp/com.test.MotionDetector
01-05 21:45:57.687: INFO/ActivityManager(754): Force stopping com.test.MotionDetector appid=10103 user=-1: uninstall pkg
01-05 21:45:57.687: INFO/ActivityManager(754): Killing 4264:com.test.MotionDetector/u0a103 (adj 7): stop com.test.MotionDetector
01-05 21:45:57.687: INFO/ActivityManager(754): Force finishing activity ActivityRecord{437a6678 u0 com.test.MotionDetector/.MotionDetectActivity t144}
01-05 21:45:57.697: WARN/InputDispatcher(754): channel '42adff40 com.test.MotionDetector/com.test.MotionDetector.MotionDetectActivity (server)' ~ Consumer closed input channel or an error occurred. events=0x9
01-05 21:45:57.697: ERROR/InputDispatcher(754): channel '42adff40 com.test.MotionDetector/com.test.MotionDetector.MotionDetectActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
01-05 21:45:57.697: WARN/InputDispatcher(754): Attempted to unregister already unregistered input channel '42adff40 com.test.MotionDetector/com.test.MotionDetector.MotionDetectActivity (server)'
01-05 21:45:57.697: INFO/WindowState(754): WIN DEATH: Window{42adff40 u0 com.test.MotionDetector/com.test.MotionDetector.MotionDetectActivity}
01-05 21:45:57.757: INFO/PackageManager(754): Running dexopt on: com.test.MotionDetector
01-05 21:45:57.757: INFO/PackageManager(754): Package com.test.MotionDetector codePath changed from /data/app/com.test.MotionDetector-1.apk to /data/app/com.test.MotionDetector-2.apk; Retaining data and using new
01-05 21:45:57.807: INFO/ActivityManager(754): Force stopping com.test.MotionDetector appid=10103 user=-1: update pkg
01-05 21:45:57.807: WARN/PackageManager(754): Code path for pkg : com.test.MotionDetector changing from /data/app/com.test.MotionDetector-1.apk to /data/app/com.test.MotionDetector-2.apk
01-05 21:45:57.807: WARN/PackageManager(754): Resource path for pkg : com.test.MotionDetector changing from /data/app/com.test.MotionDetector-1.apk to /data/app/com.test.MotionDetector-2.apk
01-05 21:45:57.937: INFO/ActivityManager(754): Force stopping com.test.MotionDetector appid=10103 user=0: pkg removed
01-05 21:45:57.987: DEBUG/BackupManagerService(754): Received broadcast Intent { act=android.intent.action.PACKAGE_REMOVED dat=package:com.test.MotionDetector flg=0x4000010 (has extras) }
01-05 21:45:58.047: DEBUG/BackupManagerService(754): Received broadcast Intent { act=android.intent.action.PACKAGE_ADDED dat=package:com.test.MotionDetector flg=0x4000010 (has extras) }
01-05 21:45:58.567: INFO/Icing.InternalIcingCorporaProvider(12750): Updating corpora: A: com.test.MotionDetector, C: MAYBE
01-05 21:45:58.647: DEBUG/PackageAddedReceiver(1086): package added com.test.MotionDetector
01-05 21:45:58.737: INFO/ActivityManager(754): START u0 {flg=0x10000000 cmp=com.test.MotionDetector/.MotionDetectActivity} from pid 4578
01-05 21:45:58.777: INFO/ActivityManager(754): Start proc com.test.MotionDetector for activity com.test.MotionDetector/.MotionDetectActivity: pid=4630 uid=10103 gids={50103, 1028, 1015}
01-05 21:45:59.627: INFO/ActivityManager(754): Displayed com.test.MotionDetector/.MotionDetectActivity: +861ms (total +972ms)
01-05 21:45:59.657: INFO/WindowManager(754): Screen frozen for +869ms due to Window{43cb77a8 u0 com.test.MotionDetector/com.test.MotionDetector.MotionDetectActivity}
Assuming that you want the jpeg saved, you don't need raw callback, so
change the call to takePicture() from:
mCamera.takePicture(null, mPicture, mPicture);
to
mCamera.takePicture(null, null, mPicture);
in your onTouchEvent(). This will use jpeg picture callback.
Calling takePicture() also causes the preview to stop, so you might want to call startPreview() again in your onPictureTaken() callback, if you want to take more pictures or have a preview restarted.
Also, in your onTouchEvent(), you might be getting multiple events, so filter for the one that works for you:
#Override
public boolean onTouchEvent(MotionEvent event) {
Toast.makeText(context, "Picture taken", Toast.LENGTH_SHORT).show();
//System.gc(); tried this because it was suggested in a stackoverflow question but it didn't help.
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
// A pressed gesture has started, the motion contains the initial starting location
break;
case MotionEvent.ACTION_UP:
// A pressed gesture has finished, the motion contains the final release location
// as well as any intermediate points since the last down or move event.
mCamera.takePicture(null, mPicture, mPicture);
break;
default:
break;
}
return true; //processed
}
If you place takePicture() in ACTION_DOWN, it will be called as soon as you touch the screen, whereas when in ACTION_UP, it will happen when you remove finger. See which one works for you.
This issue is been driving me crazy for days now. I'm trying to use opencv android the latest package. Everything is inserted and I don't have any errors, until I run the project on android and that's when it crashes. When I call a simple code like, Mat m = new Mat(); the app crashes, I saw some other people has the same problem but somehow they managed to fix it, here is my code, maybe it's something stupid I can't see! All I really need is Matrix library, I tried Jama and jblas but they work to some point but then they crash too, and they're very slow.
package com.ece.facerecog;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;'
import java.util.Arrays;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
import com.ece.facerecog.utils.UIHelper;
//import org.jblas.DoubleMatrix;
//import Jama.Matrix;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
//import android.graphics.Matrix;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
public class Face extends Activity {
private Bitmap bitmap;
private int f = Crop.k;
private ImageView tv;
private static final String TAG = "OCVSample::Activity";
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
// #Override
// public void onResume()
// {
// super.onResume();
// OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_5, this, k mLoaderCallback);
// }
private Bitmap ReadImage1(String fBitmap) {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/preprocessed");
File file = new File(myDir , fBitmap); //or any other format supported
UIHelper.displayText(this, R.id.textView1, file.toString());
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = `BitmapFactory.decodeFile(file.getAbsolutePath(),options); //This gets the image `
return bitmap;
} catch (Exception e) {
e.printStackTrace();
UIHelper.displayText(this, R.id.textView1, "Doesn't exist");
}
return bitmap;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.face);
Log.i(TAG, "Trying to load OpenCV library");
if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_5, this, mLoaderCallback))
{
Log.e(TAG, "Cannot connect to OpenCV Manager");
}
ImageView tv = (ImageView) findViewById(R.id.imageView1);
Bitmap bmp = ReadImage1("/Image-" + f+ ".jpg");
tv.setImageBitmap(bmp);
Mat m = new Mat();
}
}
`
Here's the log error,
04-13 23:14:17.412: E/AndroidRuntime(12111): FATAL EXCEPTION: main
04-13 23:14:17.412: E/AndroidRuntime(12111): java.lang.UnsatisfiedLinkError: Native method not found: org.opencv.core.Mat.n_Mat:()J
04-13 23:14:17.412: E/AndroidRuntime(12111): at org.opencv.core.Mat.n_Mat(Native Method)
04-13 23:14:17.412: E/AndroidRuntime(12111): at org.opencv.core.Mat.<init>(Mat.java:441)
04-13 23:14:17.412: E/AndroidRuntime(12111): at com.ece.facerecog.Face.onCreate(Face.java:147)
04-13 23:14:17.412: E/AndroidRuntime(12111): at android.app.Activity.performCreate(Activity.java:5104)
04-13 23:14:17.412: E/AndroidRuntime(12111): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
04-13 23:14:17.412: E/AndroidRuntime(12111): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
04-13 23:14:17.412: E/AndroidRuntime(12111): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
04-13 23:14:17.412: E/AndroidRuntime(12111): at android.app.ActivityThread.access$600(ActivityThread.java:141)
04-13 23:14:17.412: E/AndroidRuntime(12111): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
04-13 23:14:17.412: E/AndroidRuntime(12111): at android.os.Handler.dispatchMessage(Handler.java:99)
04-13 23:14:17.412: E/AndroidRuntime(12111): at android.os.Looper.loop(Looper.java:137)
04-13 23:14:17.412: E/AndroidRuntime(12111): at android.app.ActivityThread.main(ActivityThread.java:5039)
04-13 23:14:17.412: E/AndroidRuntime(12111): at java.lang.reflect.Method.invokeNative(Native Method)
04-13 23:14:17.412: E/AndroidRuntime(12111): at java.lang.reflect.Method.invoke(Method.java:511)
04-13 23:14:17.412: E/AndroidRuntime(12111): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
04-13 23:14:17.412: E/AndroidRuntime(12111): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
04-13 23:14:17.412: E/AndroidRuntime(12111): at dalvik.system.NativeStart.main(Native Method)
Thanks for helping me out!
OpenCV functions such as Mat have to be invoked in either a thread or AsyncTask, I think. I faced the SAME issue for AGES without help.
For you to avoid crashes, you could declare Mat m as a global variable and initialize it in the AsyncInitialization block of OpenCV.
Something like this :
public class Face extends Activity {
private Bitmap bitmap;
private int f = Crop.k;
private ImageView tv;
Mat m;
private static final String TAG = "OCVSample::Activity";
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
m=new Mat();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
If it still crashes, I would suggest you execute whatever function you're trying in an AsyncTask like in my project. Mat functions however can be declared without the risk of the UnsatisfiedLinkError exception in OpenCV functions. Functions called in the UI however experience this. At least this is what I've seen.
I just faced the same problem and found another solution:
You can use another activity to call your activity ("Face"), like some introduction screen with a button that starts your activity. If you initialize OpenCV in this introduction activity (same way you did in your activity) you can use OpenCV functions in the next activity without any problem...
This way you don't have to declare OpenCV variables as a global variables and initialize them in the AsyncInitialization block of OpenCV.
So what I am trying to create is an activity that displays an image button. The background for the image button points to an xml in the drawable folder to show the different pictures for on focus and click. That all works fine. I have music in my main activity that is set to loop. By default the image button is set to say Music On. What I want to happen is when the button is clicked the main sound will pause and the button background will change to a different xml drawable layout that says Music Off. When it is clicked again the music will resume where it left off and again switch back to Music On.
One problem I am having is pausing the main sound. Since I'm new to android can a media player variable I reference in my main activity be changed in a different activity? Also, in my options activity I have two if statements under the on click for the image button to check whether the sound is playing or isn't and then will either pause or resume the music depending on which one it is. I am not sure how to do the second if statement but I have the first one that I think might be right.
Sorry that there are a lot of different things I am trying to do, but I tried to break it down. Also, I am getting force closes as of now when I start the optionsActivity and I will put everything underneath including the main activity because that is where I establish the mainSound. Thanks for any help you can give me.
MainActivity:
package com.crazycastles;
import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageButton;
public class MainActivity extends Activity implements OnClickListener {
/** Called when the activity is first created. */
private MediaPlayer mainSound;
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK)) { //Back key pressed //Things to Do
if(mainSound!= null) { mainSound.pause(); mainSound=null; } finish(); return true; } return super.onKeyDown(keyCode, event); }
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mainSound = MediaPlayer.create(MainActivity.this, R.raw.mainscreen);
mainSound.setLooping(true);
mainSound.start();
//CREATE BUTTON 1 & SOUND
final MediaPlayer buttonSound = MediaPlayer.create(
MainActivity.this, R.raw.swords);
ImageButton button1 = (ImageButton) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
buttonSound.start();
startActivity(new Intent(MainActivity.this,
button1Activity.class));
}
});
ImageButton multiplayerbutton = (ImageButton) findViewById(R.id.multiplayerbutton);
multiplayerbutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
buttonSound.start();
startActivity(new Intent(MainActivity.this,
multiplayerbuttonActivity.class));
}
});
ImageButton optionsbutton = (ImageButton) findViewById(R.id.optionsbutton);
optionsbutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
buttonSound.start();
startActivity(new Intent(MainActivity.this,
optionsActivity.class));
}
});
ImageButton creditbutton = (ImageButton) findViewById(R.id.creditbutton);
creditbutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
buttonSound.start();
startActivity(new Intent(MainActivity.this,
creditsActivity.class));
}
});
ImageButton exitbutton = (ImageButton) findViewById(R.id.exitbutton);
exitbutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
buttonSound.start();
finish();
mainSound.stop();
System.exit(0);
}
});
//END OF BUTTON1 & SOUND
}
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
optionsActivity:
package com.crazycastles;
import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageButton;
public class optionsActivity extends Activity {
/** Called when the activity is first created. */
ImageButton musicbutton, musicbutton2;
private MediaPlayer mainSound;
final MediaPlayer buttonSound = MediaPlayer.create(
optionsActivity.this, R.raw.swords);
#Override
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.options);
final ImageButton musicbutton = (ImageButton) findViewById(R.id.musicbutton);
musicbutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(mainSound.isPlaying()) {
musicbutton.setBackgroundResource(R.drawable.musicbutton2);
buttonSound.start();
mainSound.pause();
}
}
});
}
}
LogCat:
01-15 16:10:55.059: E/AndroidRuntime(7319): FATAL EXCEPTION: main
01-15 16:10:55.059: E/AndroidRuntime(7319): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.crazycastles/com.crazycastles.optionsActivity}: java.lang.NullPointerException
01-15 16:10:55.059: E/AndroidRuntime(7319): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2659)
01-15 16:10:55.059: E/AndroidRuntime(7319): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2753)
01-15 16:10:55.059: E/AndroidRuntime(7319): at android.app.ActivityThread.access$2500(ActivityThread.java:129)
01-15 16:10:55.059: E/AndroidRuntime(7319): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2107)
01-15 16:10:55.059: E/AndroidRuntime(7319): at android.os.Handler.dispatchMessage(Handler.java:99)
01-15 16:10:55.059: E/AndroidRuntime(7319): at android.os.Looper.loop(Looper.java:143)
01-15 16:10:55.059: E/AndroidRuntime(7319): at android.app.ActivityThread.main(ActivityThread.java:4701)
01-15 16:10:55.059: E/AndroidRuntime(7319): at java.lang.reflect.Method.invokeNative(Native Method)
01-15 16:10:55.059: E/AndroidRuntime(7319): at java.lang.reflect.Method.invoke(Method.java:521)
01-15 16:10:55.059: E/AndroidRuntime(7319): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
01-15 16:10:55.059: E/AndroidRuntime(7319): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
01-15 16:10:55.059: E/AndroidRuntime(7319): at dalvik.system.NativeStart.main(Native Method)
01-15 16:10:55.059: E/AndroidRuntime(7319): Caused by: java.lang.NullPointerException
01-15 16:10:55.059: E/AndroidRuntime(7319): at android.content.ContextWrapper.getResources(ContextWrapper.java:80)
01-15 16:10:55.059: E/AndroidRuntime(7319): at android.media.MediaPlayer.create(MediaPlayer.java:641)
01-15 16:10:55.059: E/AndroidRuntime(7319): at com.crazycastles.optionsActivity.<init>(optionsActivity.java:17)
01-15 16:10:55.059: E/AndroidRuntime(7319): at java.lang.Class.newInstanceImpl(Native Method)
01-15 16:10:55.059: E/AndroidRuntime(7319): at java.lang.Class.newInstance(Class.java:1429)
01-15 16:10:55.059: E/AndroidRuntime(7319): at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
01-15 16:10:55.059: E/AndroidRuntime(7319): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2651)
I also have developed a music player in Android
One problem I am having is pausing the main sound. Since I'm new to
android can a media player variable I reference in my main activity be
changed in a different activity?
I could say it yes, if you declare it as a static Object
Also, in my options activity I have two if statements under the on
click for the image button to check whether the sound is playing or
isn't and then will either pause or resume the music depending on
which one it is. I am not sure how to do the second if statement but I
have the first one that I think might be right.
I think you have to look at Android Media Player lifecycle, you could re-use your object but there is some conditions : http://developer.android.com/reference/android/media/MediaPlayer.html
Since I'm new to android can a media player variable I reference in my main activity be changed in a different activity?
No. If you create a MediaPlayer in an activity, it should only be used while that activity is in the foreground. Your MediaPlayer most likely should be managed by a Service, if you are planning on it continuing to play once the user has left the activity.
I am developing an app for android that has to access another class, but i don't know why it doesn't work.
When run the App in android 2.3.3 it force closes, and I don't understand why. I think that the method is correct.
Log in the force close the phone android:
> app_vercode:1
device_model:u8800
build_version:111180
condition:1
processName:beta.tester
pid:13277
uid:10088
tag:null
shortMsg:java.lang.NullPointerException
longMsg:java.lang.NullPointerException: Unable to start activity ComponentInfo{beta.tester/beta.tester.BetaTesterActivity}: java.lang.NullPointerException
stackTrace:java.lang.RuntimeException: Unable to start activity ComponentInfo{beta.tester/beta.tester.BetaTesterActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1664)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1680)
at android.app.ActivityThread.access$1500(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3703)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at beta.tester.BetaTesterActivity.onCreate(BetaTesterActivity.java:23)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1628)
... 11 more
Detail logs:
EDIT: This code already is correctly.
The code:
class BetaTesterActivity:
package beta.tester;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class BetaTesterActivity extends Activity {
public TextView text1;
private teste cmd;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text1 = (TextView) findViewById(R.id.text1);
//Start the function
cmd = new teste();
cmd.start(this);
}
}
class teste:
package beta.tester;
public class teste {
//Function that I will start
public void start(BetaTesterActivity zav){
zav.text1.setText("Hello");
}
//
}
In class teste, you are creating a new BetaTesterActivity, which is useless. You need to use the instance created by the framework. Change your class teste to this:
public class teste {
//Function that I will start
public void start(BetaTesterActivity zav){
zav.text1.setText("Hello");
}
}
Then in the onCreate method of your activity class, you need to initialize cmd and then call start like this:
cmd.start(this);