Android学习笔记--[1]硬件访问服务_基础知识


1、硬件访问服务_基础知识

1.1编写第1个Android应用程序实现按钮和复选框

应用程序——》硬件访问服务——》JNI——》硬件
对于不同的硬件,构建不同的硬件访问服务。

效果如下:
在这里插入图片描述

//MainActivity.java
package com.example.helloword;

import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.os.Bundle;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    //定义一个Button类的私有对象指向按钮
 private Button button = null;
    private boolean ledon = false;
    private CheckBox checkBoxLED1 = null;
    private CheckBox checkBoxLED2 = null;
    private CheckBox checkBoxLED3 = null;
    private CheckBox checkBoxLED4 = null;

    @Override
 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = (Button) findViewById(R.id.BUTTON);
        checkBoxLED1 = (CheckBox) findViewById(R.id.LED1);
        checkBoxLED2 = (CheckBox) findViewById(R.id.LED2);
        checkBoxLED3 = (CheckBox) findViewById(R.id.LED3);
        checkBoxLED4 = (CheckBox) findViewById(R.id.LED4);
        //设置一个监听函数
 button.setOnClickListener(new View.OnClickListener() {
            @Override
 public void onClick(View view) {
                ledon = !ledon;
                if(ledon) {
                    button.setText("ALL ON");
                    checkBoxLED1.setChecked(true);
                    checkBoxLED2.setChecked(true);
                    checkBoxLED3.setChecked(true);
                    checkBoxLED4.setChecked(true);
                } else {
                    button.setText("ALL OFF");
                    checkBoxLED1.setChecked(false);
                    checkBoxLED2.setChecked(false);
                    checkBoxLED3.setChecked(false);
                    checkBoxLED4.setChecked(false);
                }
            }
        });
    }

    public void onCheckboxClicked (View view){
        boolean checked =((CheckBox) view).isChecked();

        switch (view.getId()) {
            case R.id.LED1:
                if (checked) {
                    Toast.makeText(getApplicationContext(),"LED1 ON",Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(getApplicationContext(),"LED1 off",Toast.LENGTH_SHORT).show();
                }
            case R.id.LED2:
                if (checked) {
                    Toast.makeText(getApplicationContext(),"LED2 ON",Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(getApplicationContext(),"LED2 off",Toast.LENGTH_SHORT).show();
                }
            case R.id.LED3:
                if (checked) {
                    Toast.makeText(getApplicationContext(),"LED3 ON",Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(getApplicationContext(),"LED3 off",Toast.LENGTH_SHORT).show();
                }
            case R.id.LED4:
                if (checked) {
                    Toast.makeText(getApplicationContext(),"LED4 ON",Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(getApplicationContext(),"LED4 off",Toast.LENGTH_SHORT).show();
                }

        }
    }
}
acatity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 tools:context=".MainActivity"
 android:orientation="vertical">

<!-- TextView 首字母大写,是View的直接子类-->
 <TextView
 		android:layout_width="wrap_content"
 		android:layout_height="wrap_content"
 		app:layout_constraintBottom_toBottomOf="parent"
 		app:layout_constraintEnd_toEndOf="parent"
		app:layout_constraintStart_toStartOf="parent"
		app:layout_constraintTop_toTopOf="parent" />
<!-- 双击ButtonShift + F1 会打开一个网页 查看该类方法,-->
 <!--Button指定一个ID -->
 <Button
 	android:id="@+id/BUTTON"
 	android:layout_width="match_parent"
 	android:layout_height="wrap_content"
 	android:text="ALL ON"/>
    <CheckBox
 		android:id="@+id/LED1"
 		android:layout_width="fill_parent"
 		android:layout_height="wrap_content"
 		android:text="LED1"
 		android:onClick="onCheckboxClicked"/>
   <CheckBox
 	android:id="@+id/LED2"
 	android:layout_width="fill_parent"
 	android:layout_height="wrap_content"
 	android:onClick="onCheckboxClicked"
 	android:text="LED2"/>
  <CheckBox
 android:id="@+id/LED3"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:onClick="onCheckboxClicked"
 android:text="LED3"/>
    <CheckBox
 android:id="@+id/LED4"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:onClick="onCheckboxClicked"
 android:text="LED4"/>

</LinearLayout>

1.2 Android -> JNI -> C库(so)

应用程序——》硬件访问服务——》JNI——》硬件

JNI: Java Native Interface的缩写,通过使用 Java本地接口书写程序,可以确保代码在不同的平台上方便移植。

在Android app里面,用JNI访问C库。

              ctrl函数

JNI ---- open函数

              close函数

HardControl.java《——》hardcontrol.c
声明native方法 ------------- 实现对应的函数

在java里面定义Hardctrl.java,声明上面三个native 方法,同样在C库里面有一个hardcontrol.c实现其对应的三个函数。

在这里插入图片描述
//arm-linux-gnueabihf-gcc-7 -fPIC -shared hardcontrol.c -o libhardcontrol.so -I /usr/lib/jvm/java-8-openjdk-amd64/include/ -I /usr/lib/jvm/java-8-openjdk-amd64/include/linux/

java.lang.UnsatisfiedLinkError: dlopen failed: “/data/app/~~BUfUpuKYSPZ5ytbSyg58zw==/com.example.helloword-Jay3NtGP7_dKfGv99DKkNQ==/base.apk!/lib/arm64-v8a/libhardcontrol.so” is 32-bit instead of 64-bit

  • 关于Android Studio导入第三方.so库,找不到so库以及找不到so库中方法的问题 :https://www.likecs.com/show-203976586.html

  • ubuntu16.04 安装交叉编译工具aarch64-linux-gnu-gccg++ https://blog.csdn.net/web13985085406/article/details/124090327

  • 交叉编译工具链-宿主机linux ubuntu 64位-目标机ARMv8 aarch64/系统ubuntu64位 https://blog.csdn.net/Star__dust/article/details/102842001

03-30 10:23:33.799 16624 16624 V ViewRootImpl: title=com.example.helloword/com.example.helloword.MainActivity enqueue motion: MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=812.0, y[0]=228.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=50160542, downTime=50160542, deviceId=2, source=0x1002, displayId=0, eventId=143227192 }

03-30 10:23:33.901 16624 16624 V ViewRootImpl: title=com.example.helloword/com.example.helloword.MainActivity enqueue motion: MotionEvent { action=ACTION_UP, actionButton=0, id[0]=0, x[0]=812.0, y[0]=228.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=50160671, downTime=50160542, deviceId=2, source=0x1002, displayId=0, eventId=365745191 }
sudo apt-get install g++-aarch64-linux-gnu

sudo apt-get install gcc-aarch64-linux-gnu

aarch64-linux-gnu-gcc  -fPIC -shared hardcontrol.c -o libhardcontrol.so -I /usr/lib/jvm/java-8-openjdk-amd64/include/ -I /usr/lib/jvm/java-8-openjdk-amd64/include/linux/ -nostdlib /home/xx/disk2/xxx/qssi/prebuilts/runtime/mainline/runtime/sdk/android/arm64/lib/libc.so -I /home/xx/disk2/xxx/qssi/prebuilts/vndk/v30/arm64/include/system/core/liblog/include_vndk/ /home/xx/disk2/xxx/qssi/prebuilts/runtime/mainline/platform/sdk/android/arm64/lib/liblog.so

cp libhardcontrol.so ~/disk2/Learn_packages/AndroidStudioProjects/Helloword/app/libs/arm64-v8a/
//hadcontrol.c
#include <jni.h> /* /usr/lib/jvm/java-1.8.0-openjdk-amd64/include/ */
#include <stdio.h>
#include <stdlib.h>

#include <android/log.h>
//-I /home/hq/disk2/ebony/qssi/prebuilts/vndk/v30/arm64/include/system/core/liblog/include_vndk/android/log.h
///home/hq/disk2/ebony/qssi/prebuilts/runtime/mainline/platform/sdk/android/arm64/lib/liblog.so

#if 0
typedef struct {
char *name;/* Java里调用函数名*/
char *signature;/* JNI 字段描述符,用来表示Java里调用的函数的参数和返回值类型*/
void *fnPtr;/* C语言实现的本地函数 */
} JNINativeMethod;
#endif

jint ledOpen(JNIEnv *env, jobject cls)
{
__android_log_print(ANDROID_LOG_DEBUG,"LEDDemo","native ledOpen...");
return 0;
}

void ledClose(JNIEnv *env, jobject cls)
{
__android_log_print(ANDROID_LOG_DEBUG,"LEDDemo","native ledClose...");
}


jint ledCtrl(JNIEnv *env, jobject cls, jint which,jint status)
{
//不能用printf添加打印信息,编成so库后printf是看不到的
__android_log_print(ANDROID_LOG_DEBUG,"helloword :LEDDemo","native ledCtrl: %d, %d",which ,status);
return 0;
}

static const JNINativeMethod methods[] = {
// {"ledOpen", "( )I", (int *)ledOpen},
// {"ledClose", "( )V", (void *)ledClose},
{"ledCtrl", "(II)I", (int *)ledCtrl},
};



/*只要java程序里面加载了libnative.so库,System.loadLibrary("native");
*就会先执行JNI_OnLoad方法。因此在JNI_OnLoad方法里面建立c_hello 和hello函数之间的映射*/
/* System.loadLibrary */
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *jvm, void *reserved)
{
JNIEnv *env;
jclass cls;

if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4)) { //首先GetEnv获得一个运行环境env,运行环境的版本为 JNI_VERSION_1_4
return JNI_ERR; /* JNI version not supported */
}
cls = (*env)->FindClass(env, "com/example/hardlibraray/HardControl");//FindClass 查找类JNIDemo,因为c_hello函数要映射到java类:JNIDemo里面的hello函数
if (cls == NULL) {//查找不到HardControl类,返回错误
return JNI_ERR;
}

/* 2. java<-->c 加载C库,在Java函数名和C库函数之间建立映射:比如在c库里面实现一个c_hello函数,在java程序里面就可以调用hello函数,在c_hello
* 和hello函数之间建立映射。*/
if ((*env)->RegisterNatives(env, cls, methods, sizeof(methods)/sizeof(methods[0])) < 0) //在运行环境env里面,提供了一个RegisterNatives方法,methods数组,数组有3项
return JNI_ERR;

return JNI_VERSION_1_4; //最后需要返回这个运行版本。
}
//MainActivity.java
package com.example.helloword;

import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.os.Bundle;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Toast;
import com.example.hardlibraray.*;


public class MainActivity extends AppCompatActivity {
//定义一个Button类的私有对象指向按钮
private Button button = null;
private boolean ledon = false;
private CheckBox checkBoxLED1 = null;
private CheckBox checkBoxLED2 = null;
private CheckBox checkBoxLED3 = null;
private CheckBox checkBoxLED4 = null;
class MyButtonListener implements View.OnClickListener{
@Override
public void onClick(View view) {
//一旦使用HardContral类,他的静态块就会被调用
HardControl hardContral = new HardControl();
ledon = !ledon;
if(ledon) {
button.setText("ALL ON");
checkBoxLED1.setChecked(true);
checkBoxLED2.setChecked(true);
checkBoxLED3.setChecked(true);
checkBoxLED4.setChecked(true);
for (int i=0;i<4;i++)
HardControl.ledCtrl(i,1);
} else {
button.setText("ALL OFF");
checkBoxLED1.setChecked(false);
checkBoxLED2.setChecked(false);
checkBoxLED3.setChecked(false);
checkBoxLED4.setChecked(false);
for (int i=0;i<4;i++)
HardControl.ledCtrl(i,0);
}
}
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

button = (Button) findViewById(R.id.BUTTON);
checkBoxLED1 = (CheckBox) findViewById(R.id.LED1);
checkBoxLED2 = (CheckBox) findViewById(R.id.LED2);
checkBoxLED3 = (CheckBox) findViewById(R.id.LED3);
checkBoxLED4 = (CheckBox) findViewById(R.id.LED4);
//设置一个监听函数
//定义一个MyButtonListener类,实现该接口
button.setOnClickListener(new MyButtonListener());
/* button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ledon = !ledon;
if(ledon) {
button.setText("ALL ON");
checkBoxLED1.setChecked(true);
checkBoxLED2.setChecked(true);
checkBoxLED3.setChecked(true);
checkBoxLED4.setChecked(true);
} else {
button.setText("ALL OFF");
checkBoxLED1.setChecked(false);
checkBoxLED2.setChecked(false);
checkBoxLED3.setChecked(false);
checkBoxLED4.setChecked(false);
}
}
});
*/
}

public void onCheckboxClicked (View view){
boolean checked =((CheckBox) view).isChecked();

switch (view.getId()) {
case R.id.LED1:
if (checked) {
Toast.makeText(getApplicationContext(),"LED1 ON",Toast.LENGTH_SHORT).show();
HardControl.ledCtrl(0,1);
}else {
Toast.makeText(getApplicationContext(),"LED1 off",Toast.LENGTH_SHORT).show();
HardControl.ledCtrl(0,0);
}
case R.id.LED2:
if (checked) {
Toast.makeText(getApplicationContext(),"LED2 ON",Toast.LENGTH_SHORT).show();
HardControl.ledCtrl(1,1);
}else {
Toast.makeText(getApplicationContext(),"LED2 off",Toast.LENGTH_SHORT).show();
HardControl.ledCtrl(1,0);
}
case R.id.LED3:
if (checked) {
Toast.makeText(getApplicationContext(),"LED3 ON",Toast.LENGTH_SHORT).show();
HardControl.ledCtrl(2,1);
}else {
Toast.makeText(getApplicationContext(),"LED3 off",Toast.LENGTH_SHORT).show();
HardControl.ledCtrl(2,0);
}
case R.id.LED4:
if (checked) {
Toast.makeText(getApplicationContext(),"LED4 ON",Toast.LENGTH_SHORT).show();
HardControl.ledCtrl(3,1);
}else {
Toast.makeText(getApplicationContext(),"LED4 off",Toast.LENGTH_SHORT).show();
HardControl.ledCtrl(3,0);
}

}
}
}
//build.gradle
plugins {
id 'com.android.application'
}

android {
namespace 'com.example.helloword'
compileSdk 33

defaultConfig {
applicationId "com.example.helloword"
minSdk 33
targetSdk 33
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
     ndk {
         abiFilters "arm64-v8a"
     }
}

sourceSets {
     main{
         jniLibs.srcDirs = ['libs'] //表示so文件是放在这个libs目录下
     }
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

dependencies {

implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

HardContral.java JNI

package com.example.hardlibraray;

import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.os.Bundle;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Toast;

public class HardControl {
    //声明native方法
 public static native int ledCtrl(int which ,int status);
 public static native int ledOpen();// 静态方法不需要实例化对象
 public static native void ledClose();

    //要在这个java程序里面加载C库:hardcontral,定义一个static模块
 //CTRL ALT T生成捕获异常的代码
 static{
        try {
            System.loadLibrary("hardcontrol");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值