自己动手做一个adb的wifi连接及adb命令的apk

2024-09-03 02:18

本文主要是介绍自己动手做一个adb的wifi连接及adb命令的apk,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

估计搞安卓开发的小伙伴们都放弃了eclipse的开发转战android studio了吧,现在gradle都3.0 buiild都24.0.2了以后 都不再支持2.2及以下的版本了。eclipse的同学快上车。

上面的都不是重点,每当你大清早起来去公司上班,然后打开电脑发现你的usb线没有带,作为一个安卓程序员的你有点尴尬了。

然后你果断的给android studio装上ADB WIFI插件,哈哈,事实证明你还是相当的机智,然后你会面临另外一个尴尬(蛋疼)。你使用时会出现如图:

你会蛋微凉微凉的,这特么不是说好的可以用wifi连接adb吗?宝宝心里苦但是不能哭,问题来了你该找谁借usb线呢?特么安卓程序员都要自己用,所以你果断放弃找他们了,然后去找测试妹子吗感觉也有点不好。

最后呢你可能会选择下个WirelessADB,然后通过cmd命令来连接手机,确实效果还是比较明显,可以顺利的完成任务,求人不如求己对吧。

这里写图片描述

这样手机就连接起来了,宝宝再也不再担心手机忘记带数据线连接不起wifi了。但是用别人的还是不爽,今天宝宝就自己来实现这个功能(记住这功能要操作adb那么你的手机必须是root的,手机没有root你还做个毛的安卓程序员)。

实现效果

就不用gif来展示了,搞2个图来展示下效果图算了:

这里写图片描述
这里写图片描述

这里写图片描述

动手实现思路

  1. 代码获取局域网ip地址

  2. 判断手机是否获取root权限(su),没有自行root(不会的话jj剁了)

  3. su文件写入adb 命令执行相关的操作

  4. cmd执行连接命令,win可以写个bat文件


所有的步骤就上面这些了,开始果断撸码吧。


然后具体的就是先判断是否有root,毕竟adb是需要root的,然后也就是把命令写入su文件执行。(也可以通过Android Runtime来弄,更加轻松)

Android Runtime使得直接调用底层Linux下的可执行程序或脚本成为可能

比如Linux下写个测试工具,直接编译后apk中通过Runtime来调用

或者写个脚本,apk中直接调用,省去中间层或者JNI

需要注意:

  1. exec不等于console命令

2.exec的输入输出流需要自己处理

3.exec执行时阻塞、非阻塞,返回结果问题

4.注意权限问题

开始撸

获取ip地址(先得有一个局域网wifi)

 /*** @return 获取ip地址*/public static String getIpAddress() {try {for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {NetworkInterface intf = en.nextElement();for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {InetAddress inetAddress = enumIpAddr.nextElement();if (!inetAddress.isLoopbackAddress()&& inetAddress instanceof Inet4Address) {return inetAddress.getHostAddress().toString();}}}} catch (Exception e) {e.printStackTrace();}return null;}

把32位整形的ip地址换成“...”地址

我们先通过安卓里面的WifiManager来获取wifiInfo,接着通过wifiInfo使用aidl来获取32位整形的ip地址,接着我们把它转化为我们常见的ip地址形式

 /*** @return 获取局域网的ip地址形式(32位整型IP地址转成本地ip)*/private static String getLocalIpAddress() {WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);WifiInfo wifiInfo = wifiManager.getConnectionInfo();// 获取32位整型IP地址int ipAddress = wifiInfo.getIpAddress();// 返回整型地址转换成“*.*.*.*”地址return String.format("%d.%d.%d.%d", (ipAddress & 0xff),(ipAddress >> 8 & 0xff), (ipAddress >> 16 & 0xff),(ipAddress >> 24 & 0xff));}

准备工作已经做好了(适配获取局域网ip)。

获取判断root权限

Runtime.getRuntime().exec("su");

一般我们使用adb得先去获取root权限的,也就是检验是否有su文件。

 // 判断机器Android是否已经root,即是否获取root权限public boolean haveRoot() {if (!mHaveRoot) {int ret = execRootCmdCilent("echo test"); // 通过执行测试命令来检测if (ret != -1) {Toast.makeText(context, "已经root", Toast.LENGTH_LONG).show();mHaveRoot = true;} else {Toast.makeText(context, "not root", Toast.LENGTH_LONG).show();Log.i(TAG, "not root!");}} else {Toast.makeText(context, "已经root", Toast.LENGTH_LONG).show();Log.i(TAG, "mHaveRoot = true, have root!");}return mHaveRoot;}

设置adb服务连接的ip和端口,并且开启adb

 /*** 打开adb连接** @param tv*/public static void openAdb(TextView tv) {if (!isConn) {tv.setText(" adb connect" + getLocalIpAddress());execShell("setprop service.adb.tcp.port 8888");//  Runtime.getRuntime().exec(new String[]{"/system/bin/su","-c", "setprop service.adb.tcp.port 5555"});try {Runtime.getRuntime().exec(new String[]{"/system/bin/su", "-c", "start adbd"}); //   execShell("start adbd");} catch (IOException e) {e.printStackTrace();}isConn = true;}}

其实呢,看代码我们也知道我们既可以使用用写入su文件的方式也可以直接使用Runtime.getRuntime().exec()来执行,后文全部使用后者使用起来很简单。

  /*** 在su文件中写入命令** @param str*/public static void execShell(String str) {try {// 权限设置Process p = Runtime.getRuntime().exec("su");// 获取输出流OutputStream outputStream = p.getOutputStream();DataOutputStream dataOutputStream = new DataOutputStream(outputStream);// 将命令写入dataOutputStream.writeBytes(str);// 提交命令dataOutputStream.flush();// 关闭流操作dataOutputStream.close();outputStream.close();} catch (Throwable t) {t.printStackTrace();}}

上面贴的代码和Runtime.getRuntime().exec(cmdstr)的功能一样。

连接的时候,你需要在cmd敲命令adb connect 你的ip地址,当然一般你是配置了adb的环境的,win下所以你只需要写一个bat文件就好了,连接的时候点击下。

里面的内容,你只需要把cmd命令拷贝进去好了(ip不能经常变的前提,变了手动改)。

关闭adb

/*** 断开adb连接*/public static void closeAdb() {try {Runtime.getRuntime().exec(new String[]{"/system/bin/su", "-c", "stop adbd"});} catch (IOException e) {e.printStackTrace();}}

重启adb

  /*** 重启adb*/public static void restartAdb() {try {Runtime.getRuntime().exec(new String[]{"/system/bin/su", "-c", "adb kill-server"});Runtime.getRuntime().exec(new String[]{"/system/bin/su", "-c", "adb start-server"});} catch (IOException e) {e.printStackTrace();}}

根据包名卸载apk

  /*** 卸载apk*/public static void uninstallApk(String packageName) {try {Process p= Runtime.getRuntime().exec(new String[]{"/system/bin/su", "-c", "pm uninstall " + packageName});if (p == null) {Toast.makeText(context, "app 卸载失败", Toast.LENGTH_LONG).show();} else {Toast.makeText(context, "app 已成功卸载", Toast.LENGTH_LONG).show();}} catch (IOException e) {e.printStackTrace();}}

根据包名杀死apk(好像没有效果)

  /*** 杀死app** @param packageName 包名*/public static void killApp(String packageName) {try {Process p=Runtime.getRuntime().exec(new String[]{"/system/bin/su", "-c", " am force-stop " + packageName});if (p == null) {Toast.makeText(context, "app 关闭失败", Toast.LENGTH_LONG).show();} else {Toast.makeText(context, "app  关闭成功", Toast.LENGTH_LONG).show();}} catch (IOException e) {e.printStackTrace();}}

杀死当前应用

 /*** 通过Android底层实现关闭当前进程*/public  static void killProcess() {int pid = android.os.Process.myPid();if (pid != 0) {System.exit(0);android.os.Process.killProcess(pid);}}

开启指定app(须知道包名)

 /*** 打开apk** @param packageName*/public static void startApk(String packageName) {try{Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);context.startActivity(intent);}catch(Exception e){Toast.makeText(context, "没有安装", Toast.LENGTH_LONG).show();}}

清除指定apk数据

 /*** 清除apk缓存** @param packageName*/public static void clearApp(String packageName) {try {Process p= Runtime.getRuntime().exec(new String[]{"/system/bin/su", "-c", "pm clear " + packageName + " HERE"});if (p == null) {Toast.makeText(context, "app 缓存数据清空失败", Toast.LENGTH_LONG).show();} else {Toast.makeText(context, "app  缓存数据清空成功", Toast.LENGTH_LONG).show();}} catch (IOException e) {e.printStackTrace();}}

adb命令重启

    /*** 重启手机*/public static void rebootPhone() {try {Runtime.getRuntime().exec(new String[]{"/system/bin/su", "-c", "reboot"});} catch (IOException e) {e.printStackTrace();}}

adb 命令关机

  /*** 关闭手机*/public static void closePhone() {try {Runtime.getRuntime().exec(new String[]{"/system/bin/su", "-c", "reboot -p"});} catch (IOException e) {e.printStackTrace();}}

具体使用代码很简单:

package com.losileeya.wifiadb;import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends AppCompatActivity {@BindView(R.id.tv_conn_adb)TextView tvConnAdb;@BindView(R.id.tv_conn_stop)TextView tvConnStop;@BindView(R.id.tv_adb_restart)TextView tvAdbRestart;@BindView(R.id.et_appinfo)EditText etAppinfo;@BindView(R.id.tv_uninstall_app)TextView tvUninstallApp;@BindView(R.id.tv_kill_app)TextView tvKillApp;@BindView(R.id.tv_start_app)TextView tvStartApp;@BindView(R.id.tv_clean_appdata)TextView tvCleanAppdata;@BindView(R.id.tv_close_phone)TextView tvClosePhone;@BindView(R.id.tv_rebot_phone)TextView tvRebotPhone;@BindView(R.id.tv_kill_currentapp)TextView tvKillCurrentapp;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ButterKnife.bind(this);}@OnClick({R.id.tv_conn_adb, R.id.tv_conn_stop, R.id.tv_adb_restart, R.id.tv_uninstall_app, R.id.tv_kill_app,R.id.tv_kill_currentapp, R.id.tv_start_app, R.id.tv_clean_appdata,R.id.tv_rebot_phone,R.id.tv_close_phone})public void onClick(View view) {String packageName=etAppinfo.getText().toString().trim();switch (view.getId()) {case R.id.tv_conn_adb:Intent intent= new Intent(MainActivity.this,ConnectActivity.class);intent.putExtra("isConn",true);startActivity(intent);break;case R.id.tv_conn_stop:Intent i= new Intent(MainActivity.this,ConnectActivity.class);i.putExtra("isConn",false);startActivity(i);break;case R.id.tv_adb_restart:new AdbUtil(this).restartAdb();break;case R.id.tv_uninstall_app:if(TextUtils.isEmpty(packageName)){Toast.makeText(this,"请输入包名",Toast.LENGTH_SHORT).show();}else{new AdbUtil(this).uninstallApk(packageName);}break;case R.id.tv_kill_app:if(TextUtils.isEmpty(packageName)){Toast.makeText(this,"请输入包名",Toast.LENGTH_SHORT).show();}else {new AdbUtil(this).killApp(packageName);}break;case R.id.tv_kill_currentapp:new AdbUtil(this).killProcess();break;case R.id.tv_start_app:if(TextUtils.isEmpty(packageName)){Toast.makeText(this,"请输入包名",Toast.LENGTH_SHORT).show();}else {new AdbUtil(this).startApk(packageName);}break;case R.id.tv_clean_appdata:if(TextUtils.isEmpty(packageName)){Toast.makeText(this,"请输入包名",Toast.LENGTH_SHORT).show();}else {new AdbUtil(this).clearApp(packageName);}break;case R.id.tv_close_phone:new AdbUtil(this).closePhone();break;case R.id.tv_rebot_phone:new AdbUtil(this).rebootPhone();break;}}
}

demo 传送门:WifiAdb.zip

总结

代码不难,就是为了学习一下adb命令,装在手机里没有带数据线的时候,也可以拿来进行wifi连接adb调试安卓应用以后再也不用去下载什么WirelessAdb了,至少关机重启还是方便点吧,可能跟cmd命令有点点差别吧。

这篇关于自己动手做一个adb的wifi连接及adb命令的apk的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1131743

相关文章

Go语言连接MySQL数据库执行基本的增删改查

《Go语言连接MySQL数据库执行基本的增删改查》在后端开发中,MySQL是最常用的关系型数据库之一,本文主要为大家详细介绍了如何使用Go连接MySQL数据库并执行基本的增删改查吧... 目录Go语言连接mysql数据库准备工作安装 MySQL 驱动代码实现运行结果注意事项Go语言执行基本的增删改查准备工作

Linux查询服务器 IP 地址的命令详解

《Linux查询服务器IP地址的命令详解》在服务器管理和网络运维中,快速准确地获取服务器的IP地址是一项基本但至关重要的技能,下面我们来看看Linux中查询服务器IP的相关命令使用吧... 目录一、hostname 命令:简单高效的 IP 查询工具命令详解实际应用技巧注意事项二、ip 命令:新一代网络配置全

python连接sqlite3简单用法完整例子

《python连接sqlite3简单用法完整例子》SQLite3是一个内置的Python模块,可以通过Python的标准库轻松地使用,无需进行额外安装和配置,:本文主要介绍python连接sqli... 目录1. 连接到数据库2. 创建游标对象3. 创建表4. 插入数据5. 查询数据6. 更新数据7. 删除

99%的人都选错了! 路由器WiFi双频合一还是分开好的专业解析与适用场景探讨

《99%的人都选错了!路由器WiFi双频合一还是分开好的专业解析与适用场景探讨》关于双频路由器的“双频合一”与“分开使用”两种模式,用户往往存在诸多疑问,本文将从多个维度深入探讨这两种模式的优缺点,... 在如今“没有WiFi就等于与世隔绝”的时代,越来越多家庭、办公室都开始配置双频无线路由器。但你有没有注

Linux grep 命令的使用指南

《Linuxgrep命令的使用指南》本文给大家介绍Linuxgrep命令的使用指南,包括基础搜索语法、实践指南,感兴趣的朋友跟随小编一起看看吧... 目录linux grep 命令全面使用指南一、基础搜索语法1. 基本文本搜索2. 多文件搜索二、常用选项详解1. 输出控制选项2. 上下文控制选项三、正则表达

DNS查询的利器! linux的dig命令基本用法详解

《DNS查询的利器!linux的dig命令基本用法详解》dig命令可以查询各种类型DNS记录信息,下面我们将通过实际示例和dig命令常用参数来详细说明如何使用dig实用程序... dig(Domain Information Groper)是一款功能强大的 linux 命令行实用程序,通过查询名称服务器并输

在 Spring Boot 中连接 MySQL 数据库的详细步骤

《在SpringBoot中连接MySQL数据库的详细步骤》本文介绍了SpringBoot连接MySQL数据库的流程,添加依赖、配置连接信息、创建实体类与仓库接口,通过自动配置实现数据库操作,... 目录一、添加依赖二、配置数据库连接三、创建实体类四、创建仓库接口五、创建服务类六、创建控制器七、运行应用程序八

解决hive启动时java.net.ConnectException:拒绝连接的问题

《解决hive启动时java.net.ConnectException:拒绝连接的问题》Hadoop集群连接被拒,需检查集群是否启动、关闭防火墙/SELinux、确认安全模式退出,若问题仍存,查看日志... 目录错误发生原因解决方式1.关闭防火墙2.关闭selinux3.启动集群4.检查集群是否正常启动5.

setsid 命令工作原理和使用案例介绍

《setsid命令工作原理和使用案例介绍》setsid命令在Linux中创建独立会话,使进程脱离终端运行,适用于守护进程和后台任务,通过重定向输出和确保权限,可有效管理长时间运行的进程,本文给大家介... 目录setsid 命令介绍和使用案例基本介绍基本语法主要特点命令参数使用案例1. 在后台运行命令2.

在Linux系统上连接GitHub的方法步骤(适用2025年)

《在Linux系统上连接GitHub的方法步骤(适用2025年)》在2025年,使用Linux系统连接GitHub的推荐方式是通过SSH(SecureShell)协议进行身份验证,这种方式不仅安全,还... 目录步骤一:检查并安装 Git步骤二:生成 SSH 密钥步骤三:将 SSH 公钥添加到 github