当前位置: 首页 > news >正文

Android 8.1 设置USB传输文件模式(MTP)

项目需求,需要在电脑端adb发送通知手机端接收指令,将USB的仅充电模式更改成传输文件(MTP)模式,便捷用户在我的电脑里操作内存文件,下面是我们的常见的修改方式

1、android12以下、android21以上是这种方式
UsbManager mUsbManager = (UsbManager) MyApplication.context.getSystemService(Context.USB_SERVICE);
mUsbManager.setCurrentFunction(UsbManager.USB_FUNCTION_MTP,true); 

UsbManager.USB_FUNCTION_MTP = "mtp" ,所有 也可以直接传mtp

2、android12以上
UsbManager mUsbManager = (UsbManager) MyApplication.context.getSystemService(Context.USB_SERVICE);
mUsbManager.setCurrentFunction(UsbManager.FUNCTION_MTP); 

 UsbManager.FUNCTION_MTP的指向是GadgetFunction.MTP,查看源码是long1<<2;也就是4;所以在android12及以上也可以传setCurrentFunction(4)

这就是我们设置MTP模式的代码触发的地方,有的人就会问了,setCurrentFunction是系统api,我们根本就不能去调用,所以有两种解决方案:1是你要设置系统app,2是修改下系统源码用反射的方法调用上面的方法,我们项目的特殊性,所以我们是有项目的源码的,可以直接修改我的系统源码,所以我使用的反射方法(基于android8.1)

    new Thread(new Runnable() {@Overridepublic void run() {try {UsbManager mUsbManager = (UsbManager) MyApplication.context.getSystemService(Context.USB_SERVICE);// 获取Class对象Class<?> clazz = mUsbManager.getClass();Method setCurrentFunctionMethod = clazz.getDeclaredMethod("setCurrentFunction",String.class, boolean.class);setCurrentFunctionMethod.invoke(mUsbManager, "mtp", true);} catch (Exception e) {// e.printStackTrace();Log.i("TAG", "setCurrentFunction: " + e.getMessage());}}}).start();

官方源码里说要在异步里面去调用这个方法,否则可能会出现异常,这一点大家注意下,在setCurrentFunction后会有一个异常,会提示我们缺少android.permission.MANAGE_USB这个权限,当我们的app不是系统权限和root的话是不能申请这个权限的,所以我说我们是改了系统api,我们可以看到setCurrentFunction是调用了Service.setCurrentFunctions(functions);这个方法,UsbService是在frameworks-base-services\frameworks-base-services\usb\java\com\android\server\usb\UsbService.java这个目录下的,如果要跟其他工程师协调就可以告诉他是这个文件目录

看截图知道了他通过enforceCallingOrSelfPermission判断权限是否用了。所以只需要注释掉这行就可以了,app就不用去申请权限了,然后刷机ok

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • gitee+picgo+typora图床搭建
  • 小秋SLAM入门实战深度学习所有文章汇总
  • go 语言程序设计第1章--入门
  • nginx安装和配置
  • Pytest单元测试系列[v1.0.0][pytest插件常用技巧]
  • Web前端第9章思维导图
  • Docker自建私人云盘系统
  • mysqld_exporter使用
  • flutter 之proto
  • 数据库-期末考前复习-第4章-数据库安全性
  • C基础使用
  • Golang leetcode206 翻转链表 迭代 递归 双指针
  • unknown variable ‘authentication_policy=mysql_native_password‘
  • 图像分割实战-系列教程7:unet医学细胞分割实战5(医学数据集、图像分割、语义分割、unet网络、代码逐行解读)
  • LeetCode 1758. 生成交替二进制字符串的最少操作数【字符串,模拟】1353
  • 【comparator, comparable】小总结
  • AngularJS指令开发(1)——参数详解
  • AzureCon上微软宣布了哪些容器相关的重磅消息
  • CentOS7 安装JDK
  • Docker下部署自己的LNMP工作环境
  • Hibernate【inverse和cascade属性】知识要点
  • Java的Interrupt与线程中断
  • JAVA多线程机制解析-volatilesynchronized
  • java中具有继承关系的类及其对象初始化顺序
  • python学习笔记 - ThreadLocal
  • Vim 折腾记
  • Vue实战(四)登录/注册页的实现
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 检测对象或数组
  • 微服务框架lagom
  • 一道面试题引发的“血案”
  • 字符串匹配基础上
  • ​你们这样子,耽误我的工作进度怎么办?
  • ​水经微图Web1.5.0版即将上线
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • #在 README.md 中生成项目目录结构
  • (02)Unity使用在线AI大模型(调用Python)
  • (2.2w字)前端单元测试之Jest详解篇
  • (23)Linux的软硬连接
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (黑马点评)二、短信登录功能实现
  • (回溯) LeetCode 46. 全排列
  • (六)Hibernate的二级缓存
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (算法二)滑动窗口
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .NET 6 Mysql Canal (CDC 增量同步,捕获变更数据) 案例版
  • .net 验证控件和javaScript的冲突问题
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • .net反混淆脱壳工具de4dot的使用
  • .net企业级架构实战之7——Spring.net整合Asp.net mvc