torch
在本文中,我们要描述如何在Android中创建简单的割炬应用程序。 这是一个很好的例子,因为我们可以探索一些有关Android Camera的Android API。 我们将使用Android Studio作为IDE来开发应用程序。 这个应用程序不仅会使用闪光灯,而且我们也可以在可以更改频率的地方实现频闪灯。 我们可以发现如何使用一些基本的UI组件,例如ToggleButton和SeekBar 。 我们想要获得一个看起来像这样的应用程序:
Android App布局
我们要做的第一件事是定义应用程序布局。 如果您发现使用Android Studio时,它会在布局目录下创建一个名为fragment_main.xml的文件。 我们必须对其进行编辑并在此处实现我们的布局。 为了使事情变得简单,我们可以假设只有ToggleButton可以打开和关闭闪光灯:
<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"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.survivingwithandroid.tourch.MainActivity$PlaceholderFragment">
<TextView
android:text="@string/app_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:id="@+id/textView" />
<TextView
android:text="@string/torchon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView"
android:layout_centerHorizontal="true"
android:layout_marginTop="43dp" />
<ToggleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="torchonoff"
android:id="@+id/toggleButton"
android:layout_below="@+id/textView"
android:layout_centerHorizontal="true"
android:layout_marginTop="15dp"
/>
...
</RelativeLayout>
在IDE预览中,结果如下:
处理相机闪光灯开和关
现在我们必须处理ToggleButton事件。 查看由我们的IDE生成的源代码,我们有一个名为MainActivity.java的类,还有另一个内部类用于管理名为PlaceHolderFragment的片段。 我们记得片段是一个复杂的生命周期,当片段移动到其生命周期中的不同状态时,会反映在系统调用的某些回调方法中。 我们可以使用onActivityCreated来获取对智能手机Camera的引用,并获取is参数,因此我们具有:
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
try {
Log.d("TORCH", "Check cam");
// Get CAM reference
cam = Camera.open();
camParams = cam.getParameters();
cam.startPreview();
hasCam = true;
Log.d("TORCH", "HAS CAM ["+hasCam+"]");
}
catch(Throwable t) {
t.printStackTrace();
}
}
在第7行,我们打开了到Camera的连接,在第8行,我们得到了默认参数,稍后我们将使用它们来打开和关闭闪光灯。 在第9行的结尾,我们调用startPreview()开始捕获预览帧。
现在我们准备处理ToggleButton事件并根据触发的事件更改闪光灯。 我们可以在onCreateView方法,当操作系统为片段提供设置其布局的机会时调用该方法:
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
// Let's get the reference to the toggle
ToggleButton tBtn = (ToggleButton) rootView.findViewById(R.id.toggleButton);
tBtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.d("TORCH", "IS CHECKED ["+isChecked+"]");
turnOnOff(isChecked);
}
});
在第1行,我们只需对布局进行充气,并使用其ID查找ToggleButton。 然后,当用户更改状态时处理事件,并调用turnOnOff方法:
private void turnOnOff(boolean on) {
if (on)
camParams.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
if (!on)
camParams.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
cam.setParameters(camParams);
cam.startPreview();
}
在第3行,我们使用Camera参数通过Camera.Parameters.FLASH_MODE_TORCH
和Camera.Parameters.FLASH_MODE_OFF.
打开和关闭闪光灯Camera.Parameters.FLASH_MODE_OFF.
Android Manifest.xml
为了使我们的应用程序能够使用闪光灯,我们必须修改Android Manifest.xml,以便我们可以声明要使用闪光灯:我们必须添加:
<uses-permission android:name="android.permission.CAMERA"/>
下一步是过滤可以在Google Play中安装我们的应用的设备。 我们希望只有具有闪光灯的设备才能安装该应用程序,因此我们必须将此行添加到Manifest.xml中:
<uses-feature android:name="android.hardware.camera"/>
实施频闪灯
最后一步是实施频闪灯。 我们希望用户可以选择光频率,以便我们使用SeekBar。 在片段布局中,我们将添加:
<TextView
android:text="@string/freq"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView1"
android:layout_centerHorizontal="true"
android:layout_marginTop="43dp"
android:layout_below="@id/toggleButton"/>
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/seekBar"
android:layout_below="@+id/textView1"
android:layout_centerHorizontal="true"
android:layout_marginTop="25dp"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:max="100"/>
并在用户移动进度级别时进行处理。 正如我们之前对ToggleButton所做的那样,我们在onCreateView方法中实现了一个事件侦听器:
// Seekbar
SeekBar skBar = (SeekBar) rootView.findViewById(R.id.seekBar);
skBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
freq = progress;
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
在第5行,我们得到当前水平。 我们必须修改turnOnOff方法,因为如果要频闪灯,我们必须启动一个可以打开和关闭灯的线程:
private void turnOnOff(boolean on) {
if (on) {
if (freq != 0) {
sr = new StroboRunner();
sr.freq = freq;
t = new Thread(sr);
t.start();
return ;
}
else
camParams.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
}
if (!on) {
if (t != null) {
sr.stopRunning = true;
t = null;
return ;
}
else
camParams.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
}
cam.setParameters(camParams);
cam.startPreview();
}
当用户打开ToggleButton且频率不为零时,我们启动一个新的Thread,它将简单地打开和关闭灯光:
private class StroboRunner implements Runnable {
int freq;
boolean stopRunning = false;
@Override
public void run() {
Camera.Parameters paramsOn = PlaceholderFragment.this.cam.getParameters();
Camera.Parameters paramsOff = PlaceholderFragment.this.camParams;
paramsOn.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
paramsOff.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
try {
while (!stopRunning) {
PlaceholderFragment.this.cam.setParameters(paramsOn);
PlaceholderFragment.this.cam.startPreview();
// We make the thread sleeping
Thread.sleep(100 - freq);
PlaceholderFragment.this.cam.setParameters(paramsOff);
PlaceholderFragment.this.cam.startPreview();
Thread.sleep(freq);
}
}
catch(Throwable t) {}
}
}
- 源代码将在@github上提供。
翻译自: https://www.javacodegeeks.com/2014/02/android-torch-app-with-stroboscopic-light-tutorial.html
torch