初探android之手电筒

来源:互联网 发布:055 台湾知乎 编辑:程序博客网 时间:2024/04/29 17:09

前段时间入了一台android的手机。有闪光灯,平时又有手电的需要。找遍网上手电应用,绝大部分有广告。苦逼 之下,想自己动手写一下。

漫长的痛苦开始了。。。。。

上网搜了很多教程。也许是机型原因。根本无法正常打开。N多次摸索后。终于搞定。直接贴代码吧。相信大家都比较喜欢

先说界面,我放了一个ToggleButton和一个SurfaceView(这个必须有)。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >


    <ToggleButton
        android:id="@+id/torchSwitch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="ON" />


    <TextView
        android:id="@+id/outputText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/sfPreview"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/torchSwitch"
        android:text="" />


    <SurfaceView
        android:id="@+id/sfPreview"
        android:layout_width="101dp"
        android:layout_height="195dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true" />


</RelativeLayout>

第二步,权限

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.aaronwang.torch"
    android:versionCode="1"
    android:versionName="1.0" >


    <uses-sdk
        android:minSdkVersion="10"
        android:targetSdkVersion="15" />
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.FLASHLIGHT"/>
    <uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.flash"/>


    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >"
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />


                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>


</manifest>


    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.FLASHLIGHT"/>
    <uses-feature android:name="android.hardware.camera"/>

这三个必须。

最后 是代码

package com.aaronwang.torch;




import android.os.IBinder;
import android.os.IHardwareService;
import java.io.IOException;
import java.lang.reflect.Method;


import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.ToggleButton;


public class MainActivity extends Activity implements View.OnClickListener, SurfaceHolder.Callback {


boolean hasFlashLight = false;
Camera camera;
SurfaceHolder holder;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        SurfaceView cameraSurface = (SurfaceView)findViewById(R.id.sfPreview);
        ViewGroup.LayoutParams lp = cameraSurface.getLayoutParams();
        lp.width = 1;
        lp.height = 1;
        cameraSurface.setLayoutParams(lp);
        cameraSurface.setZOrderOnTop(true);
        holder = cameraSurface.getHolder();
        holder.addCallback(this);
        holder.setFormat(PixelFormat.TRANSPARENT);
        
              
        View continue_button = this.findViewById(R.id.torchSwitch);
        continue_button.setOnClickListener((OnClickListener) this);
        Context context = this;
        PackageManager pm = context.getPackageManager();
         
        // if device support camera?
        hasFlashLight = pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
        
    }


    public void onClick(View view)
    {
    if (hasFlashLight) 
    {
    outputReslut(" Before view.getId()");
if (R.id.torchSwitch == view.getId()) 
{
ToggleButton button = (ToggleButton)view;
if(button.isChecked())
{
lightOn();
}
else 
{
lightOff();
}


}
}
   
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
    
    /*@Override
    public boolean onTouchEvent(MotionEvent event)
    {
    if (MotionEvent.ACTION_DOWN == event.getAction()) 
    {
    hasFlashLight = !hasFlashLight;
}
    return super.onTouchEvent(event);
    }*/
    
    @Override
    protected void onDestroy()
    {
    if(hasFlashLight)
    {
    lightOff();
    }
    if(null != camera)
    {
    camera.release();
    }
    super.onDestroy();
    }
    
    
    private void outputReslut(String str)
    {
    TextView textView = (TextView)this.findViewById(R.id.outputText);
    textView.setText(textView.getText().toString() + str);
    }
    
    private void lightOn()
    {
    if (null == camera) 
    {
    camera = Camera.open();
}
    Parameters p = camera.getParameters();
    p.setFlashMode(Parameters.FLASH_MODE_TORCH);
    p.setPreviewSize(128, 96);
    camera.setParameters(p);
    try {
camera.setPreviewDisplay(holder);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
    camera.startPreview();
    }
    
    private void lightOff()
    {
    if (null == camera) 
    {
    return;
}
    Parameters p = camera.getParameters();
    p.setFlashMode(Parameters.FLASH_MODE_OFF);
    camera.setParameters(p);
    try {
camera.setPreviewDisplay(null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
    camera.stopPreview();
    camera.release();
    camera = null;
    }


@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}


@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}


@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}


    
}


网上很多代码,没有为camera设置setPreviewDisplay,结果是永远打不开。貌似系统架构原因,flashlight是camera的一部分,只有预览的时候,flashlight才开始工作。而预览必须要一个previewdisplay。否则,preview也是不工作的。。一个怪圈。

另外一个就是网上大家经常说的。android的手电应用会很耗电。其实从代码来看也能明白。虽然你只要打开闪光灯。但相机是在完整的工作,采集,预览。这些是大头。而且,打开闪光灯过程会比较长,1秒左右。

        SurfaceView cameraSurface = (SurfaceView)findViewById(R.id.sfPreview);
        ViewGroup.LayoutParams lp = cameraSurface.getLayoutParams();
        lp.width = 1;
        lp.height = 1;
        cameraSurface.setLayoutParams(lp);
        cameraSurface.setZOrderOnTop(true);
        holder = cameraSurface.getHolder();
        holder.addCallback(this);
        holder.setFormat(PixelFormat.TRANSPARENT);


这段代码。

lp.width = 1;
        lp.height = 1;
        cameraSurface.setLayoutParams(lp);

这个是改变预览view的大小。不能是0.至少1.然后预览界面就从屏幕上消失了。

cameraSurface.setZOrderOnTop(true);

holder.setFormat(PixelFormat.TRANSPARENT);

这两句实现surfaceview初始时透明效果,不然初始就是一黑屏。


网上还有一种方法是使用iHardwareService接口,在的我i9250上使用。无效。放弃了。

只是一次尝试,代码可能不怎么规整。别介意。

原创粉丝点击