0

我正在尝试创建简单的 Android 应用程序,以在接到电话时模拟相机手电筒闪烁。如果用户接听或取消通话,我想停止手电筒闪烁。我正在使用 Handler 和 Runnable 来模拟闪烁,但问题是在用户接听或取消呼叫后我无法停止处理程序。我的源代码:

public class CallReceiver extends BroadcastReceiver 
{
    private static Camera cam = null;
    private Handler handler = new Handler();

    @Override
    public void onReceive(Context context, Intent intent) 
    {
        //device is ringing
        if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING))
        {
            if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) 
            {
                startFlashBlink();
            }
        }
        //call was answered or canceled
        else if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_IDLE) 
            || intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_OFFHOOK))
        {
            stopFlashBlink();
        }
    }

    //for simulating flash blink
    Runnable flashBlinkRunnable = new Runnable()
    {
        public void run() 
        {   
            cam = Camera.open();
            Parameters p = cam.getParameters();
            p.setFlashMode(Parameters.FLASH_MODE_TORCH);
            cam.setParameters(p);
            cam.startPreview();
            cam.stopPreview();
            cam.release();
            cam = null;
            handler.post(flashBlinkRunnable);
        }       
    };

    //start flash blink light
    public void startFlashBlink()
    {
        flashBlinkRunnable.run();
    }

    //stop flash blink light
    public void stopFlashBlink()
    {
        handler.removeCallbacks(flashBlinkRunnable);
        if (cam != null)
        {
            cam.stopPreview();
            cam.release();
            cam = null;
        }
    }
}
4

3 回答 3

1

它不会像这样工作。您的代码存在严重缺陷。问题是你不能用BroadcastReceiver这种方式。从以下文档BroadcastReceiver

BroadcastReceiver 对象仅在调用 onReceive(Context, Intent) 期间有效。一旦您的代码从此函数返回,系统就会认为该对象已完成且不再处于活动状态。

另请注意文档中的应用程序基础知识:

然而,更常见的是,广播接收器只是其他组件的“网关”,旨在完成非常少量的工作。例如,它可能会启动一项服务以根据事件执行某些工作。

因此,您的广播接收器应该启动一项服务并告诉它开始或停止闪烁,而不是在广播接收器本身中执行此操作。

于 2013-01-26T11:47:35.180 回答
0

广播接收器是一种告诉操作系统打算做某事的方法,然后操作系统会找到一个应用程序来解决该意图。在您的情况下,您的所有代码都在广播接收器中。尝试创建一个服务来解决您的问题,而不是尝试在您的广播接收器中解决。

于 2013-01-26T12:06:33.397 回答
0

问题通过服务解决。

public class FlashBlinkService extends Service 
{
    private static Camera cam = null;
    private Handler handler = new Handler();

    @Override
    public IBinder onBind(Intent intent) 
    {
        return null;
    }

    @Override
    public void onCreate()
    {
        super.onCreate();
        startFlashBlink();      
    }

    //for simulating flash blink
    Runnable flashBlinkRunnable = new Runnable()
    {
        public void run() 
        {   
            cam = Camera.open();
            Parameters p = cam.getParameters();
            p.setFlashMode(Parameters.FLASH_MODE_TORCH);
            cam.setParameters(p);
            cam.startPreview();
            cam.stopPreview();
            cam.release();
            cam = null;
            handler.post(flashBlinkRunnable);
        }       
    };

    //start flash blink light
    public void startFlashBlink()
    {
        flashBlinkRunnable.run();
    }

    //stop flash blink light
    public void stopFlashBlink()
    {
        handler.removeCallbacks(flashBlinkRunnable);
        stopCamera(cam);
    }

    //stop camera
    private void stopCamera(Camera cam)
    {
        if (cam != null)
        {
            cam.stopPreview();
            cam.release();
            cam = null;
        }
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        handler.removeCallbacks(flashBlinkRunnable);
        stopCamera(cam);
    }
}


public class CallReceiver extends BroadcastReceiver 
{
    @Override
    public void onReceive(Context context, Intent intent) 
    {
        //device is ringing
        if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING))
        {
            if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) 
            {
                startFlashBlinkService(context);
            }
        }
        //call was answered or canceled
        else if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_IDLE) 
                || intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_OFFHOOK))
        {
            stopFlashBlinkService(context);
        }
    }

    //start flash blink light
    public void startFlashBlinkService(Context context)
    {
        if (!isBlinkServiceRunning(context))
        {
            Intent iService = new Intent(context, FlashBlinkService.class);
            context.startService(iService);
        }
    }

    //stop flash blink light
    public void stopFlashBlinkService(Context context)
    {
        if (isBlinkServiceRunning(context))
        {
            Intent iService = new Intent(context, FlashBlinkService.class);
            context.stopService(iService);
        }
    }


    //check if the blink service is running
    public boolean isBlinkServiceRunning(Context context)
    {
        ActivityManager manager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
        for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE))
        {
            if ("path.to.package.FlashBlinkService".equals(service.service.getClassName()))
            {
                return true;
            }
        }
        return false;
    }
}

(:

于 2013-01-26T19:55:26.820 回答