I wrote an Android Flash Light application but that seems to show some strange behavior.
The code that is invoked on clicking the "Turn On" button is
public void flashLightOn(View view){
try {
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH))
cam = Camera.open(0);
Camera.Parameters p = cam.getParameters();
p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
cam.setParameters(p);
cam.startPreview();
}catch (Exception e){
e.printStackTrace();
}
}
Now , the strange thing is that this app works fine on some phones and doesn't work on others.
I have tried it on my OnePlus One and Motorola Droid Mini and on both of them it works fine, but when I ran it on a Motorola Droid RAZR and Moto E it didn't work.
I am not able to understand the problem here. Can anyone help?
Replace your code with:
public void flashLightOn(View view){
try {
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH))
{ // you don't added this
cam = Camera.open(0);
Camera.Parameters p = cam.getParameters();
p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
cam.setParameters(p);
cam.startPreview();
} // and this
}catch (Exception e){
e.printStackTrace();
}
}
Related
I am creating an app, in which I am setting a profile image and cover image ,so on setting profile image I want to open the front camera by default using intent.
I am using
pictureIntent.putExtra("android.intent.extras.CAMERA_FACING",1);
Its working on Sony but when I tested on a Samsung Galaxy J4 ,it's opening the back camera. I searched and found somewhere that for Samsung one should use value 2.
However it's not working.
I want to do this using intent only.
Does anyone have an idea about it?
You can do like below,
private Camera openFrontFacingCamera() {
int cameraCount = 0;
Camera cam = null;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for ( int camIdx = 0; camIdx < cameraCount; camIdx++ ) {
Camera.getCameraInfo( camIdx, cameraInfo );
if ( cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT ) {
try {
cam = Camera.open( camIdx );
} catch (RuntimeException e) {
Log.e(TAG, "Camera failed to open: " + e.getLocalizedMessage());
}
}
}
return cam;
}
And then use it in your app as follows:
public static Camera getCameraInstance() {
Camera c = null;
try {
c = openFrontFacingCamera();
}
catch (Exception e){
}
return c;
}
My photo taking algorithm works perfectly the first time, but if I call the method the second time, I get java.lang.RuntimeException: Fail to connect to camera service on camera.open()
takePhoto(this, 0);//back camera.
takePhoto(this, 1);//selfie. No matter what, the second line crashes. Even if I switch the two lines.
Here is the method that only works the first time:
private void takePhoto(final Context context, final int frontorback) {
Log.v("myTag", "In takePhoto()");
final SurfaceView preview = new SurfaceView(context);
SurfaceHolder holder = preview.getHolder();
// deprecated setting, but required on Android versions prior to 3.0
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holder.addCallback(new SurfaceHolder.Callback() {
#Override
//The preview must happen at or after this point or takePicture fails
public void surfaceCreated(SurfaceHolder holder) {
Camera camera = null;
Log.v("myTag", "Surface created ");
try {
camera = Camera.open(frontorback); //** THIS IS WHERE IT CRASHES THE SECOND TIME **
Log.v("myTag", "Opened camera");
try {
camera.setPreviewDisplay(holder);
} catch (IOException e) {
Log.v("myTag", "Can't assign preview to Surfaceview holder" + e.toString());
}
try {
camera.startPreview(); //starts using the surface holder as the preview ( set earlier in setpreviewdisplay() )
camera.autoFocus(new Camera.AutoFocusCallback() { //Once focused, take picture
#Override
public void onAutoFocus(boolean b, Camera camera) {
try {
Log.v("myTag", "Started focusing");
camera.takePicture(null, null, mPictureCallback);
Log.v("myTag", "Took picture!");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
} catch (Exception e) {
Log.v("myTag", "Can't start camera preview " + e.toString());
if (camera != null)
camera.release();
throw new RuntimeException(e);
}
}catch(Exception e){
Log.v("myTag", "can't open camera " +e.toString());
e.printStackTrace();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
});
addPreviewToSurfaceView(); //Irrelavent here
}
//CALLBACK WHERE I RELEASE:
android.hardware.Camera.PictureCallback mPictureCallback = new android.hardware.Camera.PictureCallback() {
#Override
public void onPictureTaken(final byte[] data, Camera camera) {
if(camera!=null){
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
downloadPicture(data);
sendPicture(data);
Log.v("myTag","Picture downloaded and sent");
}
};
It's odd, because takePhoto(context, int) only works the first time no matter what. Even if I switch the second parameter, only the first takePhoto() works.
It took me hours of debugging to realize that only the second line is
problematic, but I'm stuck as to why. Any feedback is much
appreciated!
EDIT:
Even after removing the code in my onPictureTaken callback, the problem continues to persist. I suspect the camera may need time to reopen immediately, but I can't sleep the thread since I'm performing UI interactions on it. This bug is like a puzzle right now!
You cannot call takePhoto() one after another, because this call takes long time (and two callbacks) to complete. You should start the second call after the first picture is finished. Here is an example, based on your code:
private void takePhoto(final Context context, final int frontorback) {
...
android.hardware.Camera.PictureCallback mPictureCallback = new android.hardware.Camera.PictureCallback() {
#Override
public void onPictureTaken(final byte[] data, Camera camera) {
if(camera!=null){
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
if (frontorback == 0) {
takePhoto(context, 1);
}
}
downloadPicture(data);
sendPicture(data);
Log.v("myTag","Picture downloaded and sent");
}
};
This will start the first photo and start the second photo only when the first is complete.
Here might be problem.
After you take photo, the picture taken callback get called.
if(camera!=null){
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
And the camera has been released, so the second time won't work. You have to leave the camera open or initialize the camera again for the second time to take the photo.
Good afeternoon
First of all, this is my first android project.
In my project I have an audio recorder and it works fine, the problem is when I switch the screen rotation gives an error and the app turns off.
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile("/dev/null");
try {
recorder.prepare();
recorder.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Error appears when Android Studio reads the line recorder.start(), after rotating the screen.
The error description is Unable to start activity ComponentInfo{com.example.duarte.mediaplayerandroid/com.example.duarte.mediaplayerandroid.MainActivity}: java.lang.RuntimeException: start failed.
To handle screen rotation, Add (Override) the method onConfigurationChanged() in your Activity . As you just want to avoid config. changes,don't put any code into it. Following is the example:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
//Nothing here...
}
My alarm program on Android does not work on many Samsung and HTC devices; it does not turn on the screen and does not play alarm until the screen is manually turned on.
This problem is in Sony Xperia P and Huawei Honor phone...
I use any thing that I think solve my problem in my code, but it isn't fixed! :(
This is my code:
try {
// baraye roshan kardane safe va roshan negah dashtane oon dar Huawei honor
PowerManager mPowerManager = (PowerManager) PlayAlarmActivity.this.getSystemService(Context.POWER_SERVICE);
mWakeLock = mPowerManager.newWakeLock((PowerManager.FULL_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP), "Power Manager");
mWakeLock.acquire();
Log.i("Unlock Screen", "1");
} catch (Exception e) {
Log.e("Error in playalarmactivity for unlock screen 1 ...", e.toString());
}
try {
// Set the window to keep screen on
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
Log.i("Unlock Screen", "2");
} catch (Exception e) {
Log.e("Error in playalarmactivity for unlock screen 2 ...", e.toString());
}
try {
// baraye baz kardane lock dar gooshihayi mesle sonye Masoud!!! :D
km = (KeyguardManager) PlayAlarmActivity.this.getSystemService(Context.KEYGUARD_SERVICE);
kl = km.newKeyguardLock("MyKeyguardLock");
kl.disableKeyguard();
Log.i("Unlock Screen", "3");
} catch (Exception e) {
Log.e("Error in playalarmactivity for unlock screen 3 ...", e.toString());
}
Try adding this permission to your AndroidManifest.xml:
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
I had my camera set to this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); and it works fine but if I change it to PORTRAIT instead of LANDSCAPE then it crashes with the following error...
07-30 12:51:37.655: ERROR/AndroidRuntime(22069): FATAL EXCEPTION: main
07-30 12:51:37.655: ERROR/AndroidRuntime(22069): java.lang.RuntimeException: Fail to connect to camera service
07-30 12:51:37.655: ERROR/AndroidRuntime(22069): at android.hardware.Camera.native_setup(Native Method)
07-30 12:51:37.655: ERROR/AndroidRuntime(22069): at android.hardware.Camera.<init>(Camera.java:110)
07-30 12:51:37.655: ERROR/AndroidRuntime(22069): at android.hardware.Camera.open(Camera.java:90)
07-30 12:51:37.655: ERROR/AndroidRuntime(22069): at org.digital.com.CamLayer.surfaceCreated(CamLayer.java:3
The method it crashes in is..
public void surfaceCreated(SurfaceHolder holder) {
synchronized(this) {
mCamera = Camera.open();
Camera.Parameters p = mCamera.getParameters();
p.setPreviewSize(800, 480);
mCamera.setParameters(p);
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
Log.e("Camera", "mCamera.setPreviewDisplay(holder);");
}
mCamera.startPreview();
mCamera.setPreviewCallback(this);
}
}
It crashes at mCamera = Camera.open();
My Manifest file has <uses-permission android:name="android.permission.CAMERA"></uses-permission>
How do I fix this so I can view my app in Portrait?
There is some concurrency problem in platform: http://code.google.com/p/android/issues/detail?id=6201
The workaround is to clear callback before releasing cam, that is I would recommend following clean-up code:
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mCam != null) {
mCam.stopPreview();
mCam.setPreviewCallback(null);
mCam.release();
mCam = null;
}
}
For your reference, this is the SurfaceHolderCallBack inner class that I'm using in my app and which works fine on Nexus One 2.2 in portrait mode - hope it helps.
Edit: "which works" = "which doesn't crash". Although I haven't figured out how to rotate the preview image correctly (see my first comment above). That's why I actually had to use landscape and 'convert' UI stuff that's surrounding the preview surface into landscape mode.
Afaik preview (with correct rotation of the preview image) only works in landscape mode. Rotation & orientation params that I tried didn't help at all.
class SurfaceHolderCallback implements SurfaceHolder.Callback {
private static final int IMAGE_WIDTH = 512;
private static final int IMAGE_HEIGHT = 384;
private static final String ORIENTATION = "orientation";
private static final String ROTATION = "rotation";
private static final String PORTRAIT = "portrait";
private static final String LANDSCAPE = "landscape";
public void surfaceCreated(SurfaceHolder holder) {
try {
// This case can actually happen if the user opens and closes the camera too frequently.
// The problem is that we cannot really prevent this from happening as the user can easily
// get into a chain of activites and tries to escape using the back button.
// The most sensible solution would be to quit the entire EPostcard flow once the picture is sent.
camera = Camera.open();
} catch(Exception e) {
finish();
return;
}
//Surface.setOrientation(Display.DEFAULT_DISPLAY,Surface.ROTATION_90);
Parameters p = camera.getParameters();
p.setPictureSize(IMAGE_WIDTH, IMAGE_HEIGHT);
camera.getParameters().setRotation(90);
Camera.Size s = p.getSupportedPreviewSizes().get(0);
p.setPreviewSize( s.width, s.height );
p.setPictureFormat(PixelFormat.JPEG);
p.set("flash-mode", "auto");
camera.setParameters(p);
try {
camera.setPreviewDisplay(surfaceHolder);
} catch (Throwable ignored) {
Log.e(APP, "set preview error.", ignored);
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
if (isPreviewRunning) {
camera.stopPreview();
}
try {
camera.startPreview();
} catch(Exception e) {
Log.d(APP, "Cannot start preview", e);
}
isPreviewRunning = true;
}
public void surfaceDestroyed(SurfaceHolder arg0) {
if(isPreviewRunning && camera != null) {
if(camera!=null) {
camera.stopPreview();
camera.release();
camera = null;
}
isPreviewRunning = false;
}
}
}
Do you have this set in AndroidManifest.xml ?
uses-permission android:name="android.permission.CAMERA"
Instead of using :
<uses-permission
android:name="android.permission.FLASHLIGHT"/>
Try to use:
<uses-permission
android:name="android.permission.FLASHLIGHT"
android:permissionGroup="android.permission-group.HARDWARE_CONTROLS"
android:protectionLevel="normal" />
and don't forget to add the permission for camera:
<uses-permission android:name="android.permission.CAMERA" />
Another possibility if you're using an Android Emulator may be that the front and back cameras are defined as "none" in the Android Virtual Device settings.
I think your problem is that when you rotate the camera it is not released correctly or at all. If you switch from landscape to portrait the Intent is launched again. If then the camera is not released and reopend you try to open an already open camera, which throws an error.
this might work...
#Override public void surfaceDestroyed(SurfaceHolder holder) {
Log.d("surfaceDestroyed", "");
cameraSource.stop(); //check if you have this line
}
I see you have set your preview area set as 800 x 480. In portrait mode, this size is invalid and there might be a bug in the API which makes it crash.
Try setting a preview area of 200x200