【问题标题】:Turn flashlight off when phone stops ringing?电话停止响时关闭手电筒?
【发布时间】:2013-02-08 19:08:08
【问题描述】:

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

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

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

【问题讨论】:

    标签: android phone-call flashlight


    【解决方案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() 中添加用于释放相机的逻辑,以确保正确释放相机。甚至可能在固定的最长持续时间后释放它,以防止它长时间停留。

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

    【讨论】:

    • 是的,这正是我目前正在做的事情。但是当 BroadcastReceiver 被触发时,它只在 onReceive 方法的持续时间内存在(所以在响铃开始时它会触发手电筒,然后整个实例与我的相机参考一起死亡),下次触发时,会创建一个新对象(它也创建了新的相机对象,因为相机正被先前的死相机对象使用,所以无法访问相机)。
    • 这就是你问题的根源。您需要将 BroadcastReceiver 封装在 Service 中。
    • 是的,你是对的。我还通过实施服务解决了这个问题。
    【解决方案2】:

    感谢 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();
    }   
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-12
      • 2014-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多