前言

经常会有人问:“现在学习Android开发还有前景?”我的看法是现在只是市场趋于平稳了,对开发人员的要求越来越好了,这并不代表没有前景了。

移动开发不等于App开发,所有新的技术浪潮其实都可以融入到移动开发的体系里,比如IOT、音视频、边缘计算、VR/AR,我们要做的,只是打好基础,随时准备战斗。其次,从心态上,我觉得我们千万不要把时间浪费在纠结问题上,而是应该放在解决问题上。“王者荣耀”“吃鸡”并不能解决我们的焦虑,拥抱变化,才能拥有未来,让我们共勉。

移动端的招聘中高端的职位还是很多的,看了下拉勾上的Android招聘需求,在北京中高级Android开发大多是15k-30k,如何从初级进阶?

int deviceVID = device.getVendorId();
int devicePID = device.getProductId();
if (deviceVID != 0x1d6b && (devicePID != 0x0001 && devicePID != 0x0002 && devicePID != 0x0003)) {
// There is a device connected to our Android device. Try to open it as a Serial Port.
requestUserPermission();
keep = false;
} else {
device = null;
}

if (!keep)
break;
}
}
}

上面的代码运行之后,如果没有问题则会得到一个UsbDevice,先看看google文档给出的这个类的解释:

This class represents a USB device attached to the android device with the android device acting as the USB host. Each device contains one or more UsbInterfaces, each of which contains a number of UsbEndpoints (the channels via which data is transmitted over USB).

此类表示连接到Android设备的USB设备,其中android设备充当USB主机。 每个设备都包含一个或多个UsbInterfaces,每个UsbInterfaces包含许多UsbEndpoints(相当于一个通道,通过USB来进行数据传输的通道)。

其实这个类就是用来描述USB设备的信息的,可以通过这个类获取到设备的输出输入端口,以及设备标识等信息。

获取到需要的设备之后,请求使用权限:

private static final String ACTION_USB_PERMISSION = “com.android.example.USB_PERMISSION”;
public static final String ACTION_USB_ATTACHED = “android.hardware.usb.action.USB_DEVICE_ATTACHED”;
public static final String ACTION_USB_DETACHED = “android.hardware.usb.action.USB_DEVICE_DETACHED”;
private void requestUserPermission() {
Intent intent = new Intent(ACTION_USB_PERMISSION);
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
IntentFilter permissionFilter = new IntentFilter(ACTION_USB_PERMISSION);
context.registerReceiver(usbPermissionReceiver, permissionFilter);
//申请权限 会弹框提示用户授权
usbManager.requestPermission(usbDevice, mPermissionIntent);
}

这里我们声明一个广播Receiver,当接受到授权成功的广播后做一些其他处理:

private boolean serialPortConnected;
private UsbDeviceConnection connection;
private final BroadcastReceiver cardReaderReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent arg1) {
if (arg1.getAction().equals(ACTION_USB_PERMISSION)) {
boolean granted = arg1.getExtras().getBoolean(UsbManager.EXTRA_PERMISSION_GRANTED); //用户是否同意授权使用usb
if (granted)
{
connection = usbManager.openDevice(device); //建立一个连接,通过这个连接读写数据
new ConnectionThread().start(); //开始读写数据
}
} else if (arg1.getAction().equals(ACTION_USB_ATTACHED)) {
if (!serialPortConnected)
findSerialPortDevice();
} else if (arg1.getAction().equals(ACTION_USB_DETACHED)) {
serialPortConnected = false;
}
}
};

收发数据

授权成功之后,就可以建立一个连接来读写数据了。UsbDeviceConnection就是这个连接

google文档给出的解释是:

This class is used for sending and receiving data and control messages to a USB device. Instances of this class are created by openDevice(UsbDevice).

这个类用于向USB设备发送和接收数据,以及控制消息。 它的实例由openDevice(UsbDevice)这个方法创建。

在这个时候,我们已经可以和设备进行数据传输了(理论上)。在大部分情况下还需要对USB串口进行一些配置,比如波特率,停止位,数据控制等,不然两边配置不同,收到的数据会乱码。具体怎么配置,需要看串口设备的芯片是什么了,现在主流的基本上就是PL2303,我使用的转接线也是PL2303的。幸运的是github上有个专门的库[UsbSerial]((),将这些繁琐的配置都打包好了,我们直接用就好了,使用方法可以去github上看,写得很详细。

发送命令

那怎么给usb外设发送数据呢?UsbDeviceConnection有一个方法用于发送数据:

int bulkTransfer(outEndpoint, data, data.length, TIMEOUT);

第一个参数是数据传输的端口,这个端口可不是随便设置的,我们要找到具有数据传输功能的接口UsbInterface,从它里面找到数据输入和输出端口UsbEndpoint 。

mInterface = device.getInterface(0); //一般第一个就是我们需要的
int numberEndpoints = mInterface.getEndpointCount();
for(int i=0;i<=numberEndpoints-1;i++)
{
UsbEndpoint endpoint = mInterface.getEndpoint(i);
if(endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK
&& endpoint.getDirection() == UsbConstants.USB_DIR_IN)
inEndpoint = endpoint;
else if(endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK
&& endpoint.getDirection() == UsbConstants.USB_DIR_OUT)
outEndpoint = endpoint;
}

第二个参数是发送的数据

第三个参数是数据的大小,最后一个参数是设置超时时间。这个方法的返回值是int类型,它表示本次发送数据成功的字节数,如果失败的话,就返回-1。

接收数据

我们已经找到了数据输入端口usbEndpointIn,因为数据的输入是不定时的,因此我们可以另开一个线程,来专门接受数据。

int maxSize = inEndpoint.getMaxPacketSize();
ByteBuffer byteBuffer = ByteBuffer.allocate(maxSize); //创建一个缓冲区接收数据
UsbRequest usbRequest = new UsbRequest(); //注意UsbRequest是异步处理的
usbRequest.initialize(connection, inEndpoint);
usbRequest.queue(byteBuffer, maxSize);
if(connection.requestWait() == usbRequest){
byte[] retData = byteBuffer.array();
for(Byte byte1 : retData){
Log.d(TAG,byte1)
}
}

绕过USB系统授权

不知道是Android的bug还是什么,给usb授权的时候会有一个弹框提醒,虽然可以勾选不再提示,但是没有任何用,关机重启之后,还是会重新弹出来。因为是Android开发板,就算外接显示屏,也不会触屏呀!一两台设备还好,外接鼠标搞定,要是上百上千台,那不得累死!

所以有没有什么方法,可以跳过USB授权验证呢?答案是有的。

我们不需要这个弹框,可以看看点击弹框确认按钮之后做了什么操作。我们可以模仿点击确认之后的流程,骗过系统。

当弹框出现的时候,可以通过adb shell查看当前的activity:

adb shell dumpsys activity | grep -i run

可以清楚的看到当前的activity是UsbPermissionActivity,AndroidSdk里面是可以搜得到这个activity的,我的开发板是6.0的,所以选的android-23,那我们分析一下这个activity做了些什么。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wyD0nZWM-1649748756871)(https://user-gold-cdn.xitu.io/2019/6/18/16b69777645bceb3?imageView2/0/w/1280/h/960/ignore-error/1)]

先把代码全部贴出来:

public class UsbPermissionActivity extends AlertActivity
implements DialogInterface.OnClickListener, CheckBox.OnCheckedChangeListener {

private static final String TAG = “UsbPermissionActivity”;

private CheckBox mAlwaysUse;
private TextView mClearDefaultHint;
private UsbDevice mDevice;
private UsbAccessory mAccessory;
private PendingIntent mPendingIntent;
private String mPackageName;
private int mUid;
private boolean mPermissionGranted;
private UsbDisconnectedReceiver mDisconnectedReceiver;

@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);

Intent intent = getIntent();
mDevice = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
mAccessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
mPendingIntent = (PendingIntent)intent.getParcelableExtra(Intent.EXTRA_INTENT);
mUid = intent.getIntExtra(Intent.EXTRA_UID, -1);
mPackageName = intent.getStringExtra(“package”);

PackageManager packageManager = getPackageManager();
ApplicationInfo aInfo;
try {
aInfo = packageManager.getApplicationInfo(mPackageName, 0);
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, “unable to look up package name”, e);
finish();
return;
}
String appName = aInfo.loadLabel(packageManager).toString();

final AlertController.AlertParams ap = mAlertParams;
ap.mIcon = aInfo.loadIcon(packageManager);
ap.mTitle = appName;
if (mDevice == null) {
ap.mMessage = getString(R.string.usb_accessory_permission_prompt, appName);
mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mAccessory);
} else {
ap.mMessage = getString(R.string.usb_device_permission_prompt, appName);
mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mDevice);
}
ap.mPositiveButtonText = getString(android.R.string.ok);
ap.mNegativeButtonText = getString(android.R.string.cancel);
ap.mPositiveButtonListener = this;
ap.mNegativeButtonListener = this;

// add “always use” checkbox
LayoutInflater inflater = (LayoutInflater)getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
ap.mView = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null);

总结:

各行各样都会淘汰一些能力差的,不仅仅是IT这个行业,所以,不要被程序猿是吃青春饭等等这类话题所吓倒,也不要觉得,找到一份工作,就享受安逸的生活,你在安逸的同时,别人正在奋力的向前跑,这样与别人的差距也就会越来越遥远,加油,希望,我们每一个人,成为更好的自己。

  • BAT大厂面试题、独家面试工具包,

  • 资料包括 数据结构、Kotlin、计算机网络、Framework源码、数据结构与算法、小程序、NDK、Flutter,



    奋力的向前跑,这样与别人的差距也就会越来越遥远,加油,希望,我们每一个人,成为更好的自己。

  • BAT大厂面试题、独家面试工具包,

  • 资料包括 数据结构、Kotlin、计算机网络、Framework源码、数据结构与算法、小程序、NDK、Flutter,

    [外链图片转存中…(img-vofI04Z4-1649748756872)]
    [外链图片转存中…(img-mba7se4f-1649748756873)]
    Android开发不会这些?如何面试拿高薪!

Android USB串口通信实现 以及绕过USB弹框验证,50w字+的Android技术类校招面试题汇总相关推荐

  1. 万字Android技术类校招面试题汇总,深度好文

    开头 在Android开发当中,相信大家对第三方库的重要性是无需多说的,尤其是三方库源码更是重中之重,而EventBus源码就属于其中的一个重点. EventBus是安卓(Java中也可以用)开发中非 ...

  2. android基础面试题及答案,万字Android技术类校招面试题汇总

    前言 回顾一下自己这段时间的经历,九月份的时候,公司通知了裁员,我匆匆忙忙地出去面了几家,但最终都没有拿到offer,我感觉今年的寒冬有点冷.到十二月份,公司开始第二波裁员,我决定主动拿赔偿走人.后续 ...

  3. oppo安卓面试题,万字Android技术类校招面试题汇总,GitHub标星3.2K

    一.开始的开始 **Android框架体系架构(高级UI+FrameWork源码)**这块知识是现今使用者最多的,我们称之Android2013~2016年的技术,但是,即使是这样的技术,Androi ...

  4. 50w字+的Android技术类校招面试题汇总,成功入职阿里

    前言 我今年38岁,失业前是南方二线城市某知名互联网公司的部门技术主管,婚姻幸福,膝下有一儿一女,组成一个好字,房子车子:有一辆十几万的汽车,一套月供八千的房子,妻子全职在家带娃,家里的一切开销全部指 ...

  5. Android开发技术总结!万字Android技术类校招面试题汇总,架构师必备技能

    开头 年前面试了一些公司,目前已经拿到了阿里跟头条的 offer.去年我也出去找工作了,面试五家拿到了四家公司的 offer.所以在面试方面我应该可以提供一些愚见吧.本篇会讲解一些常见题目以及一些答题 ...

  6. 万字Android技术类校招面试题汇总,Android岗

    前不久听我一个字节的朋友说了一个神转折的故事. 一名大专生,异常执着地向他们公司投简历,屡战屡败,屡败屡战,前前后后向字节跳动投了九次简历. 你猜后面怎么着?还真让他成功了,第九次居然拿到了offer ...

  7. 万字Android技术类校招面试题汇总,吐血整理

    背景 本人双非渣本 今年由于疫情,上半年一直在家里.2月份本来无忧无虑,呆在家里不给国家添乱的时候,发现身边的同学找到了大厂的offer.心里开始有点慌张.本来想在3月份如果能回到学校,就开始考研之路 ...

  8. 50w字+的Android技术类校招面试题汇总(附答案

    (3).如何在未排序整数数组中找到最大值和最小值? 字节跳动 (4).在Java中如何从给定数组中删除多重复制? (5).大数相加(今日头条) 3.1.3 链表 (1).那查询第一个跟倒数第二个呢?( ...

  9. 不可多得的干货!万字Android技术类校招面试题汇总,吐血整理

    背景 本人双非渣本 今年由于疫情,上半年一直在家里.2月份本来无忧无虑,呆在家里不给国家添乱的时候,发现身边的同学找到了大厂的offer.心里开始有点慌张.本来想在3月份如果能回到学校,就开始考研之路 ...

最新文章

  1. 我的Debian 8.0 (jessie)配置文档
  2. 黑马java教程是什么_Java教程:揭秘什么是面向接口编程
  3. ListView添加项目
  4. 【机器学习基础】Softmax与Sigmoid你还不知道存在这些联系?
  5. koreader下载_koreader下载_koreader安装_koreader最新版_koreader安卓版下载_koreader app_易玩网...
  6. Java多线程和并发(三),Thread类和Runnable接口
  7. oracle网络ora文件,Oracle错误—ORA-03113:在通信信道文件的末尾(归档日志处理)...
  8. U盘安装CentOS系统
  9. 很荣幸,和各位一起创造了历史
  10. mysql fastdfs_FastDFS监控系统Fastdfs-zyc配置
  11. 【sqlplus】SQL*Plus命令使用大全
  12. 孙溟㠭篆刻作品《叶》
  13. 设计分享|基于单片机电子密码锁(汇编)
  14. ES6中PadStart方法
  15. 关于实时时钟模块DS1302使用心得
  16. python抓取经典评论_通过Python抓取天猫评论数据
  17. 恒源云算力平台使用感受
  18. 河马书来了!线上实验领域的“圣经”火热预售中
  19. 计算机ps2级证书英语,全国计算机等级PHOTOSHOP一级证书
  20. 中国芯片首富300亿办的大学“亮相”:占地2250亩,陈十一院士领衔筹建,已与西湖大学达成合作...

热门文章

  1. MYSQL的级联复制
  2. 对移动通信网络优化工作的一些见解(转)
  3. 华为mate40和苹果12pro参数对比 哪个好?看了这篇再决定
  4. Windows双系统Ubuntu18.04安装分区过程
  5. (转)图森技术汇 | 聊聊Anchor的前世今生(下)
  6. 上城区餐饮油污加大整治,环境污染攻坚克难
  7. 音乐播放器之--在线音乐播放
  8. java lt t gt 是什么意思_关于泛型:Java 7中的菱形运算符(&lt;&gt;)有什么意义?...
  9. 抖音电商升级:全场景、全链路与可持续生态
  10. ElasticSearch入门总结