Android-手电筒应用小思路(一)
来源:互联网 发布:java web分页完整代码 编辑:程序博客网 时间:2024/06/09 20:55
Android 手电筒应用应该算是一个非常简单的应用。所以就不做太多说明。手电筒应用主要知识点就是Camera(硬件)的使用,控制闪光灯来达到手电筒的效果。本人不才,前面有翻译过关于Camera的官方文档,虽然翻译的比较粗糙,但是还是能明白大概意思--- Android官方开发指南-Camera(相机)。
很显然,手电筒应用的主要控制代码如下:
protected void openTorchLight(){ try { if (mCamera == null) { mCamera = Camera.open(); int textureID = 0; mCamera.setPreviewTexture(new SurfaceTexture(textureID)); mCamera.startPreview(); mParameters = mCamera.getParameters(); mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); mCamera.setParameters(mParameters); } } catch (IOException e) { e.printStackTrace(); } } protected void closeTorchLight(){ if(mCamera != null){ mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); mCamera.setParameters(mParameters); mCamera.release(); mCamera = null; } }然后就是在打开手电筒的时候调用openTorchLight()函数,在关闭手电筒的时候调用closeTorchLight()函数,当然 还要在activity的部分生命周期函数中做处理。然而我就思考,这是否就是 最优的方式。所以我自己有两个疑问:
1、Camera 在任何机器上都是秒开起吗?
2、这样打开Camera是在主线程,一单Camera出现问题,打开延迟好多,那主线程是否就会ANR,或者出其它问题。
对于第一个问题,配置高的手机可以接近让camera秒开启。但是配置低的手机,特别是低端手机,打开camera的时候,就能很明显的感觉到打开camera所需要的时间。
所以就有必要很好的控制camera什么时候打开,什么时候关闭。比如在手电筒应用主界面,打开和关闭手电筒,除了第一次要打开camera以外,其它就不用再次打开camera,这样做,就只要在离开手电筒主界面的时候 释放camera就好!
对于第二个问题,在Android中主线程,也就是UI线程。所以还是有一点的风险的。如果读过Android 照相机应用源码的朋友肯定知道,Android源码照相机应用是在一个Thread中打开Camera的。
说太多都不如代码来的实际,所以针对以上两点我直接贴代码(代码只包括.java代码,):
package com.example.torchlight;import android.app.Activity;import android.content.pm.PackageManager;import android.graphics.Point;import android.graphics.SurfaceTexture;import android.graphics.drawable.TransitionDrawable;import android.hardware.Camera;import android.os.Bundle;import android.os.PowerManager;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.view.WindowManager;import android.widget.ImageView;import android.widget.Toast;import java.io.IOException;public class TorchActivity extends Activity implements OnClickListener{ private final static String TAG = "TorchActivity"; private ImageView mImageViewTorchLight; private ImageView mImageViewTorchLightControler; private Camera mCamera; private Camera.Parameters mParameters; private PowerManager.WakeLock mWakeLock; private CameraOpenThread cameraOpenThread; private boolean torchstate; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_torch); torchstate = true; mImageViewTorchLight = (ImageView) findViewById(R.id.imageview_torchlight); mImageViewTorchLightControler = (ImageView) findViewById(R.id.imageview_torchlight_controler); mImageViewTorchLightControler.setOnClickListener(this); //set the flag of this window getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); PowerManager mPowerManager = (PowerManager) this.getSystemService(this.POWER_SERVICE); mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); mWakeLock.acquire(); //set the Rect of controlling to open or close flash light Point mPoint = new Point(); getWindowManager().getDefaultDisplay().getSize(mPoint); ViewGroup.LayoutParams layoutParams= (ViewGroup.LayoutParams)mImageViewTorchLightControler.getLayoutParams(); layoutParams.height = mPoint.y * 3 / 4; layoutParams.width = mPoint.x / 3; mImageViewTorchLightControler.setLayoutParams(layoutParams); if(getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)){ if(mCamera == null){ cameraOpenThread = new CameraOpenThread(); cameraOpenThread.start(); } } mImageViewTorchLight.setTag(true); } protected void onClick_TorchLight(){ if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)){ Toast.makeText(this, this.getResources().getString(R.string.toast_prompt), Toast.LENGTH_LONG).show(); } if(((boolean)mImageViewTorchLight.getTag()) == false){ openTorchLight(); } else{ closeTorchLight(); } } protected void openTorchLight(){ TransitionDrawable mTransitionDrawable = (TransitionDrawable) mImageViewTorchLight.getDrawable(); mTransitionDrawable.reverseTransition(200); mImageViewTorchLight.setTag(true); if(mCamera != null){ mParameters.setFlashMode(mParameters.FLASH_MODE_TORCH); mCamera.setParameters(mParameters); } } protected void closeTorchLight(){ TransitionDrawable mTransitionDrawable = (TransitionDrawable)mImageViewTorchLight.getDrawable(); if(((boolean)mImageViewTorchLight.getTag()) == true){ mTransitionDrawable.startTransition(200); mImageViewTorchLight.setTag(false); if(mCamera != null){ mParameters.setFlashMode(mParameters.FLASH_MODE_OFF); mCamera.setParameters(mParameters); } } } protected void openCamera(){ try { if (mCamera == null) { mCamera = Camera.open(); int textureID = 0; mCamera.setPreviewTexture(new SurfaceTexture(textureID)); mCamera.startPreview(); mParameters = mCamera.getParameters(); mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); mCamera.setParameters(mParameters); } } catch (IOException e) { e.printStackTrace(); } } @Override public void onClick(View v) { if (v.getId() == R.id.imageview_torchlight_controler){ onClick_TorchLight(); } } protected class CameraOpenThread extends Thread{ @Override public void run() { //super.run(); openCamera(); } } protected void releaseCamera(){ if(mCamera != null){ mCamera.release(); mCamera = null; } if(cameraOpenThread != null){ cameraOpenThread.isInterrupted(); cameraOpenThread = null; } if(mWakeLock != null){ mWakeLock.release(); mWakeLock = null; } torchstate = false; } @Override protected void onPause() { super.onPause(); releaseCamera(); } @Override protected void onDestroy() { super.onDestroy(); } @Override protected void onResume() { super.onResume(); if(!torchstate){ if(mCamera == null){ cameraOpenThread = new CameraOpenThread(); cameraOpenThread.start(); torchstate = true; } } }}
说明:
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">1、因为是独立应用,所以在onPause()的时候就要释放掉camera,否则其它应用就不能成功调用camera了。</span>
2、PowerManager mPowerManager = (PowerMananger)this.getSystemService(this.POWER_SERVICE);
mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mWakeLock.acquire();
这段代码是让手机灭屏以后仍保持cpu的运作,否则手机完全进入休眠状态,cpu停止运作,很有可能会导致手机crash 或者重启。因为cpu停止运作就会suspend camera。而此时手电筒仍在后台开启,两者就会产生矛盾。
ps:其它资源和布局文件没贴出来。整个demo我已经上传(http://download.csdn.net/detail/u013656135/8726413 )。
有不足之处请谅解和指点,谢谢!
- Android-手电筒应用小思路(一)
- Android 5.1-手电筒应用小思路(三)
- Andriod-手电筒应用小思路(二)
- Android第一个小程序(手电筒)
- Android 一键开启手电筒
- Android手电筒(闪光灯)
- Android 小应用 (一)
- Android小项目实践之制作手电筒
- Android 七彩手电筒的实现与应用
- <Android 应用 之路> 简易手电筒
- android资料(闪光灯手电筒)
- Android 手电筒(最强适配版)
- android手电筒
- Android手电筒
- Android手电筒
- android 手电筒
- android手电筒
- android手电筒
- Struts2拦截器
- Android Intent Action有什么用?
- 【DP】poj2184
- Linux命令!!!
- mysql中char,varchar与text类型的区别和选用
- Android-手电筒应用小思路(一)
- [leetcode]爬楼梯的递归和非递归方法
- [Xutils]安卓框架的学习之路
- ADT离线安装(Eclipse)
- 【cocos2d-x】构造函数与初始化
- Redis服务的安装使用
- java 内部类
- 联想2015云计算大数据实习生面试题
- Sublime Text3 安装Lua运行环境