I am trying to integrate some code and one of the lines I have is:
mPreview = new CameraPreview(this, mCamera, previewCb, autoFocusCB);
When I have it in an Activity, there is no error. When I put it in my Fragment, I get this error:
Expected:android.content.context
Actual:this (com.xxx.ScanFragment)
This is the CameraPreview method
public CameraPreview(Context context, Camera camera,
PreviewCallback previewCb,
AutoFocusCallback autoFocusCb)
As I said, no error when this was in the activity file, so I assume the issue is some difference in what "context" is between Activities and Fragments?
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.TextView;
import com.parse.ParseUser;
import net.sourceforge.zbar.Config;
import net.sourceforge.zbar.Image;
import net.sourceforge.zbar.ImageScanner;
import net.sourceforge.zbar.Symbol;
import net.sourceforge.zbar.SymbolSet;
/**
* Created by Jakub on 7/23/2014.
*/
public class Pay extends Fragment {
private Button scanBtn;
private TextView formatTxt, contentTxt;
private Camera mCamera;
private CameraPreview mPreview;
private Handler autoFocusHandler;
TextView scanText;
Button scanButton;
ImageScanner scanner;
private boolean barcodeScanned = false;
private boolean previewing = true;
static {
System.loadLibrary("iconv");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_pay, container, false);
return rootView;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
autoFocusHandler = new Handler();
mCamera = getCameraInstance();
/* Instance barcode scanner */
scanner = new ImageScanner();
scanner.setConfig(0, Config.X_DENSITY, 3);
scanner.setConfig(0, Config.Y_DENSITY, 3);
mPreview = new CameraPreview(getActivity(), mCamera, previewCb, autoFocusCB);
FrameLayout preview = (FrameLayout)getActivity().findViewById(R.id.cameraPreview);
Log.d(Payspot.TAG,"This is the string:" + preview.toString());
preview.addView(mPreview);
scanText = (TextView)getActivity().findViewById(R.id.scanText);
scanButton = (Button)getActivity().findViewById(R.id.ScanButton);
scanButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (barcodeScanned) {
barcodeScanned = false;
scanText.setText("Scanning...");
mCamera.setPreviewCallback(previewCb);
mCamera.startPreview();
previewing = true;
mCamera.autoFocus(autoFocusCB);
}
}
});
}
public void onPause() {
super.onPause();
releaseCamera();
}
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open();
} catch (Exception e){
}
return c;
}
private void releaseCamera() {
if (mCamera != null) {
previewing = false;
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
}
private Runnable doAutoFocus = new Runnable() {
public void run() {
if (previewing)
mCamera.autoFocus(autoFocusCB);
}
};
Camera.PreviewCallback previewCb = new Camera.PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = parameters.getPreviewSize();
Image barcode = new Image(size.width, size.height, "Y800");
barcode.setData(data);
int result = scanner.scanImage(barcode);
if (result != 0) {
previewing = false;
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
SymbolSet syms = scanner.getResults();
for (Symbol sym : syms) {
scanText.setText("barcode result " + sym.getData());
barcodeScanned = true;
}
}
}
};
// Mimic continuous auto-focusing
Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
autoFocusHandler.postDelayed(doAutoFocus, 1000);
}
};
}
Activity extends Context, but Fragments do not. This is why you can pass it this for a context parameter. So the error message sees your ScanFragment as a parameter for Context which does not work. Each Fragment is associated with an Activity's fragment. You can either use getActivity() or getActivity().getApplicationContext() to receive a valid context to use in these situations.
Your new code would be:
mPreview = new CameraPreview(getActivity(), mCamera, previewCb, autoFocusCB);
In fragment you must call getActivity() method to get the context. Because fragment must be associated with an activity and has activity context (activity extends Context).
Related
I have two buttons that need to open a custom dialog that has a surface view that's supposed to hold a camera preview. I need to not have the default camera controls, just the preview itself, behind another included layout that's holding buttons.
Here's the code for my buttons:
topeyebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg3) {
//Starting a new Intent
Intent topClick = new Intent(Intent.ACTION_VIEW, Uri.parse("http://funnmag.com"));
// starting new activity
startActivity(topClick);
}});
And here's the code for my surface view and camera preview:
package com.adanawtn.FunnMagViewerWindow;
import java.io.IOException;
import android.app.Activity;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup.LayoutParams;
public class camerapreview extends Activity {
private SurfaceView surface_view;
private Camera mCamera;
SurfaceHolder.Callback sh_ob = null;
SurfaceHolder surface_holder = null;
SurfaceHolder.Callback sh_callback = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
surface_view = new SurfaceView(getApplicationContext());
addContentView(surface_view, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
if (surface_holder == null) {
surface_holder = surface_view.getHolder();
}
sh_callback = my_callback();
surface_holder.addCallback(sh_callback);
}
SurfaceHolder.Callback my_callback() {
SurfaceHolder.Callback ob1 = new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
mCamera.startPreview();
}
};
return ob1;
}
}
I have an app that scans qr code. The app returns the url in a string named value. I want to open the url in a webview. How can I call the WebViewActivity in CameraTestActivity the the WebViewActivity uses the url from the CameraTestActvity for loading the website. There are comments in the code for the things I want to do but I do not know how. Can you please help me? I may be not able to graduate because of this problem? I've been doing this for days.
CameraTestActivity.java
import net.sourceforge.zbar.Config;
import net.sourceforge.zbar.Image;
import net.sourceforge.zbar.ImageScanner;
import net.sourceforge.zbar.Symbol;
import net.sourceforge.zbar.SymbolSet;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.os.Handler;
import android.text.method.LinkMovementMethod;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.TextView;
/* Import ZBar Class files */
#SuppressLint("SetJavaScriptEnabled")
public class CameraTestActivity extends Activity
{
private Camera mCamera;
private CameraPreview mPreview;
private Handler autoFocusHandler;
TextView scanText;
Button scanButton;
Button exitButton;
WebView web;
ImageScanner scanner;
private boolean barcodeScanned = false;
private boolean previewing = true;
static {
System.loadLibrary("iconv");
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
autoFocusHandler = new Handler();
mCamera = getCameraInstance();
/* Instance barcode scanner */
scanner = new ImageScanner();
scanner.setConfig(0, Config.X_DENSITY, 3);
scanner.setConfig(0, Config.Y_DENSITY, 3);
mPreview = new CameraPreview(this, mCamera, previewCb, autoFocusCB);
FrameLayout preview = (FrameLayout)findViewById(R.id.cameraPreview);
preview.addView(mPreview);
scanText = (TextView)findViewById(R.id.scanText);
scanButton = (Button)findViewById(R.id.ScanButton);
scanButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (barcodeScanned) {
barcodeScanned = false;
scanText.setText("Place code inside the square to scan");
mCamera.setPreviewCallback(previewCb);
mCamera.startPreview();
previewing = true;
mCamera.autoFocus(autoFocusCB);
}
}
});
exitButton = (Button)findViewById(R.id.ExitButton);
exitButton.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
System.exit(0);
}
});
}
public void onPause() {
super.onPause();
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mPreview.getHolder().removeCallback(mPreview); // you need this line
releaseCamera();
}
}
#Override
public void onResume() {
super.onResume();
// Get the Camera instance as the activity achieves full user focus
try {
mCamera = Camera.open();
mCamera.setPreviewCallback(null);
mPreview = new CameraPreview(this, mCamera, previewCb, autoFocusCB);
FrameLayout preview = (FrameLayout)findViewById(R.id.cameraPreview);
preview.addView(mPreview);
mCamera.startPreview();
} catch (Exception e) {
}
}
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open();
} catch (Exception e){
}
return c;
}
private Runnable doAutoFocus = new Runnable() {
public void run() {
if (previewing)
mCamera.autoFocus(autoFocusCB);
}
};
PreviewCallback previewCb = new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
Camera.Parameters parameters = camera.getParameters();
Size size = parameters.getPreviewSize();
Image barcode = new Image(size.width, size.height, "Y800");
barcode.setData(data);
int result = scanner.scanImage(barcode);
if (result != 0) {
previewing = false;
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
SymbolSet syms = scanner.getResults();
for (Symbol sym : syms) {
String value = new String(sym.getData()); //url scanned from the qr code
if(value.startsWith("http://192.168.1.6")){ //if the url starts with
scanText.setText("QR Code result: " + value);
barcodeScanned = true;
//intent for WebViewActivty.java
//The WebViewActivty.java should load the string value which contains the the url
}
else{
scanText.setText("QR Code result 2: " + value);
barcodeScanned = true;
}
TextView tv = (TextView) findViewById(R.id.scanText);
tv.setMovementMethod(LinkMovementMethod.getInstance());
}
}
}
};
// Mimic continuous auto-focusing
AutoFocusCallback autoFocusCB = new AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
autoFocusHandler.postDelayed(doAutoFocus, 1000);
}
};
private void releaseCamera(){
if (mCamera != null){
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
}
WebViewActivity.java
package net.sourceforge.zbar.android.CameraTest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class WebViewActivity extends Activity {
private WebView webView;
#SuppressLint("SetJavaScriptEnabled")
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webview);
webView = (WebView) findViewById(R.id.web_engine);
webView.setWebViewClient(new MyWebClient());
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("http://192.168.1.6/sp/products.php");//the link should be from the CameraTestActivity
}
}
class MyWebClient extends WebViewClient {
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// TODO Auto-generated method stub
super.onPageStarted(view, url, favicon);
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// TODO Auto-generated method stub
return false;
}
}
Replace your preview callback with this.
PreviewCallback previewCb = new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
Camera.Parameters parameters = camera.getParameters();
Size size = parameters.getPreviewSize();
Image barcode = new Image(size.width, size.height, "Y800");
barcode.setData(data);
int result = scanner.scanImage(barcode);
if (result != 0) {
previewing = false;
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
SymbolSet syms = scanner.getResults();
for (Symbol sym : syms) {
String value = new String(sym.getData()); //url scanned from the qr code
Intent i = new Intent(CameraTestActivity.this,WebViewActivity.class);
i.putExtra("mUrl",value);
startActivity(i)
}
else{
scanText.setText("QR Code result 2: " + value);
barcodeScanned = true;
}
TextView tv = (TextView) findViewById(R.id.scanText);
tv.setMovementMethod(LinkMovementMethod.getInstance());
}
}
}
};
and change your webActivity to this:
String mUrl = getIntent().getStringExtra("mUrl");
webView = (WebView) findViewById(R.id.web_engine);
webView.setWebViewClient(new MyWebClient());
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl(mUrl);
if you use ('me.dm7.barcodescanner:zxing:1.9') library. So just follow this. Hope it works for you also.
Intent newWindow = new Intent(getApplicationContext(), Browser.class);
newWindow.putExtra("scannedLink", myResult);
startActivity(newWindow);
Happy Coding
My objective is as simple as to have my own flashlight app; I have researched both the android developer site and stackoverflow quite thoroughly but seem to lack the connecting bits:
package my.torch;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.CompoundButton;
public class MainActivity extends Activity {
/* public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
*/
Camera mCamera;
CompoundButton mTorch;
Parameters camParams;
private Context context;
AlertDialog.Builder builder;
AlertDialog alertDialog;
public SurfaceView surfaceView;
public SurfaceHolder surfaceHolder;
public String flashMode = null;
/** A safe way to get an instance of the Camera object. */
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
surfaceView = (SurfaceView) findViewById(R.id.mysurface);
surfaceHolder = surfaceView.getHolder();
context = MainActivity.this;
if(context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA_FLASH)){
mTorch = (CompoundButton) findViewById(R.id.toggleButton1);
}
else{
// should use Dialog
// tell the user that he has no camera
//showDialog(context, FLASH_NOT_SUPPORTED);
}
final Camera mCamera = Camera.open(0);
mTorch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
Log.e("mTorch", "on");
Parameters camParams = mCamera.getParameters();
// params.setFlashMode( Parameters.FLASH_MODE_OFF )
camParams.setFlashMode( Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(camParams);
mCamera.startPreview();
flashMode = camParams.getFlashMode();
Log.e("mTorch", flashMode );
// The toggle is enabled
} else {
// The toggle is disabled
Log.e("mTorch", "off");
Parameters camParams = mCamera.getParameters();
// params.setFlashMode( Parameters.FLASH_MODE_OFF )
camParams.setFlashMode( Parameters.FLASH_MODE_OFF);
mCamera.setParameters(camParams);
mCamera.stopPreview();
flashMode = camParams.getFlashMode();
Log.e("mTorch", flashMode );
}
}
});
//mCamera.release();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onDestroy() {
super.onDestroy();
if (mCamera != null) {
camParams.setFlashMode(Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(camParams);
mCamera.stopPreview();
mCamera.release();
}
}
}
The logging happily reports that the flashmode is torch or off as intended, however: The flash does not torch at all.
I read that I needed a surfaceview so I added it but with 0 height.
As I did collect bits and pieces here and there the code is probably not beautiful, my apologies.
Any idea on what I'm missing out?
(this is for a Nexus 5, 4.4.2)
Did you add permission to access camera in your manifest file?
uses-permission android:name="android.permission.CAMERA"
I made a camera preview app for android and everything works fine even when I press the power button to make device asleep, and waking it up again. But when my activity goes to background (like pressing home button) and then it comes to foreground again the program stops.
This is my activity code:
package com.example.campreview;
import com.example.campreview.CameraPreview;
import com.example.campreview.R;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PreviewCallback;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.view.Menu;
import android.view.View;
public class ScanActivity extends Activity {
private CameraPreview CamPrev = null;
private FrameLayout PreviewFrm;
private Camera cam = null;
private Handler atfcs;
private ImageScanner scnr;
private boolean hascam = false;
private boolean prvng = true;
private boolean paused = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
PreviewFrm = (FrameLayout)findViewById(R.id.PreviewFrm);
StartCamera();
if (cam != null) {
hascam = true;
atfcs = new Handler();
CamPrev = new CameraPreview(this, cam, PreviewCB, AutoFocusCB);
PreviewFrm.addView(CamPrev);
}
}
#Override
public void onPause() {
ReleaseCamera();
paused = true;
super.onPause();
}
#Override
public void onResume() {
super.onResume();
if (paused) StartPreview();
}
private boolean StartCamera() {
boolean r = true;
if (cam == null) {
try {
cam = Camera.open();
} catch (Exception e) {
cam = null;
r = false;
}
if (cam != null) {
try {
Camera.Parameters p = cam.getParameters();
if (p.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_AUTO))
p.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
if (p.getSupportedFlashModes().contains(Camera.Parameters.FLASH_MODE_OFF))
p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
if (p.getSupportedPreviewFormats().contains(ImageFormat.NV21))
p.setPreviewFormat(ImageFormat.NV21);
Camera.Size s = null;
int a = 0, b;
for (Camera.Size z : p.getSupportedPreviewSizes()) {
b = z.width * z.height;
if (Math.abs(b - 307200) < Math.abs(a - 307200)) { //640x480 is the best
s = z;
a = b;
}
}
if (a != 0) p.setPreviewSize(s.width, s.height);
cam.setParameters(p);
cam.setDisplayOrientation(90);
if (CamPrev != null) cam.setPreviewDisplay(CamPrev.getHolder());
} catch (Exception e) {
r = false;
cam.release();
cam = null;
}
}
}
return r;
}
private void ReleaseCamera() {
if (cam != null) {
StopPreview();
cam.release();
cam = null;
}
}
public void StartPreview() {
if ((!prvng) & hascam) {
if (StartCamera()) {
cam.setPreviewCallback(PreviewCB);
cam.startPreview();
cam.autoFocus(AutoFocusCB);
prvng = true;
}
}
}
public void StopPreview() {
if (prvng) {
cam.stopPreview();
cam.setPreviewCallback(null);
prvng = false;
}
}
private Runnable DoAutoFocus = new Runnable() {
public void run() {
if (prvng) cam.autoFocus(AutoFocusCB);
}
};
AutoFocusCallback AutoFocusCB = new AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
atfcs.postDelayed(DoAutoFocus, 1000);
}
};
PreviewCallback PreviewCB = new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
//
}
};
}
And this is the preview code:
package com.example.campreview;
import java.io.IOException;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.AutoFocusCallback;
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder hldr;
private Camera cam;
private PreviewCallback pcb;
private AutoFocusCallback afcb;
public CameraPreview(Context context, Camera camera, PreviewCallback previewCb, AutoFocusCallback autoFocusCb) {
super(context);
cam = camera;
pcb = previewCb;
afcb = autoFocusCb;
hldr = getHolder();
hldr.addCallback(this);
//hldr.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
try {
cam.setPreviewDisplay(holder);
} catch (IOException e) {
// No Code
}
}
public void surfaceDestroyed(SurfaceHolder holder) {}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (hldr.getSurface() == null) return;
try {
cam.stopPreview();
} catch (Exception e){
// No Code
}
try {
cam.setPreviewDisplay(hldr);
cam.setPreviewCallback(pcb);
cam.startPreview();
cam.autoFocus(afcb);
} catch (Exception e) {
// No Code
}
}
}
Is there any idea how can I solve this problem?
I found the problem. It seems the SurfaceView that is made in program destroys on activity stop. So I replaced it with a SurfaceView in my layout.
package com.example.campreview;
import com.example.campreview.R;
import java.io.IOException;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PreviewCallback;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
public class ScanActivity extends Activity implements OnClickListener {
private SurfaceView PreviewSfc;
private Camera cam = null;
private Handler atfcs;
private boolean hascam = false;
private boolean validdisplay = false;
private boolean prvng = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
PreviewSfc = (SurfaceView)findViewById(R.id.PreviewSfc);
PreviewSfc.getHolder().addCallback(SurfaceCB);
//PreviewSfc.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
StartCamera();
if (cam != null) {
hascam = true;
atfcs = new Handler();
}
}
#Override
public void onPause() {
ReleaseCamera();
super.onPause();
}
#Override
public void onResume() {
super.onResume();
StartPreview();
}
private boolean StartCamera() {
boolean r = true;
if (cam == null) {
try {
cam = Camera.open();
} catch (Exception e) {
cam = null;
r = false;
}
if (cam != null) {
try {
Camera.Parameters p = cam.getParameters();
if (p.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_AUTO))
p.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
if (p.getSupportedFlashModes().contains(Camera.Parameters.FLASH_MODE_OFF))
p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
if (p.getSupportedPreviewFormats().contains(ImageFormat.NV21))
p.setPreviewFormat(ImageFormat.NV21);
Camera.Size s = null;
int a = 0, b;
for (Camera.Size z : p.getSupportedPreviewSizes()) {
b = z.width * z.height;
if (Math.abs(b - 307200) < Math.abs(a - 307200)) { //640x480 is the best
s = z;
a = b;
}
}
if (a != 0) p.setPreviewSize(s.width, s.height);
cam.setParameters(p);
cam.setDisplayOrientation(90);
if (validdisplay) cam.setPreviewDisplay(PreviewSfc.getHolder());
} catch (Exception e) {
r = false;
cam.release();
cam = null;
}
}
}
//if (!r) Error message that failed to start camera
return r;
}
private void ReleaseCamera() {
if (cam != null) {
StopPreview();
cam.release();
cam = null;
}
}
public void StartPreview() {
if ((!prvng) & (hascam) & (validdisplay)) {
if (StartCamera()) {
cam.setPreviewCallback(PreviewCB);
cam.startPreview();
cam.autoFocus(AutoFocusCB);
prvng = true;
}
}
}
public void StopPreview() {
if (prvng) {
cam.stopPreview();
cam.setPreviewCallback(null);
prvng = false;
}
}
private Runnable DoAutoFocus = new Runnable() {
public void run() {
if (prvng) cam.autoFocus(AutoFocusCB);
}
};
AutoFocusCallback AutoFocusCB = new AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
atfcs.postDelayed(DoAutoFocus, 1000);
}
};
PreviewCallback PreviewCB = new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
//
}
};
SurfaceHolder.Callback SurfaceCB = new SurfaceHolder.Callback() {
public void surfaceCreated(SurfaceHolder holder) {
if (cam != null) {
try {
cam.setPreviewDisplay(holder);
} catch (IOException e) {
// No Code
}
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
validdisplay = true;
StartPreview();
}
public void surfaceDestroyed(SurfaceHolder holder) {
validdisplay = false;
}
};
}
I'm learning how to program the video camera in android and wrote a very basic program (XML with SurfaceView and two buttons, one to start, one to stop video recording). Video Preview works fine, but after clicking the start_video button I'm getting an IllegalStateException in line 71 mediaRecorder.setVideoFrameRate(videoFramesPerSecond);:
IllegalStateException.<init>() line: 33
MediaRecorder.setVideoFrameRate(int) line: not available [native method]
CamtestActivity$2.onClick(View) line: 71
. I can't understand why this line is throwing this exception while the former line for example, does not.
Any hints? Thanks.
package com.grapp.camtest;
import java.io.IOException;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;
public class CamtestActivity extends Activity implements SurfaceHolder.Callback{
private static final String TAG = "Camera-Tutorial";
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private Camera camera;
private boolean previewRunning;
private MediaRecorder mediaRecorder;
private final int maxDurationInMs = 20000;
private final int videoFramesPerSecond = 20;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
surfaceView = (SurfaceView) findViewById(R.id.surface_camera);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
Button start_video = (Button) findViewById(R.id.start_video);
Button stop_video = (Button) findViewById(R.id.stop_video);
stop_video.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mediaRecorder.stop();
camera.lock();
}
});
start_video.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try {
camera.unlock();
mediaRecorder = new MediaRecorder();
mediaRecorder.setCamera(camera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
mediaRecorder.setMaxDuration(maxDurationInMs);
mediaRecorder.setVideoFrameRate(videoFramesPerSecond);
mediaRecorder.setVideoSize(surfaceView.getWidth(), surfaceView.getHeight());
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
mediaRecorder.setOutputFile("/sdcard/video.mp4");
mediaRecorder.prepare();
mediaRecorder.start();
} catch (IllegalStateException e) {
Log.e(TAG,e.getMessage());
e.printStackTrace();
} catch (IOException e) {
Log.e(TAG,e.getMessage());
e.printStackTrace();
}
}
});
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
if (camera != null){
Camera.Parameters params = camera.getParameters();
camera.setParameters(params);
}
else {
Toast.makeText(getApplicationContext(), "Camera not available!", Toast.LENGTH_LONG).show();
finish();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (previewRunning){
camera.stopPreview();
}
Camera.Parameters p = camera.getParameters();
p.setPreviewSize(width, height);
camera.setParameters(p);
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
previewRunning = true;
}
catch (IOException e) {
Log.e(TAG,e.getMessage());
e.printStackTrace();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
previewRunning = false;
camera.release();
}
}
From the documentation for setVideoFrameRate():
Sets the frame rate of the video to be captured.
Must be called after setVideoSource().
Call this after setOutFormat() but before prepare().
It seems like you have not yet called setVideoSource() before you try to setVideoFrameRate(). Try setting the video source and see if that solves your problem.