我正在尝试构建一个应用程序,它会定期调用相机拍照并保存。 我的问题是,除非我把'takePictuce'打电话给' onCreate'对“拍摄图片”的回应' (onPictureTaken)永远不会被调用。
我已经尽可能简单地分解了应用程序。
如果处理相机的类部分定义为:
public class CameraHandler {
private Camera mCamera;
public CameraHandler(){
mCamera = Camera.open();
mCamera.setPreviewTexture(new SurfaceTexture(10));
mCamera.startPreview();
mCamera.takePicture(null, null, mPicture);
}
Camera.PictureCallback mPicture = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
} catch (IOException e) { }
}
};
然后,当我将以下代码放入MainActivity.java时,' onPictureTaken'在实例化CameraHandler时调用。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CameraHandler cameraHandler = new CameraHandler();
}
但是,在MainActivity.java中的click事件中调用实例化CameraHandler将不会调用' onPictureTaken'响应takePicture电话。
(This snippet is located in MainACtivity.java)
public void onClickListener(View view){
CameraHandler cameraHandler = new CameraHandler();
}
那么为什么会发生这种情况呢?我怎样才能接到电话,让它在所属的班级拍照,而不是在主要的'该计划?
欢迎所有帮助
答案 0 :(得分:0)
最后想出了如何设置手机拍摄定时照片而不显示任何屏幕。 我遇到了两个主要问题。首先,我想拍摄照片而不显示到屏幕。沿着这些方向,我找到了一个他们使用的例子: mCamera.setPreviewTexture(new SurfaceTexture(10)); 使用此预览方法时,屏幕上没有显示任何内容。看来需要进行某种预览。另一种方法是将预览设置为1像素。这种方法在网上有例子似乎也有用,但我没试过。
第二个也是更大的问题与' onPictureTaken'方法。此方法会在拍摄照片后处理您的照片。呼叫。 似乎无论我使用什么循环方法,或者在代码中的哪个地方调用“拍摄图片”。找到了,所有的' onPictureTaken'方法排队等候,一旦接下来的话,就会一个接一个地调用方法。来电者结束了。
尽管onPictureTaken处理的图片数据处于适当的时间顺序,但我可以看到存储了数百张照片并等待处理可能会导致问题,并且需要找到一种方法,在处理和存储照片之前拍下一张照片。
沿着这些方向,我偶然发现了AlarmManager并将其与BroadcastReceiver和Future类耦合以解决问题。
我所做的是将alarmManger设置为在设定的时间或时间频率下关闭。 BroadcaseReceiver捕获此呼叫&反过来调用一个创建的方法 一个线索,其中一个未来'对象打电话拍照。
'未来'对象很好,因为它会等待物理相机拍摄照片(takePicture)然后处理它(onPictureTaken)。这一切都发生在一个线程中,然后终止。因此,不需要对要处理的图片进行排队,并且每个图片序列都是单独处理的。
代码包含在下面。请注意,某些默认'覆盖'被遗漏以节省空间。此外,可见屏幕基本上是一个捕获点击事件的按钮......非常基本。 MainActivity.java: 包myTest.com.test;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class MainActivity extends Activity {
CameraHandler cameraHandler;
public BroadcastReceiver br;
public PendingIntent pi;
public AlarmManager am;
final static private long LOOPTIME = 20000;
private static final ExecutorService threadpool = Executors.newFixedThreadPool(3);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setup();
}
private void setup() {
try{
cameraHandler = new CameraHandler();
br = new BroadcastReceiver() {
@Override
public void onReceive(Context c, Intent i) {
//Toast.makeText(c, "Taking a pic!", Toast.LENGTH_LONG).show();
TryAThread();
}
};
registerReceiver(br, new IntentFilter("com.timedActivity.activity") );
pi = PendingIntent.getBroadcast(this, 0, new Intent("com.timedActivity.activity"), 0);
am = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
}
catch (Exception e){ }
}
private void TryAThread() {
try{
CameraCaller cameraCaller = new CameraCaller(cameraHandler);
Future future = threadpool.submit(cameraCaller);
while (!future.isDone()) {
try {
Thread.sleep(5000);
} catch (Exception ex) { }
}
}
catch (Exception e){ }
}
@Override
protected void onDestroy() {
am.cancel(pi);
unregisterReceiver(br);
super.onDestroy();
}
public void onClickListener(View view){
try{
am.setRepeating(am.ELAPSED_REALTIME,SystemClock.elapsedRealtime(), LOOPTIME, pi);
}
catch (Exception e){ }
}
}
CameraCaller.java:
package myTest.com.test;
import java.util.concurrent.Callable;
public class CameraCaller implements Callable {
private CameraHandler cameraHandler;
public CameraCaller(CameraHandler ch){
cameraHandler = ch;
}
@Override
public Object call() throws Exception {
cameraHandler.takeAPic();
return true;
}
}
CameraHandler.java:
package myTest.com.test;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Environment;
import android.util.Log;
import junit.runner.Version;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class CameraHandler implements Camera.PictureCallback{
private Camera mCamera;
public CameraHandler(){
}
public Boolean takeAPic(){
try{
if (mCamera == null){
mCamera = Camera.open();
mCamera.enableShutterSound(false);
try {
mCamera.setPreviewTexture(new SurfaceTexture(10));
}
catch (IOException e1) {Log.e(Version.id(), e1.getMessage());
}
}
mCamera.startPreview();
mCamera.takePicture(null, null, this);
}
catch (Exception ex){ }
return true;
}
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
} catch (IOException e) { }
try {
Thread.sleep(2000);
}catch (Exception ex){}
}
public static File getOutputMediaFile() {
File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File mediaStorageDir = new File(file, "MyCameraApp");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
return mediaFile;
}
}