第一章:android串口开发so库生成,android零基础

return mFileOutputStream;

}

// JNI(调用java本地接口,实现串口的打开和关闭)

/**

  • 串口有五个重要的参数:串口设备名,波特率,检验位,数据位,停止位

  • 其中检验位一般默认位NONE,数据位一般默认为8,停止位默认为1

*/

/**

  • @param path 串口设备的绝对路径

  • @param baudrate 波特率

  • @param flags 校验位

*/

private native static FileDescriptor open(String path, int baudrate, int flags);

/**

  • 打开串口

  • @param path 串口设备文件

  • @param baudRate 波特率

  • @param parity 奇偶校验,0 None(默认); 1 Odd; 2 Even

  • @param dataBits 数据位,5 ~ 8 (默认8)

  • @param stopBit 停止位,1 或 2 (默认 1)

  • @param flags 标记 0(默认)

  • @throws SecurityException

  • @throws IOException

*/

private native static FileDescriptor open(String path, int baudRate, int parity, int dataBits,

int stopBit, int flags);

public native void close();

static {

System.loadLibrary(“serial_port”);

}

}

  • 使用javah生成.h头文件

https://huangxiaoguo.blog.csdn.net/article/details/94385612

  • 编码c支持设置奇偶校验、数据位、停止位

在这里插入图片描述

/*

  • Copyright 2009-2011 Cedric Priscal

  • Licensed under the Apache License, Version 2.0 (the “License”);

  • you may not use this file except in compliance with the License.

  • You may obtain a copy of the License at

  • http://www.apache.org/licenses/LICENSE-2.0

  • Unless required by applicable law or agreed to in writing, software

  • distributed under the License is distributed on an “AS IS” BASIS,

  • WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

  • See the License for the specific language governing permissions and

  • limitations under the License.

*/

#include <termios.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <string.h>

#include <jni.h>

#include “SerialPort.h”

#include “android/log.h”

static const char *TAG=“serial_port”;

#define LOGI(fmt, args…) __android_log_print(ANDROID_LOG_INFO, TAG, fmt, ##args)

#define LOGD(fmt, args…) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)

#define LOGE(fmt, args…) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)

static speed_t getBaudrate(jint baudrate)

{

switch(baudrate) {

case 0: return B0;

case 50: return B50;

case 75: return B75;

case 110: return B110;

case 134: return B134;

case 150: return B150;

case 200: return B200;

case 300: return B300;

case 600: return B600;

case 1200: return B1200;

case 1800: return B1800;

case 2400: return B2400;

case 4800: return B4800;

case 9600: return B9600;

case 19200: return B19200;

case 38400: return B38400;

case 57600: return B57600;

case 115200: return B115200;

case 230400: return B230400;

case 460800: return B460800;

case 500000: return B500000;

case 576000: return B576000;

case 921600: return B921600;

case 1000000: return B1000000;

case 1152000: return B1152000;

case 1500000: return B1500000;

case 2000000: return B2000000;

case 2500000: return B2500000;

case 3000000: return B3000000;

case 3500000: return B3500000;

case 4000000: return B4000000;

default: return -1;

}

}

static void throwException(JNIEnv *env, const char *name, const char *msg)

{

jclass cls = env->FindClass(name);

/* if cls is NULL, an exception has already been thrown */

if (cls != NULL) {

env->ThrowNew(cls, msg);

}

/* free the local ref */

env->DeleteLocalRef(cls);

}

extern “C”

JNIEXPORT jobject JNICALL Java_cn_yumakeji_lib_1serialportapi_SerialPort_open__Ljava_lang_String_2IIIII

(JNIEnv *env, jclass thiz, jstring path, jint baudrate,jint parity, jint dataBits, jint stopBit, jint flags)

{

int fd;

speed_t speed;

jobject mFileDescriptor;

/* Check arguments */

{

speed = getBaudrate(baudrate);

if (speed == -1) {

throwException(env, “java/lang/IllegalArgumentException”, “Invalid baudrate”);

return NULL;

}

if (parity <0 || parity>2) {

throwException(env, “java/lang/IllegalArgumentException”, “Invalid parity”);

return NULL;

}

if (dataBits <5 || dataBits>8) {

throwException(env, “java/lang/IllegalArgumentException”, “Invalid dataBits”);

return NULL;

}

if (stopBit <1 || stopBit>2) {

throwException(env, “java/lang/IllegalArgumentException”, “Invalid stopBit”);

return NULL;

}

}

/* Opening device */

{

jboolean iscopy;

const char *path_utf = env->GetStringUTFChars(path, &iscopy);

LOGD(“Opening serial port %s with flags 0x%x”, path_utf, O_RDWR | flags);

fd = open(path_utf, O_RDWR | flags);

LOGD(“open() fd = %d”, fd);

env->ReleaseStringUTFChars(path, path_utf);

if (fd == -1)

{

throwException(env, “java/io/IOException”, “Cannot open port”);

return NULL;

}

}

/* Configure device */

{

struct termios cfg;

LOGD(“Configuring serial port”);

if (tcgetattr(fd, &cfg))

{

LOGE(“tcgetattr() failed”);

close(fd);

throwException(env, “java/io/IOException”, “tcgetattr() failed”);

return NULL;

}

cfmakeraw(&cfg);

cfsetispeed(&cfg, speed);

cfsetospeed(&cfg, speed);

/* More attribute set */

switch (parity) {

case 0: break;

case 1: cfg.c_cflag |= PARENB; break;

case 2: cfg.c_cflag &= ~PARODD; break;

}

switch (dataBits) {

case 5: cfg.c_cflag |= CS5; break;

case 6: cfg.c_cflag |= CS6; break;

case 7: cfg.c_cflag |= CS7; break;

case 8: cfg.c_cflag |= CS8; break;

}

switch (stopBit) {

case 1: cfg.c_cflag &= ~CSTOPB; break;

case 2: cfg.c_cflag |= CSTOPB; break;

}

if (tcsetattr(fd, TCSANOW, &cfg))

{

LOGE(“tcsetattr() failed”);

close(fd);

/* TODO: throw an exception */

return NULL;

}

}

/* Create a corresponding file descriptor */

{

jclass cFileDescriptor = env->FindClass(“java/io/FileDescriptor”);

jmethodID iFileDescriptor = env->GetMethodID(cFileDescriptor, “”, “()V”);

jfieldID descriptorID = env->GetFieldID(cFileDescriptor, “descriptor”, “I”);

mFileDescriptor = env->NewObject(cFileDescriptor, iFileDescriptor);

env->SetIntField(mFileDescriptor, descriptorID, (jint)fd);

}

return mFileDescriptor;

}

/*

  • Class: android_serialport_SerialPort

  • Method: open

  • Signature: (Ljava/lang/String;II)Ljava/io/FileDescriptor;

*/

JNIEXPORT jobject JNICALL Java_cn_yumakeji_lib_1serialportapi_SerialPort_open__Ljava_lang_String_2II

(JNIEnv *env, jclass thiz, jstring path, jint baudrate, jint flags)

{

int fd;

speed_t speed;

jobject mFileDescriptor;

/* Check arguments */

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

最后

简历首选内推方式,速度快,效率高啊!然后可以在拉钩,boss,脉脉,大街上看看。简历上写道熟悉什么技术就一定要去熟悉它,不然被问到不会很尴尬!做过什么项目,即使项目体量不大,但也一定要熟悉实现原理!不是你负责的部分,也可以看看同事是怎么实现的,换你来做你会怎么做?做过什么,会什么是广度问题,取决于项目内容。但做过什么,达到怎样一个境界,这是深度问题,和个人学习能力和解决问题的态度有关了。大公司看深度,小公司看广度。大公司面试你会的,小公司面试他们用到的你会不会,也就是岗位匹配度。

面试过程一定要有礼貌!即使你觉得面试官不尊重你,经常打断你的讲解,或者你觉得他不如你,问的问题缺乏专业水平,你也一定要尊重他,谁叫现在是他选择你,等你拿到offer后就是你选择他了。

另外,描述问题一定要慢!不要一下子讲一大堆,慢显得你沉稳、自信,而且你还有时间反应思路接下来怎么讲更好。现在开发过多依赖ide,所以会有个弊端,当我们在面试讲解很容易不知道某个方法怎么读,这是一个硬伤…所以一定要对常见的关键性的类名、方法名、关键字读准,有些面试官不耐烦会说“你到底说的是哪个?”这时我们会容易乱了阵脚。正确的发音+沉稳的描述+好听的嗓音决对是一个加分项!

最重要的是心态!心态!心态!重要事情说三遍!面试时间很短,在短时间内对方要摸清你的底子还是比较不现实的,所以,有时也是看眼缘,这还是个看脸的时代。

希望大家都能找到合适自己满意的工作!

进阶学习视频

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

堆,慢显得你沉稳、自信,而且你还有时间反应思路接下来怎么讲更好。现在开发过多依赖ide,所以会有个弊端,当我们在面试讲解很容易不知道某个方法怎么读,这是一个硬伤…所以一定要对常见的关键性的类名、方法名、关键字读准,有些面试官不耐烦会说“你到底说的是哪个?”这时我们会容易乱了阵脚。正确的发音+沉稳的描述+好听的嗓音决对是一个加分项!

最重要的是心态!心态!心态!重要事情说三遍!面试时间很短,在短时间内对方要摸清你的底子还是比较不现实的,所以,有时也是看眼缘,这还是个看脸的时代。

希望大家都能找到合适自己满意的工作!

进阶学习视频

[外链图片转存中…(img-DwG29yW4-1711884968201)]

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

[外链图片转存中…(img-l0A35xik-1711884968201)]

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

  • 10
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值