I am developing an Android application that converts morse code to sounds and flashes. The flashes part works well, but I'm having troubles with sound part.
here is the code I have so far:
SoundPool sp =new SoundPool.Builder().setMaxStreams(1).build(); // declare before onCreate()
int soundId = sp.load(this,R.raw.beep,1); // declared inside onCreate()
public void flashCode(View view){
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},0);
}
}
int dotTime=150; // in milliseconds
long ms=System.currentTimeMillis();
long ms2=System.currentTimeMillis();
//
//int streamID=mSoundPool.load(this,R.raw.beep,1);
for (int i=0;i<code.length();i++)
{
streamID=sp.play(soundId,1,1,1,1,1.0f);
sp.pause(streamID);
if (String.valueOf(code.charAt(i)).contentEquals("."))
{
String cameraId = null; // Usually front camera is at 0 position.
try {
cameraId = camManager.getCameraIdList()[0];
ms=System.currentTimeMillis();
ms2=System.currentTimeMillis()+dotTime;
camManager.setTorchMode(cameraId, true);
//mSoundPool.resume(streamID);
while (ms<ms2){
ms=System.currentTimeMillis();
}
camManager.setTorchMode(cameraId, false);
//mSoundPool.stop(streamID);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
if (String.valueOf(code.charAt(i)).contentEquals("-"))
{
String cameraId = null; // Usually front camera is at 0 position.
try {
cameraId = camManager.getCameraIdList()[0];
ms=System.currentTimeMillis();
ms2=System.currentTimeMillis()+dotTime*3;
camManager.setTorchMode(cameraId, true);
//mSoundPool.resume(streamID);
while (ms<ms2){
ms=System.currentTimeMillis();
}
camManager.setTorchMode(cameraId, false);
//mSoundPool.stop(streamID);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
if (String.valueOf(code.charAt(i)).contentEquals(" "))
{
String cameraId = null; // Usually front camera is at 0 position.
try {
cameraId = camManager.getCameraIdList()[0];
ms=System.currentTimeMillis();
ms2=System.currentTimeMillis()+dotTime;
camManager.setTorchMode(cameraId, false);
while (ms<ms2){
ms=System.currentTimeMillis();
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
}
}
What I want is the play a sound when I turn flash on and off, but only during that time. I tried with SoundPool but when I tested it out, the flash and sounds weren't synced and MediaPlayer it even skipped some sounds.
Could you tell me what I'm doing wrong or tell me how would you do it.
Related
I tried to make flashlight blink on pressing a button continuously until the button is pressed again. The flash is blinking continuously but I am unable to stop the blinking as the app freezes. Here is my Code:
public void Buts1(View view) {
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
long blinkDelay = 50;//delay in ms
if(textView.getText().toString().equals("ON")){
boolean s=false;
while (textView.getText().toString().equals("ON")){
if(s){
try {
String cameraId = cameraManager.getCameraIdList()[0];
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
cameraManager.setTorchMode(cameraId, true);
}
} catch (CameraAccessException e) {
}
s=false;
}else{
try {
String cameraId = cameraManager.getCameraIdList()[0];
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
cameraManager.setTorchMode(cameraId, false);
}
} catch (CameraAccessException e) {
}
s=true;
}
try {
Thread.sleep(blinkDelay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
I believe you're freezing the UI thread here. Also I don't see anything that sets the textView text to "OFF".
I've slightly modified your code, which assumes textView starts with the text "OFF" and will change to "ON" when you click the button. Clicking the button again will set the textView text to "OFF" and turn the flashing off. This works by being on a separate thread instead of the UI thread.
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
Thread flashThread = new Thread(new Runnable() {
#Override
public void run() {
boolean s=false;
long blinkDelay = 50;//delay in ms
while (textView.getText().toString().equals("ON")){
if(s){
try {
String cameraId = cameraManager.getCameraIdList()[0];
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
cameraManager.setTorchMode(cameraId, true);
}
} catch (CameraAccessException e) {
}
s=false;
}else{
try {
String cameraId = cameraManager.getCameraIdList()[0];
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
cameraManager.setTorchMode(cameraId, false);
}
} catch (CameraAccessException e) {
}
s=true;
}
try {
Thread.sleep(blinkDelay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
if(textView.getText().toString().equalsIgnoreCase("OFF")){
textView.setText("ON");
flashThread.start();
}else{
flashThread.interrupt();
try {
String cameraId = cameraManager.getCameraIdList()[0];
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
cameraManager.setTorchMode(cameraId, false);
}
} catch (CameraAccessException e) {
}
textView.setText("OFF");
}
}
});
I'm developing an application where if the screen of the phone is facing up the flashlight starts blinking. If the screen of the phone is facing downwards the flashlight is suppose to stop blinking. For detecting whether if the screen of the phone is facing up or down I'm using the accelerometer. The code to detect the orientation of the screen is here:
#Override
protected void onResume() {
super.onResume();
smAccelerometer.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onPause() {
super.onPause();
smAccelerometer.unregisterListener(this);
}
#Override
public void onSensorChanged(SensorEvent event) {
int type = event.sensor.getType();
if (type == Sensor.TYPE_ACCELEROMETER) {
float gz = event.values[2];
if (mGZ == 0) {
mGZ = gz;
} else {
if ((mGZ * gz) < 0) {
mEventCountSinceGZChanged++;
if (mEventCountSinceGZChanged == MAX_COUNT_GZ_CHANGE) {
mGZ = gz;
mEventCountSinceGZChanged = 0;
if (gz > 0) {
Log.d(TAG, "now screen is facing up.");
Toast toast = Toast.makeText(MainActivity.this, "Up", Toast.LENGTH_SHORT);
toast.show();
flashlightFrequency();
} else if (gz < 0) {
Log.d(TAG, "now screen is facing down.");
Toast toast = Toast.makeText(MainActivity.this, "Down", Toast.LENGTH_SHORT);
toast.show();
}
}
} else {
if (mEventCountSinceGZChanged > 0) {
mGZ = gz;
mEventCountSinceGZChanged = 0;
}
}
}
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
As you can see from this code, whenever the screen is facing up i call the method flashlightFrequency() which turns the flashlight on and off in intervals:
public void flashlightFrequency() {
String myString = "0101010101";
int frequency = 2000; //Delay in ms
CameraManager camManager;
String cameraId = null; // Usually front camera is at 0 position.
camManager = (CameraManager) getApplicationContext().getSystemService(Context.CAMERA_SERVICE);
try {
cameraId = camManager.getCameraIdList()[0];
} catch (CameraAccessException e) {
e.printStackTrace();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
for (int i = 0; i <= myString.length(); i++) {
if (i == myString.length()) {
flashlightFrequency();
}
if (myString.charAt(i) == '0') {
try {
camManager.setTorchMode(cameraId, true);
} catch (CameraAccessException e) {
e.printStackTrace();
}
} else {
try {
camManager.setTorchMode(cameraId, false);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(frequency);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
The accelerometer works fine and I'm able to detect the orientation of the screen UNTIL I call the method flashlightFrequency(). When the flashlight starts the phone no longer registers motions. It seems like the flashlight cancels the SensorListener. Whenever the flashlight is turned on I can't use the accelerometer to detect the orientation of the screen.
The solution was to implement the flashlightFrequency() in an IntentService class. By doing that the flashlight will run in the background and therefore not interfere with the accelerometer.
I'm trying to record video by using GLSurfaceview in android. But every time when i tap to record, it gives me null pointer exception onPause.
here is my code to record video
mCamera = new CameraLoader();
buttonn_capture.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try{
if (recording) {
mediaRecorder.stop(); // stop the recording
recording = false;
} else {
// Release Camera before MediaRecorder start
mCamera.releaseCamera();
if (!prepareMediaRecorder()) {
finish();
}
try {
mediaRecorder.prepare();
} catch (IllegalStateException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mediaRecorder.start();
recording = true;
// myButton.setText("Cancel");
}
}catch(Exception ex){
Toast.makeText(getApplicationContext(), "Please tap and hold to record!",
Toast.LENGTH_LONG).show();
reload();
}
}
});
private boolean prepareMediaRecorder() {
mCamera.mCameraInstance.unlock();
mediaRecorder.setCamera(mCamera.mCameraInstance);
// Step 2: Set sources
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES),
"MusicDubs");
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
mediaStorageDir.mkdirs();
}
timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault())
.format(new Date());
CameraInfo caminfo = new CameraInfo();
mCamera.mCameraInstance.getCameraInfo(0, caminfo);
if (caminfo.facing == CameraInfo.CAMERA_FACING_FRONT) {
mediaRecorder.setProfile(CamcorderProfile.get(0,
CamcorderProfile.QUALITY_HIGH));
mediaRecorder
.setOrientationHint(270);
} else if (caminfo.facing == CameraInfo.CAMERA_FACING_BACK) {
mediaRecorder.setProfile(CamcorderProfile.get(0,
CamcorderProfile.QUALITY_HIGH));
mediaRecorder
.setOrientationHint(270);
mediaRecorder.setOrientationHint(90);
}
//mediaRecorder.setCaptureRate(20);
mediaRecorder.setVideoFrameRate(120);
mediaRecorder.setOutputFile(mediaStorageDir.getPath() + "/"
+ "_" + timeStamp + ".mp4");
// Step 5: Set the preview output
mediaRecorder.setPreviewDisplay(glSurfaceView.getHolder()
.getSurface());
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
// releaseMediaPlayer();
return false;
} catch (IOException e) {
releaseMediaRecorder();
// releaseMediaPlayer();
return false;
}
return true;
}
private void releaseMediaRecorder() {
if (mediaRecorder != null) {
mediaRecorder.reset(); // clear recorder configuration
mediaRecorder.release(); // release the recorder object
mediaRecorder = null;
mCamera.mCameraInstance.lock(); // lock camera for later use
}
}
on Activity pause and resume i added that code
#Override
protected void onResume() {
super.onResume();
mCamera.onResume();
}
#Override
protected void onPause() {
mCamera.onPause();
super.onPause();
}
here is my camera class to load camera
private class CameraLoader {
private int mCurrentCameraId = 0;
private Camera mCameraInstance;
public void onResume() {
setUpCamera(mCurrentCameraId);
}
public void onPause() {
releaseCamera();
}
public void switchCamera() {
releaseCamera();
mCurrentCameraId = (mCurrentCameraId + 1) % mCameraHelper.getNumberOfCameras();
setUpCamera(mCurrentCameraId);
}
private void setUpCamera(final int id) {
mCameraInstance = getCameraInstance(id);
Parameters parameters = mCameraInstance.getParameters();
// TODO adjust by getting supportedPreviewSizes and then choosing
// the best one for screen size (best fill screen)
if (parameters.getSupportedFocusModes().contains(
Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
}
mCameraInstance.setParameters(parameters);
int orientation = mCameraHelper.getCameraDisplayOrientation(
ActivityCamera.this, mCurrentCameraId);
CameraInfo2 cameraInfo = new CameraInfo2();
mCameraHelper.getCameraInfo(mCurrentCameraId, cameraInfo);
boolean flipHorizontal = cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT;
mGPUImage.setUpCamera(mCameraInstance, orientation, flipHorizontal, false);
}
/** A safe way to get an instance of the Camera object. */
private Camera getCameraInstance(final int id) {
Camera c = null;
try {
c = mCameraHelper.openCamera(id);
} catch (Exception e) {
e.printStackTrace();
}
return c;
}
private void releaseCamera() {
mCameraInstance.setPreviewCallback(null);
mCameraInstance.release();
mCameraInstance = null;
}
}
Its behavior is very strange, I didn't get why it is giving me null pointer exception onPause because there is no point of getting camera null there. please tell me where i'm doing wrong. Any help would be much appreciated. Thank you :)
I have been working in one of my android project in which I need to integrate Zbar scanner. I have integrated Zbar scanner in project. The problem I am facing is sometimes in Samsung Tab 3 has scanner area shows black screen. It is working perfectly in other devices. I have checked in nexus,canvas like devices and it shows perfect scanning screen. Is there any problem in my code? Here is my code.
private void initControls() {
try {
{
System.loadLibrary("iconv");
}
surfaceViewFlash = (SurfaceView) mView.findViewById(R.id.PREVIEW);
surfaceViewFlash.setVisibility(View.INVISIBLE);
surfaceViewFlash.setVisibility(View.VISIBLE);
mCameraScanner = getCameraInstance();
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
previewingScanner = true;
autoFocusHandlerScanner = new Handler();
try {
// Instance barcode zBarScanner
zBarScanner = new ImageScanner();
zBarScanner.setConfig(0, Config.X_DENSITY, 3);
zBarScanner.setConfig(0, Config.Y_DENSITY, 3);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
mPreviewScanner = new CameraPreview(getActivity(), mCameraScanner, previewCb, autoFocusCB);
FrameLayout preview = (FrameLayout) mView.findViewById(R.id.cameraPreview);
preview.addView(mPreviewScanner);
if (barcodeScanned) {
barcodeScanned = false;
mCameraScanner.setPreviewCallback(previewCb);
mCameraScanner.startPreview();
previewingScanner = true;
Log.e("initControls", "initControls");
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* A safe way to get an instance of the Camera object.
*/
public Camera getCameraInstance() {
Camera c = null;
int frontId = 0, backId = 0;
try {
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++) {
Camera.getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
frontId = i;
} else if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
backId = i;
}
}
c = Camera.open(backId);
} catch (Exception e) {
e.printStackTrace();
GeneralAlertDialog.createDialog(getActivity(), getString(R.string.app_name), "Camera is not working, Please try again.", new DialogDismiss() {
#Override
public void onDismiss() {
getCallBackForCloseScanner().OnCloseButtonClickOfScanner();
}
});
}
return c;
}
private void releaseCamera() {
if (mCameraScanner != null) {
mCameraScanner.cancelAutoFocus();
previewingScanner = false;
mCameraScanner.setPreviewCallback(null);
mPreviewScanner.getHolder().removeCallback(mPreviewScanner);
mCameraScanner.stopPreview();
mCameraScanner.release();
mCameraScanner = null;
mPreviewScanner = null;
}
}
Runnable doAutoFocus = new Runnable() {
public void run() {
try {
if (previewingScanner) {
if (mCameraScanner == null)
mCameraScanner = getCameraInstance();
Camera.Parameters parameters = null;
Log.e("mCameraScanner", mCameraScanner + "");
if (null != mCameraScanner.getParameters()) {
parameters = mCameraScanner.getParameters();
}
List<String> focusModes = parameters.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
mCameraScanner.setParameters(parameters);
mCameraScanner.autoFocus(autoFocusCB);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
Please help me out to solve the problem.
releaseCamera on pause and on destroyed. it happen when camera is not release by any resource and you are again starting it.hope this will help you.
It's late, but this finally helped me, after overlooking the obvious.
Make sure you have camera permission for your app. It must be enabled not only through the camera permission declaration in the manifest file, BUT you also have to make sure you grant your app access to your camera by Android OS. Go to Preferences -> Apps -> Your App -> Permissions -> Allow camera access.
Starting from Android 6.0 (API 23), users are not asked for permissions at the time of installation rather developers need to request the permissions at the run time. Only the permissions that are defined in the manifest file can be requested at run time.
Request camera permission like here!.
I'm trying to develop a video recorder with the front and back camera. The app can switch between the back (default) and front camera. When the app is activated the front camera, and I press the recording button, the app goes to on error method, and I release and init the camera and the recording, but the error persists another time. Any idea?
UPDATE: I update the onError method, with the code below, and I think I don't make the release and the init camera well, because when the app executes this method the surface holder is black and doesn't give me what the camera sees
Here, my code:
onError method:
public void onError(MediaRecorder mr, int what, int extra) {
stopRecording();
//if Error 100, app must release the Camera object and instantiate a new one.
if (what == 100) {
if (error_100 == 2) { //Error 100 persists, change camera
if (Camera.getNumberOfCameras() <= 1) {
//No mas camaras para app
} else {
if (selected_camera == FRONT_CAMERA) {
selected_camera=BACK_CAMERA;
} else {
selected_camera=FRONT_CAMERA;
}
selected_camera_button.setEnabled(false);
Toast.makeText(this, "Initializing other camera", Toast.LENGTH_SHORT).show();
}
} else { //No camera init finish activity
if (error_100 == 3) {
Toast.makeText(this, "Initialize cameras failed", Toast.LENGTH_SHORT).show();
finish();
} else {
Toast.makeText(this, "Recording error has occurred. Stopping the recording", Toast.LENGTH_SHORT).show();
}
}
error_100++;
initCamera();
initCameraRecorder();
}
}
And the other method:
/** Initializes the back/front camera */
private boolean initCamera() {
try {
camera = getCameraInstance(selected_camera);
Camera.Parameters camParams = camera.getParameters();
camParams.set( "cam_mode", 1 );
camParams.set("orientation", "portrait");
checkCameraFlash(camParams);
//Establish the rotation angle camera
setAngleCameraRotation();
camera.setDisplayOrientation(angle_rotation_camera);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
Establish 4:3 ratio and 480x640 if is posible
setAspectResolutionCamera(camParams);
camera.setParameters(camParams);
//Camera eye
video_view.getHolder().setFixedSize(height_video, width_video);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(height_video, width_video);
video_view.setLayoutParams(lp);
camera.lock();
surface_holder = video_view.getHolder();
surface_holder.addCallback(this);
surface_holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
setPreviewCamera();
} catch(Exception e) {
Log.v("RecordVideo", "Could not initialize the Camera");
return false;
}
return true;
}
/** Initializes the camera recorder before starts the recording */
private void initCameraRecorder() {
if(media_recorder != null) return;
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
output_file_name = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + File.separator + timeStamp + ".mp4";
File outFile = new File(output_file_name);
if(outFile.exists()) {
outFile.delete();
}
try {
camera.stopPreview();
camera.unlock();
media_recorder = new MediaRecorder();
media_recorder.setCamera(camera);
media_recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
media_recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
profile.videoBitRate = 885000; //Medium quality
profile.videoFrameHeight = height_video;
profile.videoFrameWidth = width_video;
media_recorder.setProfile(profile);
media_recorder.setMaxDuration(21000); // limit to 21 seconds
media_recorder.setOrientationHint(setOrientationCameraRecorder());
media_recorder.setPreviewDisplay(surface_holder.getSurface());
media_recorder.setOutputFile(output_file_name);
media_recorder.prepare();
Log.v("RecordVideo", "MediaRecorder initialized");
} catch(Exception e) {
Log.v("RecordVideo", "MediaRecorder failed to initialize");
e.printStackTrace();
}
}
/** Starts the recording video */
private void beginRecording() {
media_recorder.setOnInfoListener(this);
media_recorder.setOnErrorListener(this);
media_recorder.start();
record_button.setTextColor(getResources().getColor(android.R.color.holo_red_dark));
}
/** Stops the recording video */
private void stopRecording() {
if (media_recorder != null) {
media_recorder.setOnErrorListener(null);
media_recorder.setOnInfoListener(null);
try {
media_recorder.stop();
} catch(IllegalStateException e) {
// This can happen if the recorder has already stopped.
Log.e("INFO:", "Got IllegalStateException in stopRecording");
}
releaseRecorder();
record_button.setTextColor(getResources().getColor(android.R.color.black));
releaseCamera();
}
video_task.cancel(true);
output_file_name.isEmpty();
}