Android Studio 学习实例记录-手电筒
Android Studio 学习实例记录-手电筒
刚安装好Android Studio3.1.2,上网搜了一个实例进行实践学习,仅用这篇文章来记录学习过程
MainActivity.java的源码来自博客:
https://blog.csdn.net/Frakie_Kwok/article/details/66973695
一、在Android studio上建立一个新的工程
File-New-New Project
Next,
next,选择empty activity
Next,
点击Finish,工程建立完成
二、布局页面
进入app-res-layout-activity_main.xml文件
选择可视界面
当时我点击了Design之后,可视界面里面没有任何显示,这个问题和API level有关,解决方法参考我另外一篇博客:
https://blog.csdn.net/ficey/article/details/80351933
可视界面能正常显示之后,删除默认的textview控件,右键删除
然后添加一个button控件和一个toggle button控件,直接选中button和toggle butto拖拽到图上就行
注意,这两个控件拖拽到图上之后,
button和toggle button后面的标注会是一个红色的感叹号,鼠标放在感叹号上它会提示说:This view is not constrained, it only has designtime positions, so it will jump to (0,0)...
这里报错的意思是说:这个view没有被约束,他只有设计时的位置,所以他将会跳到(0,0),除非你添加约束。也就是说组件没有锁定,可能会导致重合。所有的组件都不重叠
button控件后面标注为红色感叹号,控件提示view is not constrained...的解决方法:
1、对于Android studio3.0以前的版本,在Design中,对着活动点击右键,选择Constraint Layout----->Infer Constraints
2、对于Android studio 3.1.2版本,点击图上的这个魔法棒,也就是infer constraints工具
然后就可以看到红色感叹号的标注消失了,修改成功。
三、在MainActivity.java中添加源码
按照文章开头提到的博客地址,将源码添加到MainActivity.java中
四、添加权限
在AndroidManifest.xml添加调用摄像头的权限:
<?xml version="1.0" encoding="utf-8"?>
五、设置apk的名字和显示的图片
apk名字:在app-res-values-strings.xml文件中,红框标注的地方修改为我们apk的名字,如手电筒。
apk图片:在app-res-drawable里,右键点击drawable,选择New-Image Asset
在弹出的窗口里,在Path里选择自己所在图片的路径,一直next,直到Finish。(我在这里没有替换图片,直接用的默认图片,所以没有操作这一步)
六、编译程序并安装到手机
使用USB线将手机连上电脑,打开手机的USB调试,然后点击这个绿色的三角形,程序会编译并且自动将apk安装到手机,有的手机上可能会弹出一个是否安装的提示,点击确定安装,我的手机没有提示,直接就可以安装了
七、调试
以为到第六步就结束了??并没有,如果代码ok的话,那按照第六步就可以完成这次实践了。但是在编译的时候报错了!!!!
来,一起回顾一下这次遇到的问题
1、AAPT2 error:check logs for details
关于这个问题的解决方法请参考我的另外一篇博客:
https://blog.csdn.net/ficey/article/details/80496660
2、找不到符号,变量id,位置:类R
双击报错跳转到代码里报错的位置,分别是这三句:
Button open_btn = (Button) findViewById(R.id.open_btn);Button close_btn = (Button) findViewById(R.id.close_btn);ToggleButton toggle_btn = (ToggleButton) findViewById(R.id.toggle_btn);
查看activity_main.xml文件,可以看到button id斜线后面跟的分别是button和toggleButton
所以对应的R.id.后面要跟对应的符号,修改为:
Button open_btn = (Button)findViewById(R.id.button); Button close_btn = (Button) findViewById(R.id.button); ToggleButton toggle_btn = (ToggleButton)findViewById(R.id.toggleButton);
3、匿名...不是抽象的,并且未覆盖OnCheckedChangeListener中的抽象方法onCheckedChanged
报错的语句是:
ToggleButton toggle_btn = (ToggleButton)findViewById(R.id.toggleButton); toggle_btn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){ //@Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked){ try{ manager.setTorchMode("0",isChecked); }catch (CameraAccessException e){ e.printStackTrace(); } } });
遇到这个问题的时候上网搜索了相关的解答,网上的方法都试了一下,对于我的代码没有效果,最后是重新拼写了代码就正常了,可能是拼写错误,没有注意到
4、手电筒无响应,停止运行
上面的三个问题解决之后,再编译就可以编译成功并且成功安装到手机上了,有一丢丢小开心~~~,在手机上点击这个应用打开,提示手电筒无响应,停止运行,什么鬼。。。。。。
继续debug。。。。。。
手机连上电脑,使用adb抓取log
抓取log命令:
adb logcat -s "AndroidRuntime"
1)查看打印出来的log信息:
05-29 17:10:45.127 16199 16199 E AndroidRuntime: Process: com.example.wd.flashlight, PID: 1619905-29 17:10:45.127 16199 16199 E AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.wd.flashlight/com.example.wd.flashlight.MainActivity}: java.lang.IllegalStateException: Already attached05-29 17:10:45.127 16199 16199 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2768)05-29 17:10:45.127 16199 16199 E AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2833)05-29 17:10:45.127 16199 16199 E AndroidRuntime: at android.app.ActivityThread.-wrap12(ActivityThread.java)05-29 17:10:45.127 16199 16199 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1561)05-29 17:10:45.127 16199 16199 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:110)05-29 17:10:45.127 16199 16199 E AndroidRuntime: at android.os.Looper.loop(Looper.java:203)05-29 17:10:45.127 16199 16199 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6354)05-29 17:10:45.127 16199 16199 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)05-29 17:10:45.127 16199 16199 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1111)05-29 17:10:45.127 16199 16199 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:972)05-29 17:10:45.127 16199 16199 E AndroidRuntime: Caused by: java.lang.IllegalStateException: Already attached05-29 17:10:45.127 16199 16199 E AndroidRuntime: at android.support.v4.app.FragmentManagerImpl.attachController(FragmentManager.java:2871)05-29 17:10:45.127 16199 16199 E AndroidRuntime: at android.support.v4.app.FragmentController.attachHost(FragmentController.java:104)05-29 17:10:45.127 16199 16199 E AndroidRuntime: at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:317)05-29 17:10:45.127 16199 16199 E AndroidRuntime: at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:85)05-29 17:10:45.127 16199 16199 E AndroidRuntime: at com.example.wd.flashlight.MainActivity.onCreate(MainActivity.java:27)05-29 17:10:45.127 16199 16199 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:6694)05-29 17:10:45.127 16199 16199 E AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1121)05-29 17:10:45.127 16199 16199 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2721)05-29 17:10:45.127 16199 16199 E AndroidRuntime: ... 9 more
看到
Caused by: java.lang.IllegalStateException: Already attached
AndroidRuntime: at com.example.wd.flashlight.MainActivity.onCreate(MainActivity.java:27)
在MainActivity.java文件中找到报错的位置:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); super.onCreate(savedInstanceState);
这里onCreate调用了两次,修改为:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //super.onCreate(savedInstanceState);
2)重新编译安装,仍然报无响应,停止运行,继续使用adb抓log
查看log打印信息:
05-30 11:21:54.508 9395 9395 E AndroidRuntime: Process: com.example.wd.flashlight, PID: 939505-30 11:21:54.508 9395 9395 E AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.wd.flashlight/com.example.wd.flashlight.MainActivity}: java.lang.ClassCastException: android.widget.Button cannot be cast to android.widget.ToggleButton05-30 11:21:54.508 9395 9395 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2768)05-30 11:21:54.508 9395 9395 E AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2833)05-30 11:21:54.508 9395 9395 E AndroidRuntime: at android.app.ActivityThread.-wrap12(ActivityThread.java)05-30 11:21:54.508 9395 9395 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1561)05-30 11:21:54.508 9395 9395 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:110)05-30 11:21:54.508 9395 9395 E AndroidRuntime: at android.os.Looper.loop(Looper.java:203)05-30 11:21:54.508 9395 9395 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6354)05-30 11:21:54.508 9395 9395 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)05-30 11:21:54.508 9395 9395 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1111)05-30 11:21:54.508 9395 9395 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:972)05-30 11:21:54.508 9395 9395 E AndroidRuntime: Caused by: java.lang.ClassCastException: android.widget.Button cannot be cast to android.widget.ToggleButton05-30 11:21:54.508 9395 9395 E AndroidRuntime: at com.example.wd.flashlight.MainActivity.onCreate(MainActivity.java:57)05-30 11:21:54.508 9395 9395 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:6694)05-30 11:21:54.508 9395 9395 E AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1121)05-30 11:21:54.508 9395 9395 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2721)05-30 11:21:54.508 9395 9395 E AndroidRuntime: ... 9 more
Caused by: java.lang.ClassCastException: android.widget.Button cannot be cast to android.widget.ToggleButton
at com.example.wd.flashlight.MainActivity.onCreate(MainActivity.java:57)
组件问题,在第二步布局页面的时候,其实我只添加了一个button组件,没有添加toggleButton组件,然后在这里报出错误之后,才按照第二步的操作添加了一个toggleButton组件,所以:
- 如果按照第二步操作在最开始就添加了button和toggleButton组件的话,就不会出现现在这个组件问题
- 如果第二步只添加了button组件的话,那么在这里就会报出组件问题,解决方法就是在layout-activity_main.xml文件的可视界面中添加一个toggleButton组件就可以了
5、点击开关按键打不开闪光灯
上面问题解决之后,程序可以编译成功,安装在手机之后也可以进入apk了,但是点击按钮想要打开闪光灯的时候又失败了,点击按钮无反应。。。
回到代码查看:
ToggleButton toggle_btn = (ToggleButton)findViewById(R.id.toggleButton); toggle_btn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){ //@Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked){ try{ manager.setTorchMode("1",isChecked); }catch (CameraAccessException e){ e.printStackTrace(); } } });
将 manager.setTorchMode("1",isChecked);
改为:
manager.setTorchMode("0",isChecked);
八、成功
重新编译安装,打开手电筒app,点击按钮,这个时候发现我们可以正常的打开关闭闪光灯了
九、后记
虽然apk可以正常使用了,但是这里依然留下了一个问题,本来最开始在页面布局的时候,只打算添加一个button控制开关就可以了,但是在后来的调试过程中根据代码又添加了一个toggleButton控件,最后的结果就是上面那个按钮是没有用的,只有下面那个按钮可以控制开关,就造成了界面按键的多余,这个问题是根据代码编写来看的,之后还需要再研究一下代码。。。
十、各个文件源码
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
build.gradle(Module:app)
apply plugin: 'com.android.application'android { compileSdkVersion 25 defaultConfig { applicationId "com.example.wd.flashlight" minSdkVersion 15 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }}dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'com.android.support:appcompat-v7:25.1.1' implementation 'com.android.support.constraint:constraint-layout:1.1.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'}
MainActivity.java
package com.example.wd.flashlight;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.app.Activity;import android.content.Context;import android.hardware.Camera;import android.hardware.camera2.CameraAccessException;import android.hardware.camera2.CameraManager;import android.os.Build;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.CompoundButton;import android.widget.ToggleButton;//public class MainActivity extends AppCompatActivity {public class MainActivity extends Activity { private CameraManager manager; private Camera camera = null; private static boolean kaiguan = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //super.onCreate(savedInstanceState); manager = (CameraManager)getSystemService(Context.CAMERA_SERVICE); try{ String [] cameraList = manager.getCameraIdList(); for (String str:cameraList ) { Log.d("List", str); } }catch (CameraAccessException e){ Log.e("error",e.getMessage()); } Button open_btn = (Button)findViewById(R.id.button); open_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { try{ manager.setTorchMode("0",true); }catch(CameraAccessException e){ e.printStackTrace(); } } }); Button close_btn = (Button) findViewById(R.id.button); close_btn.setOnClickListener(closeOnClickListener); ToggleButton toggle_btn = (ToggleButton)findViewById(R.id.toggleButton); toggle_btn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){ //@Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked){ try{ manager.setTorchMode("0",isChecked); }catch (CameraAccessException e){ e.printStackTrace(); } } }); } private View.OnClickListener closeOnClickListener = new View.OnClickListener() { @Override public void onClick(View v) { try{ manager.setTorchMode("0",false); }catch (CameraAccessException e){ e.printStackTrace(); } } }; }
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
更多相关文章
- android 背景图片设置
- 关于android中的EditView,TextView的图片问题
- 阅读《Android 从入门到精通》(7)——图片按钮
- Android 分享文本和图片
- [转]android animation的应用实例
- android从sdcard加载.9.png图片
- 剪切图片-扩展android 选择图片(从手机照相机或手机图片)
- Android WebView 实例