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

Android Studio 学习实例记录-手电筒_第1张图片

Next,

Android Studio 学习实例记录-手电筒_第2张图片


next,选择empty activity

Android Studio 学习实例记录-手电筒_第3张图片

Next,

Android Studio 学习实例记录-手电筒_第4张图片

点击Finish,工程建立完成


二、布局页面

进入app-res-layout-activity_main.xml文件

Android Studio 学习实例记录-手电筒_第5张图片

选择可视界面

Android Studio 学习实例记录-手电筒_第6张图片

当时我点击了Design之后,可视界面里面没有任何显示,这个问题和API level有关,解决方法参考我另外一篇博客:

https://blog.csdn.net/ficey/article/details/80351933

可视界面能正常显示之后,删除默认的textview控件,右键删除

Android Studio 学习实例记录-手电筒_第7张图片

然后添加一个button控件和一个toggle button控件,直接选中button和toggle butto拖拽到图上就行

Android Studio 学习实例记录-手电筒_第8张图片

注意,这两个控件拖拽到图上之后,

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工具

Android Studio 学习实例记录-手电筒_第9张图片

然后就可以看到红色感叹号的标注消失了,修改成功。

Android Studio 学习实例记录-手电筒_第10张图片


三、在MainActivity.java中添加源码

按照文章开头提到的博客地址,将源码添加到MainActivity.java中


四、添加权限

在AndroidManifest.xml添加调用摄像头的权限:



    
    
    
    
    

Android Studio 学习实例记录-手电筒_第11张图片


五、设置apk的名字和显示的图片

apk名字:在app-res-values-strings.xml文件中,红框标注的地方修改为我们apk的名字,如手电筒。

Android Studio 学习实例记录-手电筒_第12张图片

apk图片:在app-res-drawable里,右键点击drawable,选择New-Image Asset

Android Studio 学习实例记录-手电筒_第13张图片

在弹出的窗口里,在Path里选择自己所在图片的路径,一直next,直到Finish。(我在这里没有替换图片,直接用的默认图片,所以没有操作这一步)

Android Studio 学习实例记录-手电筒_第14张图片


六、编译程序并安装到手机

使用USB线将手机连上电脑,打开手机的USB调试,然后点击这个绿色的三角形,程序会编译并且自动将apk安装到手机,有的手机上可能会弹出一个是否安装的提示,点击确定安装,我的手机没有提示,直接就可以安装了

Android Studio 学习实例记录-手电筒_第15张图片


七、调试

以为到第六步就结束了??并没有,如果代码ok的话,那按照第六步就可以完成这次实践了。但是在编译的时候报错了!!!!

来,一起回顾一下这次遇到的问题

1、AAPT2 error:check logs for details

关于这个问题的解决方法请参考我的另外一篇博客:

https://blog.csdn.net/ficey/article/details/80496660

2、找不到符号,变量id,位置:类R

Android Studio 学习实例记录-手电筒_第16张图片

双击报错跳转到代码里报错的位置,分别是这三句:

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

Android Studio 学习实例记录-手电筒_第17张图片

所以对应的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

Android Studio 学习实例记录-手电筒_第18张图片

报错的语句是:

            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: 16199
05-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 attached
05-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 attached
05-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: 9395
05-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.ToggleButton
05-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.ToggleButton
05-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控件,最后的结果就是上面那个按钮是没有用的,只有下面那个按钮可以控制开关,就造成了界面按键的多余,这个问题是根据代码编写来看的,之后还需要再研究一下代码。。。

Android Studio 学习实例记录-手电筒_第19张图片


十、各个文件源码

activity_main.xml




    

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



    
    
    
    
    

    
        
            
                

                
            
        
    


你可能感兴趣的:(Android,Studio)