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"?>                                                                                                    

更多相关文章

  1. Android(安卓)Studio 配置 OpenCV for Android
  2. Android, property 添加写权限。
  3. 解决Android(安卓)Studio Fetching Android(安卓)SDK component
  4. Android(安卓)菜单(OptionMenu)大全
  5. Android安装环境搭建
  6. Android模拟点击的四种方式
  7. h5页面点击按钮,触发手机自带的发短信
  8. Android(安卓)ScrollView的使用
  9. Android(安卓)开源组件无限循环ViewPager

随机推荐

  1. android的Material Design点击涟漪效果
  2. android ListView 显示在底部
  3. SDK下载地址
  4. android 图片处理
  5. Android(安卓)basic1
  6. Android7.0中文API -- SeekBar
  7. Android圆型头像实现
  8. 【Android】自定义 Tabhost
  9. Android(安卓)SystemClock
  10. Android(安卓)basic1