2

我正在制作一个应用程序,它可以在手机开始响铃时打开手电筒,并在它停止响铃时将其关闭。问题是当电话开始响铃时相机被锁定,并且对它的对象引用丢失了,所以我不知道以后如何将其关闭。

我正在使用 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();
    }
}

有谁知道如何保留对相机对象的引用或任何解决方法?我想到了使用服务,但市场上的其他应用程序似乎没有使用服务来完成相同的任务。

4

2 回答 2

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();
}   
}
于 2013-02-10T23:14:16.560 回答
1

根据有关控制相机的文档,您应该在类中保存对 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()以确保正确释放相机。甚至可能在固定的最长持续时间后释放它,以防止它长时间停留。

听起来像一个漂亮的应用程序!

于 2013-02-08T22:08:05.323 回答