Using front and rear camera on the same activity android - java

I know this question has been asked many times but i have no other option than asking this question again. I am using camera2 api to display both front and rear cameras on the same screen. I have created two texture views each with two camera instances. Even then I'm getting an exception.
This is my code for the MainActivity.java:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "AndroidCameraApi";
private TextureView textureView,textureView1;
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
static {
ORIENTATIONS.append(Surface.ROTATION_0, 90);
ORIENTATIONS.append(Surface.ROTATION_90, 0);
ORIENTATIONS.append(Surface.ROTATION_180, 270);
ORIENTATIONS.append(Surface.ROTATION_270, 180);
}
private String cameraId,cameraId1;
protected CameraDevice cameraDevice,cameraDevice1;
protected CameraCaptureSession cameraCaptureSessions,cameraCaptureSessions1;
protected CaptureRequest.Builder captureRequestBuilder,captureRequestBuilder1;
private Size imageDimension,imageDimension1;
private static final int REQUEST_CAMERA_PERMISSION = 200;
private Handler mBackgroundHandler,mBackgroundHandler1;
private HandlerThread mBackgroundThread,mBackgroundThread1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_android_camera_api);
textureView = (TextureView) findViewById(R.id.texture);
textureView1 = (TextureView) findViewById(texture1);
assert textureView != null;
assert textureView1 != null;
textureView.setSurfaceTextureListener(textureListener);
textureView1.setSurfaceTextureListener(textureListener1);
}
TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
//open your camera here
openCamera();
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
// Transform you image captured size according to the surface width and height
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
};
TextureView.SurfaceTextureListener textureListener1 = new TextureView.SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
//open your camera here
openBackCamera();
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
// Transform you image captured size according to the surface width and height
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
};
private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(CameraDevice camera) {
//This is called when the camera is open
Log.e(TAG, "onOpened");
cameraDevice = camera;
createCameraPreview();
}
#Override
public void onDisconnected(CameraDevice camera) {
cameraDevice.close();
}
#Override
public void onError(CameraDevice camera, int error) {
cameraDevice.close();
cameraDevice = null;
}
};
private final CameraDevice.StateCallback stateCallback1 = new CameraDevice.StateCallback() {
#Override
public void onOpened(CameraDevice camera) {
//This is called when the camera is open
Log.e(TAG, "onOpened");
cameraDevice1 = camera;
createCameraPreview1();
}
#Override
public void onDisconnected(CameraDevice camera) {
cameraDevice1.close();
}
#Override
public void onError(CameraDevice camera, int error) {
cameraDevice1.close();
cameraDevice1 = null;
}
};
protected void startBackgroundThread() {
mBackgroundThread = new HandlerThread("Camera Background");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
}
protected void stopBackgroundThread() {
mBackgroundThread.quitSafely();
try {
mBackgroundThread.join();
mBackgroundThread = null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
protected void startBackgroundThread1() {
mBackgroundThread1 = new HandlerThread("Camera Background");
mBackgroundThread1.start();
mBackgroundHandler1 = new Handler(mBackgroundThread1.getLooper());
}
protected void stopBackgroundThread1() {
mBackgroundThread1.quitSafely();
try {
mBackgroundThread1.join();
mBackgroundThread1 = null;
mBackgroundHandler1 = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
protected void createCameraPreview() {
try {
SurfaceTexture texture = textureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight());
Surface surface = new Surface(texture);
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(surface);
cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback(){
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
//The camera is already closed
if (null == cameraDevice) {
return;
}
// When the session is ready, we start displaying the preview.
cameraCaptureSessions = cameraCaptureSession;
updatePreview();
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
Toast.makeText(MainActivity.this, "Configuration change", Toast.LENGTH_SHORT).show();
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
protected void createCameraPreview1() {
try {
SurfaceTexture texture1 = textureView1.getSurfaceTexture();
assert texture1 != null;
texture1.setDefaultBufferSize(imageDimension1.getWidth(), imageDimension1.getHeight());
Surface surface = new Surface(texture1);
captureRequestBuilder1 = cameraDevice1.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder1.addTarget(surface);
cameraDevice1.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback(){
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
//The camera is already closed
if (null == cameraDevice1) {
return;
}
// When the session is ready, we start displaying the preview.
cameraCaptureSessions1 = cameraCaptureSession;
updatePreview1();
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
Toast.makeText(MainActivity.this, "Configuration change", Toast.LENGTH_SHORT).show();
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void openCamera() {
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
Log.e(TAG, "is camera open");
try {
cameraId = manager.getCameraIdList()[0];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
assert map != null;
imageDimension = map.getOutputSizes(SurfaceTexture.class)[0];
// Add permission for camera and let user grant the permission
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CAMERA_PERMISSION);
return;
}
manager.openCamera(cameraId, stateCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
Log.e(TAG, "openCamera X");
}
private void openBackCamera() {
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
Log.e(TAG, "is camera open");
try {
cameraId1 = manager.getCameraIdList()[1];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId1);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
assert map != null;
imageDimension1 = map.getOutputSizes(SurfaceTexture.class)[0];
// Add permission for camera and let user grant the permission
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CAMERA_PERMISSION);
return;
}
manager.openCamera(cameraId1, stateCallback1, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
Log.e(TAG, "openCamera X");
}
protected void updatePreview() {
if(null == cameraDevice) {
Log.e(TAG, "updatePreview error, return");
}
captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
try {
cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
protected void updatePreview1() {
if(null == cameraDevice1) {
Log.e(TAG, "updatePreview error, return");
}
captureRequestBuilder1.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
try {
cameraCaptureSessions1.setRepeatingRequest(captureRequestBuilder1.build(), null, mBackgroundHandler1);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == REQUEST_CAMERA_PERMISSION) {
if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
// close the app
Toast.makeText(MainActivity.this, "Sorry!!!, you can't use this app without granting permission", Toast.LENGTH_LONG).show();
finish();
}
}
}
#Override
protected void onResume() {
super.onResume();
Log.e(TAG, "onResume");
startBackgroundThread();
startBackgroundThread1();
if (textureView.isAvailable()) {
openCamera();
} else {
textureView.setSurfaceTextureListener(textureListener);
}
if (textureView1.isAvailable()) {
openBackCamera();
} else {
textureView1.setSurfaceTextureListener(textureListener1);
}
}
#Override
protected void onPause() {
Log.e(TAG, "onPause");
//closeCamera();
stopBackgroundThread();
stopBackgroundThread1();
super.onPause();
}
}
Code for layout file:
<LinearLayout 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:orientation="vertical"
>
<TextureView
android:id="#+id/texture"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginBottom="10dp"/>
<TextureView
android:id="#+id/texture1"
android:layout_width="match_parent"
android:layout_height="200dp"
/>
</LinearLayout>
Exception i am getting is as below:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.camera2.CameraDevice.close()' on a null object reference
I am getting exception on this line:
cameraDevice1.close();

Which of the cameraDevice1.close() calls fails? Did you ever get an onOpened call for that camera?
There's no guarantee that a given Android device can have multiple cameras open at once; the only way to know is to try, and if it can't be done, the second camera will not fire onOpened, it'll fire onError with error code TOO_MANY_CAMERAS_IN_USE.
So if that's happening here, then you'll get onError without onOpened, and your cameraDevice1 will never have been set.

Related

can't display video in VideoView until I restart the app on android 12

i am making an app that records a video and then displays this video on another activity.
the problem is that this video cannot be played right away, i would have to record the video, and then restart the android app for it to show. otherwise it shows me a message that
says: "can't play this video".
Moreover the thing that i really dont understand is that i tried it on an older phone of android version 11 and it works perfectly, but for some reason on the new phone it doesn't
i have made some research and i think it has something to do with the storage permissions but i am not sure since i tried fixing it with no luck.
what can i do to fix this?
public class MainActivity extends AppCompatActivity {
CameraManager CamMan;
boolean flag = false;
public static boolean FirstDirectoryCreated;
CameraSource cameraSource;
Button seeVideos;
public static File LeakedVids;
public static boolean isDirectoryCreated;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.CAMERA}, 1);
}
seeVideos = findViewById(R.id.seeVideos);
init();
createFiles();
CamMan = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
seeVideos.setOnClickListener(v -> goToVideos());
}
private void goToVideos() {
Intent intent = new Intent(this, ShowVideo.class);
startActivity(intent);
}
#Override
public void onBackPressed(){
Intent a = new Intent(Intent.ACTION_MAIN);
a.addCategory(Intent.CATEGORY_HOME);
a.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(a);
}
private void createFiles () {
File EyeTracker = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES), "Eye Tracker");
FirstDirectoryCreated = EyeTracker.exists() || EyeTracker.mkdirs();
if (FirstDirectoryCreated) {
LeakedVids = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) + File.separator
+ "Eye Tracker", "Leaked Videos");
isDirectoryCreated = LeakedVids.exists() || LeakedVids.mkdirs();
}
}
private void init () {
flag = true;
initCameraSource();
}
//method to create camera source from faceFactoryDaemon class
private void initCameraSource () {
FaceDetector detector = new FaceDetector.Builder(this)
.setTrackingEnabled(true)
.setClassificationType(FaceDetector.ALL_CLASSIFICATIONS)
.setMode(FaceDetector.ACCURATE_MODE)
.build();
detector.setProcessor(new MultiProcessor.Builder(new FaceTrackerDaemon(MainActivity.this)).build());
cameraSource = new CameraSource.Builder(this, detector)
.setRequestedPreviewSize(1024, 768)
.setFacing(CameraSource.CAMERA_FACING_BACK)
.setRequestedFps(30.0f)
.build();
try {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.CAMERA}, 1);
return;
}
cameraSource.start();
} catch (IOException e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
#Override
protected void onResume () {
super.onResume();
if (cameraSource != null) {
try {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.CAMERA}, 1);
return;
}
cameraSource.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
protected void onPause () {
super.onPause();
if (cameraSource != null) {
cameraSource.stop();
}
}
#Override
protected void onDestroy () {
super.onDestroy();
if (cameraSource != null) {
cameraSource.release();
}
}
//update view
#SuppressLint("SetTextI18n")
public void updateMainView (Condition condition){
switch (condition) {
case USER_EYES_OPEN:
openCam();
break;
case FACE_NOT_FOUND:
break;
}
}
public void openCam () {
Intent intent = new Intent(this, VideoPreview.class);
startActivity(intent);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
}
VideoPreview
public class VideoPreview extends AppCompatActivity {
private VideoCapture<Recorder> videoCapture = null;
private Recording recording = null;
private ExecutorService cameraExecutor;
private ActivityVideoPreviewBinding viewBinding;
Timer timer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_preview);
viewBinding = ActivityVideoPreviewBinding.inflate(getLayoutInflater());
setContentView(viewBinding.getRoot());
startCamera();
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
captureVideo();
}
}, 173);
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
stopRec();
}
}, 6000);
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
backToMain();
}
}, 6100);
cameraExecutor = Executors.newSingleThreadExecutor();
}
private void stopRec() {
Recording curRecording = recording;
if (curRecording != null) {
// Stop the current recording session.
curRecording.stop();
recording = null;
}
}
#Override
public void onBackPressed() {
Toast.makeText(this, "Ntek Ntor Ya Zabre", Toast.LENGTH_SHORT).show();
}
private void captureVideo() {
/* MediaStoreOutputOptions mediaStoreOutputOptions = (new androidx.camera.video.MediaStoreOutputOptions
.Builder(this.getContentResolver(), android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI))
.build(); */
String name = "LeakedVideo_" + System.currentTimeMillis() + ".mp4";
File vids = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) + File.separator
+ "Eye Tracker" + File.separator + "Leaked Videos", name);
FileOutputOptions fileOutputOptions = new FileOutputOptions.Builder(vids).build();
if (videoCapture != null) {
PendingRecording recording = (videoCapture.getOutput())
.prepareRecording(this, fileOutputOptions);
this.recording = recording.start((ContextCompat.getMainExecutor(this)), videoRecordEvent -> {
});
}
}
private void startCamera() {
ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this);
cameraProviderFuture.addListener((() -> {
ProcessCameraProvider var10000 = null;
try {
var10000 = cameraProviderFuture.get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
assert var10000 != null;
Intrinsics.checkNotNullExpressionValue(var10000, "cameraProviderFuture.get()");
ProcessCameraProvider cameraProvider = var10000;
Preview preview = new Preview.Builder()
.build();
preview.setSurfaceProvider(viewBinding.viewFinder.getSurfaceProvider());
Recorder recorder = (new Recorder.Builder())
.setQualitySelector(QualitySelector.from(Quality.HIGHEST))
.build();
videoCapture = VideoCapture.withOutput(recorder);
CameraSelector cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA;
try {
cameraProvider.unbindAll();
cameraProvider
.bindToLifecycle(this, cameraSelector, preview, videoCapture);
} catch (Exception exc) {
Log.e("CameraXApp", "Use case binding failed", exc);
}
}), ContextCompat.getMainExecutor(this));
}
protected void onDestroy() {
super.onDestroy();
cameraExecutor.shutdown();
}
public void backToMain() {
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
}
}
ShowVideo:
public class ShowVideo extends AppCompatActivity {
private static final String TAG = "MainActivity";
private CardStackLayoutManager manager;
public static File[] files;
public static List<Video> videos;
public static int num;
File newFile;
String dir;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.show_video);
if (ActivityCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{READ_EXTERNAL_STORAGE}, 1);
}
dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).getPath();
files = MainActivity.LeakedVids.listFiles();
num = 1;
videos = new ArrayList<>();
CardStackView cardStackView = findViewById(R.id.card_stack_view);
if (files.length > 0) {
videos.add(new Video(files[files.length - 1].getPath()));
Adapter adapter = new Adapter(videos);
cardStackView.setAdapter(adapter);
} else {
Toast.makeText(this, "No Videos to show", Toast.LENGTH_SHORT).show();
}
manager = new CardStackLayoutManager(this, new CardStackListener() {
#Override
public void onCardDragging(Direction direction, float ratio) {
}
#Override
public void onCardSwiped(Direction direction) {
Log.d(TAG, "onCardSwiped: p=" + manager.getTopPosition() + " d=" + direction);
if (direction == Direction.Right) {
if (files.length == 1) {
newFile = new File(dir, files[files.length - 1].getName());
FileChannel outputChannel = null;
FileChannel inputChannel = null;
try {
outputChannel = new FileOutputStream(newFile).getChannel();
inputChannel = new FileInputStream(files[files.length - 1]).getChannel();
inputChannel.transferTo(0, inputChannel.size(), outputChannel);
inputChannel.close();
files[files.length - 1].delete();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputChannel != null) {
try {
inputChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputChannel != null) {
try {
outputChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} else {
newFile = new File(dir, files[files.length - num].getName());
FileChannel outputChannel = null;
FileChannel inputChannel = null;
try {
outputChannel = new FileOutputStream(newFile).getChannel();
inputChannel = new FileInputStream(files[files.length - num]).getChannel();
inputChannel.transferTo(0, inputChannel.size(), outputChannel);
inputChannel.close();
files[files.length - num].delete();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputChannel != null) {
try {
inputChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputChannel != null) {
try {
outputChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
if (direction == Direction.Left) {
if (files.length == 1) {
files[files.length - 1].delete();
} else {
files[files.length - num].delete();
}
}
if (files != null) {
if (files.length > num) {
num++;
videos.add(new Video(files[files.length - num].getPath()));
}
}
Adapter adapter = new Adapter(videos);
cardStackView.setAdapter(adapter);
}
#Override
public void onCardRewound() {
Log.d(TAG, "onCardRewound: " + manager.getTopPosition());
}
#Override
public void onCardCanceled() {
Log.d(TAG, "onCardRewound: " + manager.getTopPosition());
}
#Override
public void onCardAppeared(View view, int position) {
}
#Override
public void onCardDisappeared(View view, int position) {
}
});
manager.setStackFrom(StackFrom.None);
manager.setVisibleCount(3);
manager.setTranslationInterval(8.0f);
manager.setScaleInterval(0.95f);
manager.setSwipeThreshold(0.3f);
manager.setMaxDegree(20.0f);
manager.setDirections(Direction.FREEDOM);
manager.setCanScrollHorizontal(true);
manager.setCanScrollVertical(false);
manager.setSwipeableMethod(SwipeableMethod.Manual);
manager.setOverlayInterpolator(new LinearInterpolator());
cardStackView.setLayoutManager(manager);
cardStackView.setItemAnimator(new DefaultItemAnimator());
}
#Override
public void onBackPressed(){
Intent a = new Intent(this, MainActivity.class);
startActivity(a);
}
}
Adapter:
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
private List<Video> videos;
public Adapter(List<Video> videos) {
this.videos = videos;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int position) {
//LayoutInflater inflater = LayoutInflater.from(parent.getContext());
//View view = inflater.inflate(R.layout.item_card, parent, false);
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_card, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.setData(videos.get(position));
holder.itemView.setOnClickListener(v -> {
Intent intent = new Intent(holder.itemView.getContext(), DetailActivity.class);
intent.putExtra("param", videos.get(position).getPath());
holder.itemView.getContext().startActivity(intent);
});
}
#Override
public int getItemCount() {
return videos.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public static VideoView videoView;
ViewHolder(#NonNull View itemView) {
super(itemView);
videoView = itemView.findViewById(R.id.item_video);
}
void setData(Video video) {
videoView.setVideoPath(video.getPath());
videoView.setOnPreparedListener(MediaPlayer::start);
videoView.setOnCompletionListener(MediaPlayer::start);
}
}
public List<Video> getItems() {
return videos;
}
public void setItems(List<Video> items) {
this.videos = items;
}
}
the problem is that when i open the 'ShowVideo' class the video doesnt play until i restart the app
pls help.

Add current authenticated username to image and/or video filename

I'm trying to figure out how I would get the data in a Firebase database assigned to a particular user but that is proving very tricky for me.
So, for now, I would like to be able to attach the current signed-in/authenticated user's name/ID to any file that I save from my app but I don't know how to go about it.
I tried adding the following lines to my Camera Photo activity but it didn't do anything:
public void onStart() {
super.onStart();
FirebaseUser currentUser = mAuth.getCurrentUser();
updateUI(currentUser);
and then adding to the code where it assigns the file name (as such):
file = new File(Environment.getExternalStorageDirectory() + "/" + UUID.randomUUID().toString()
+ FirebaseAuth.getInstance().getCurrentUser() + ".jpg");
But, as I say, it doesn't do anything and just keeps the file name in the same format without any user ID associated with it.
Below is the full class for taking and saving a photo (without my added attempts):
public class CameraPhotoActivity extends AppCompatActivity {
private Button btnCapture;
private TextureView textureView;
// to check the state orientation of the output image
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
static {
ORIENTATIONS.append(Surface.ROTATION_0, 90);
ORIENTATIONS.append(Surface.ROTATION_90, 0);
ORIENTATIONS.append(Surface.ROTATION_180, 270);
ORIENTATIONS.append(Surface.ROTATION_270, 180);
}
private String cameraId;
private CameraDevice cameraDevice;
private CameraCaptureSession cameraCaptureSessions;
private CaptureRequest.Builder captureRequestBuilder;
private Size imageDimension;
private ImageReader imageReader;
// save to file
private File file;
private static final int REQUEST_CAMERA_PERMISSION = 200;
private boolean mFlashSupported;
private Handler mBackgroundHandler;
private HandlerThread mBackgroundThread;
CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(#NonNull CameraDevice camera) {
cameraDevice = camera;
createCameraPreview();
}
#Override
public void onDisconnected(#NonNull CameraDevice cameraDevice) {
cameraDevice.close();
}
#Override
public void onError(#NonNull CameraDevice cameraDevice, int i) {
cameraDevice.close();
cameraDevice = null;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera_photo);
textureView = (TextureView) findViewById(R.id.textureView);
assert textureView != null;
textureView.setSurfaceTextureListener(textureListener);
btnCapture = (Button) findViewById(R.id.btnCapture);
btnCapture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
takePicture();
}
});
}
private void takePicture() {
if (cameraDevice == null)
return;
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraDevice.getId());
Size[] jpegSizes = null;
if (characteristics != null)
jpegSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
.getOutputSizes(ImageFormat.JPEG);
// capture the image with custom size
int width = 640;
int height = 480;
if (jpegSizes != null && jpegSizes.length > 0) {
width = jpegSizes[0].getWidth();
height = jpegSizes[0].getHeight();
}
final ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
List<Surface> outputSurface = new ArrayList<>(2);
outputSurface.add(reader.getSurface());
outputSurface.add(new Surface(textureView.getSurfaceTexture()));
final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(reader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
// check the orientation on the device
int rotation = getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
file = new File(Environment.getExternalStorageDirectory() + "/" + UUID.randomUUID().toString()
+ ".jpg");
ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
#Override
public void onImageAvailable(ImageReader imageReader) {
Image image = null;
try {
image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
save(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
{
if (image != null)
image.close();
}
}
}
private void save(byte[] bytes) throws IOException {
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(file);
outputStream.write(bytes);
} finally {
if (outputStream != null)
outputStream.close();
}
MediaScannerConnection.scanFile(CameraPhotoActivity.this, new String[]{file.toString()}, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("External Storage", "Scanned" + path + ":");
Log.i("External Storage", "-> uri=" + uri);
}
});
}
};
reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
#Override
public void onCaptureCompleted(#NonNull CameraCaptureSession session, #NonNull CaptureRequest request, #NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
Toast.makeText(CameraPhotoActivity.this, "Saved " + file, Toast.LENGTH_SHORT).show();
createCameraPreview();
}
};
cameraDevice.createCaptureSession(outputSurface, new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
try {
cameraCaptureSession.capture(captureBuilder.build(), captureListener, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
}
}, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void createCameraPreview() {
try {
SurfaceTexture texture = textureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight());
Surface surface = new Surface(texture);
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(surface);
cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
if (cameraDevice == null)
return;
cameraCaptureSessions = cameraCaptureSession;
updatePreview();
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
Toast.makeText(CameraPhotoActivity.this, "Changed", Toast.LENGTH_SHORT).show();
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void updatePreview() {
if (cameraDevice == null)
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
try {
cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void openCamera() {
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
cameraId = manager.getCameraIdList()[0];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
assert map != null;
imageDimension = map.getOutputSizes(SurfaceTexture.class)[0];
// check realtime permission if run higher than API 23
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, REQUEST_CAMERA_PERMISSION);
return;
}
manager.openCamera(cameraId, stateCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
openCamera();
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
};
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == REQUEST_CAMERA_PERMISSION) {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "You can't use the camera without permission", Toast.LENGTH_SHORT).show();
finish();
}
}
}
#Override
protected void onResume() {
super.onResume();
startBackgroundThread();
if (textureView.isAvailable())
openCamera();
else
textureView.setSurfaceTextureListener(textureListener);
}
#Override
protected void onPause() {
stopBackgroundThread();
super.onPause();
}
private void stopBackgroundThread() {
mBackgroundThread.quitSafely();
try {
mBackgroundThread.join();
mBackgroundThread = null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void startBackgroundThread() {
mBackgroundThread = new HandlerThread("Camera Background");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
}
}
Also, here is my login authentication class:
public class MainLoginActivity extends AppCompatActivity {
private EditText mEmailField;
private EditText mPasswordField;
private Button mLoginBtn;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private boolean isUserClickedBackButton = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_login);
mAuth = FirebaseAuth.getInstance();
mEmailField = (EditText) findViewById(R.id.emailField);
mPasswordField = (EditText) findViewById(R.id.passwordField);
mLoginBtn = (Button) findViewById(R.id.loginBtn);
// connection to user authentication on firebase (database)
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
if (firebaseAuth.getCurrentUser() != null){
startActivity(new Intent(MainLoginActivity.this, MainActivity.class));
}
}
};
mLoginBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startSiginIn();
}
});
}
#Override
protected void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
}
#Override
// code for exiting from app by using back button on login page
public void onBackPressed() {
//moveTaskToBack(true);
if (!isUserClickedBackButton){
Toast.makeText(this, "Press back again to exit", Toast.LENGTH_SHORT).show();
isUserClickedBackButton = true;
} else {
System.exit(0); // exits right out of app
super.onBackPressed();
}
}
// for login
private void startSiginIn() {
String email = mEmailField.getText().toString();
String password = mPasswordField.getText().toString();
if (TextUtils.isEmpty(email) || TextUtils.isEmpty(password)) {
Toast.makeText(MainLoginActivity.this, "Please input email and password", Toast.LENGTH_LONG).show();
} else {
mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (!task.isSuccessful())
Toast.makeText(MainLoginActivity.this, "Sign in problem. Please check email" +
" and password", Toast.LENGTH_LONG).show();
}
});
}
}
}
Again, any help and advice greatly appreciated.
Thanks
If you want to add the user name in the name of your file, you need to change this line of code:
file = new File(Environment.getExternalStorageDirectory()
+ "/" + UUID.randomUUID().toString()
+ FirebaseAuth.getInstance().getCurrentUser() + ".jpg");
with
file = new File(Environment.getExternalStorageDirectory()
+ "/" + UUID.randomUUID().toString()
+ FirebaseAuth.getInstance().getCurrentUser().getDisplayName() + ".jpg");
See, I have added a call to .getDisplayName() method.

Show camera2 preview in wallpaperservice

I need to show camera preview in live wallpaper.
I've already made for android < M versions. But can't understand how it working with new API. Oldest Camera is deprecated now
In google example they put it in xml and in TextureView but how I can change that for my needs, I can't understand.
Anyway Thanks!
Google example
https://github.com/googlesamples/android-Camera2Basic
Below my code.
Start wallpaper
Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, new ComponentName(this, TransparentWallpaperService.class));
startActivity(intent);
TransparentWallpaperService
public class TransparentWallpaperService extends WallpaperService {
#Override
public Engine onCreateEngine() {
return new GlowEngine();
}
private class GlowEngine extends Engine {
private final Handler handler = new Handler();
private final Runnable viewRunner = new Runnable() {
#Override
public void run() {
drawView();
}
};
private boolean visible = true;
private CameraView view;
public GlowEngine() {
super();
view = new CameraView(getBaseContext(), getSurfaceHolder());
handler.post(viewRunner);
}
#Override
public void onVisibilityChanged(boolean visible) {
this.visible = visible;
if (visible) {
handler.post(viewRunner);
}
else {
handler.removeCallbacks(viewRunner);
}
}
#Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
this.visible = false;
handler.removeCallbacks(viewRunner);
}
private void drawView() {
view.surfaceChanged(getSurfaceHolder(), OPAQUE, view.getWidth(), view.getHeight());
handler.removeCallbacks(viewRunner);
if (visible) {
handler.postDelayed(viewRunner, 4000);
}
}
}
}
CameraView class
public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder holder;
private Camera camera;
public CameraView(Context context) {
super(context);
camera = getCameraInstance();
}
public CameraView(Context context, SurfaceHolder holder) {
this(context);
this.holder = holder;
holder.addCallback(this);
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
if(camera == null) {
camera = getCameraInstance();
}
if(camera != null) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
}
catch (IOException e) {
Log.e("CameraView", "Error setting camera preview: " + e.getMessage());
}
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
boolean portrait = true;
if (width > 0 && height >0 && width < height){
portrait =true;
} else if (width > 0 && height >0 && width > height){
portrait = false;
}
Camera.Parameters parameters;
if (camera == null) {
camera = getCameraInstance();
}
if (camera != null){
parameters = camera.getParameters();
Camera.Size size = parameters.getPictureSize();
size = parameters.getPreviewSize();
parameters.setPreviewSize(size.width, size.height);
if (portrait) {
camera.setDisplayOrientation(90);
} else {
camera.setDisplayOrientation(180);
}
try {
camera.setParameters(parameters);
camera.setPreviewDisplay(holder);
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
if(camera != null) {
try {
camera.stopPreview();
camera.release();
}
catch (Exception e) {
Log.e("CameraView", "Error stopping camera preview: " + e.getMessage());
}
}
}
private Camera getCameraInstance() {
Context context = getContext();
Camera camera = null;
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
try {
camera = Camera.open();
}
catch (Exception e) {
Log.e("CameraView", "Error getting camera instance: " + e.getMessage());
}
}
else {
Log.i("CameraView", "No camera found!");
}
return camera;
}
}
You can just keep using the old API; it's fully functional even on new devices.
Otherwise, you can just replace the TextureView with a SurfaceView easily enough; instead of creating a Surface from TextureView's SurfaceTexture, get a Surface from SurfaceView's SurfaceHolder in surfaceChanged.

Front camera not working on different devices

public class camera extends Activity {
private static final String LOG_TAG = "photo";
private int cameraId = 1;
private Camera camera = null;
Button b1, b2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_photo);
}
public void takephoto() {
camera.takePicture(null, null, pictureCallback);
}
#Override
public void onResume() {
Log.d(LOG_TAG, "onResume");
super.onResume();
setSurface();
}
private Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
try {
FileOutputStream jpg = new FileOutputStream(String.format(
"/sdcard/%d.jpg", System.currentTimeMillis()));
jpg.write(data);
jpg.close();
Log.i(LOG_TAG, "written " + data.length + " bytes to /sdcard/JBCameraCapture.jpg");
} catch (Exception e) {
e.printStackTrace();
}
finish();
}
};
private SurfaceHolder.Callback shCallback = new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.i(LOG_TAG, "surfaceDestroyed callback");
if (camera != null) {
camera.stopPreview();
camera.release();
}
camera = null;
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
Log.i(LOG_TAG, "surfaceCreated callback");
startCamera(cameraId);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.i(LOG_TAG, "surfaceChanged callback ");
}
};
private void setSurface() {
SurfaceView previewSurfaceView = (SurfaceView) findViewById(R.id.preview_surface);
previewSurfaceView.getHolder().addCallback(shCallback);
}
protected void startCamera(final int id) {
new AsyncTask<Integer, Void, Camera>() {
#Override
protected Camera doInBackground(Integer... ids) {
return openCamera(ids[0]);
}
#Override
protected void onPostExecute(Camera c) {
startPreview(id, c);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
takephoto();
}
}, 1000);
}
}.execute(id);
}
private static Camera openCamera(int id) {
Log.d(LOG_TAG, "opening camera " + id);
Camera camera = null;
try {
camera = Camera.open(id);
Log.d(LOG_TAG, "opened camera " + id);
} catch (Exception e) {
e.printStackTrace();
camera.release();
camera = null;
}
return camera;
}
private void startPreview(int id, Camera c) {
if (c != null) {
try {
SurfaceView previewSurfaceView = (SurfaceView) findViewById(R.id.preview_surface);
SurfaceHolder holder = previewSurfaceView.getHolder();
c.setPreviewDisplay(holder);
camera = c;
cameraId = id;
} catch (IOException e) {
e.printStackTrace();
c.release();
}
}
}
}
I have written this code for the front camera but it is not working in all Android devices, in some devices it reboots the phone and in some devices it shows an unfortunate error and in some devices it works properly.

Camera Preview freezing on Menu Intent

I have a Glass application where I am trying to use a Live Card to start a Camera Preview activity from the menu options. The application seems to freeze when I move away from the Live Card (say, to the weather) and back, and then try to bring up the camera through the menu options. Sorry for all of the code, here are the following files:
Service.java
. . .
#Override
public IBinder onBind(Intent intent) { return mBinder; }
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (mLiveCard == null) {
mLiveCard = new LiveCard(this, LIVE_CARD_TAG);
mRemoteViews = new RemoteViews(getPackageName(), R.layout.service_layout);
mLiveCard.setViews(mRemoteViews);
// Display the options menu when the live card is tapped.
Intent menuIntent = new Intent(this, MenuActivity.class);
menuIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TASK);
mLiveCard.setAction(PendingIntent.getActivity(this, 0, menuIntent, 0));
mLiveCard.attach(this);
mLiveCard.publish(PublishMode.REVEAL);
} else {
mLiveCard.navigate();
}
return START_STICKY;
}
#Override
public void onDestroy() {
if (mLiveCard != null && mLiveCard.isPublished()) {
mLiveCard.unpublish();
mLiveCard = null;
}
super.onDestroy();
}
}
MenuActivity.java
public class MenuActivity extends Activity {
#Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
// Open the options menu right away.
openOptionsMenu();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.layout, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_stop:
// Stop the service which will unpublish the live card.
stopService(new Intent(MenuActivity.this, Service.class));
return true;
case R.id.action_camera:
startActivity(new Intent(MenuActivity.this, Camera.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onOptionsMenuClosed(Menu menu) { finish(); }
}
Camera.java
public class Camera extends Activity {
private SurfaceView mPreview = null;
private SurfaceHolder mPreviewHolder = null;
private Camera mCamera = null;
private boolean inPreview = false;
private boolean cameraConfigured = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
mPreview = (SurfaceView) findViewById(R.id.camera_preview);
mPreviewHolder = mPreview.getHolder();
mPreviewHolder.addCallback(surfaceCallback);
}
#Override
public void onResume() {
super.onResume();
mCamera = Camera.open();
startPreview();
}
#Override
public void onPause() {
super.onPause();
if (inPreview) {
mCamera.stopPreview();
}
mCamera.release();
mCamera = null;
inPreview = false;
}
private Camera.Size getBestPreviewSize(int width, int height,
Camera.Parameters parameters) {
Camera.Size result = null;
for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
if (size.width <= width && size.height <= height) {
if (result == null) {
result = size;
} else {
int resultArea = result.width * result.height;
int newArea = size.width * size.height;
if (newArea > resultArea) {
result = size;
}
}
}
}
return (result);
}
private void initPreview(int width, int height) {
if (mCamera != null && mPreviewHolder.getSurface() != null) {
try {
mCamera.setPreviewDisplay(mPreviewHolder);
} catch (Throwable t) {
Log.e("PreviewDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
}
if (!cameraConfigured) {
Camera.Parameters parameters = mCamera.getParameters();
Camera.Size size = getBestPreviewSize(width, height,
parameters);
if (size != null) {
parameters.setPreviewSize(size.width, size.height);
mCamera.setParameters(parameters);
cameraConfigured = true;
}
}
}
}
private void startPreview() {
if (cameraConfigured && mCamera != null) {
mCamera.startPreview();
inPreview = true;
}
}
I can't seem to figure out why the camera preview works initially but doesn't work when navigating away. I feel like there is something simple that I am just missing here. Any help would be greatly appreciated!
I'm not sure if this would fix your problem, but I would start and stop the camera this way:
private Camera getCameraInstance() {
Camera mCamera = null;
try {
/* attempt to get a Camera instance */
mCamera = Camera.open();
} catch (Exception e) {
/* Camera is not available (in use or does not exist) */
Log.e(TAG, "Error getting camera: " + e.getMessage());
// process null error here
// finish();
}
/* returns null if camera is unavailable */
return mCamera;
}
#Override
public void onResume() {
super.onResume();
if (mCamera == null) {
mCamera = getCameraInstance();
if (mCamera != null) {
startPreview();
} else {
// process null error here
}
}
}
#Override
public void onPause() {
super.onPause();
if (mCamera != null) {
/* stop preview */
if (inPreview) {
try {
mCamera.stopPreview();
} catch (Exception e) {
/* ignore: tried to stop a non-existent preview */
}
}
/* release the camera */
mCamera.release();
mCamera = null;
inPreview = false;
}
}
I would also check if mCamera or getSurface is null in initPreview.
private void initPreview(int width, int height) {
if (mCamera != null && mPreviewHolder.getSurface() != null) {
try {
mCamera.setPreviewDisplay(mPreviewHolder);
} catch (Throwable t) {
Log.e("PreviewDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
}
if (!cameraConfigured) {
Camera.Parameters parameters = mCamera.getParameters();
Camera.Size size = getBestPreviewSize(width, height,
parameters);
if (size != null) {
parameters.setPreviewSize(size.width, size.height);
mCamera.setParameters(parameters);
cameraConfigured = true;
}
}
} else {
Log.e(TAG, "Camera or getSurface is null");
}
}

Categories