手机停止响铃时关闭手电筒?

时间:2013-02-08 19:08:09

标签: android phone-call flashlight

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

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

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

2 个答案:

答案 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();
}   
}