我正在制作一个应用程序,当手机开始响铃时打开手电筒,并在手机停止响铃时关闭手电筒。问题是当手机开始响铃时相机会被锁定,并且对象的引用会丢失,因此我不知道如何在以后关闭它。
我正在使用BroadcastReceiver打开/关闭它:
@Override
public void onReceive(Context context, Intent intent) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (TelephonyManager.EXTRA_STATE_RINGING.equals(state)) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {
cam = Camera.open();
Parameters p = cam.getParameters();
p.setFlashMode(Parameters.FLASH_MODE_TORCH);
cam.setParameters(p);
cam.startPreview();
}
}
if (TelephonyManager.EXTRA_STATE_IDLE.equals(state)) {
cam = Camera.open();
cam.stopPreview();
cam.release();
}
}
有谁知道如何保持对相机对象或任何变通方法的引用?我想到了使用服务,但市场上的其他应用程序似乎并没有使用服务来完成相同的任务。
答案 0 :(得分:1)
根据the documentation on controlling the camera,您应该在类中为Camera对象保留一个引用,并在完成后释放它。他们通过字段寻址对象来做到这一点。
您可以通过执行相同操作来解决问题:
public TelephonyReceiver extends BroadcastReceiver {
Camera mCamera;
@Override
public void onReceive(Context context, Intent intent) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (TelephonyManager.EXTRA_STATE_RINGING.equals(state)) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {
mCamera = Camera.open();
Parameters p = mCamera.getParameters();
p.setFlashMode(Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(p);
mCamera.startPreview();
}
}
if (TelephonyManager.EXTRA_STATE_IDLE.equals(state) && mCamera != null) {
mCamera.stopPreview();
mCamera.release();
// Make sure to clear the reference, otherwise we might attempt to
// release the camera a second time
mCamera = null;
}
}
}
如果您是从服务中执行此操作,我建议您还添加用于在onDestroy()
中释放相机的逻辑,以确保相机已正确释放。也许甚至可以在固定的最长持续时间后释放它,以防止它长时间停留。
听起来像一个漂亮的应用程序!
答案 1 :(得分:1)
感谢Paul Lammertsma的建议。 我通过添加保存相机对象的服务解决了这个问题。
收件人代码:
public class Receiver extends BroadcastReceiver {
SharedPreferences prefs = null;
boolean enabled = false;
@Override
public void onReceive(Context context, Intent intent) {
prefs = PreferenceManager.getDefaultSharedPreferences(context);
AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
int ringState = am.getRingerMode();
enabled = prefs.getBoolean("full", false);
if (!enabled || ringState != AudioManager.RINGER_MODE_NORMAL) {
return;
}
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (TelephonyManager.EXTRA_STATE_RINGING.equals(state) ||
TelephonyManager.EXTRA_STATE_IDLE.equals(state) ||
TelephonyManager.EXTRA_STATE_OFFHOOK.equals(state)) {
context.startService(new Intent(context, MyService.class).putExtra("state", state));
}
}
}
服务代码:
public class MyService extends Service {
Camera cam = null;
boolean offhook = false;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String state = intent.getStringExtra("state");
if (TelephonyManager.EXTRA_STATE_RINGING.equals(state)) {
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH) && !offhook) {
cam = Camera.open();
Parameters p = cam.getParameters();
p.setFlashMode(Parameters.FLASH_MODE_TORCH);
cam.setParameters(p);
}
}
if (TelephonyManager.EXTRA_STATE_IDLE.equals(state)) {
if (!offhook) {
if (cam != null) {
cam.release();
cam = null;
}
this.stopSelf();
} else {
offhook = false;
}
}
if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(state)) {
offhook = true;
if (cam != null) {
cam.stopPreview();
cam.release();
cam = null;
}
this.stopSelf();
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
if (cam != null) {
cam.release();
cam = null;
}
super.onDestroy();
}
}