Android系统8.0以上通过代码获取root权限

1 篇文章 0 订阅
1 篇文章 0 订阅

最近要做一个通过代码模拟屏幕点击事件,由于之前系统使用的是Android 5.1,下面代码可以运行,也没有问题

(注意的是系统必须要root)

try {
            // 申请获取root权限,这一步很重要,不然会没有作用
            Process process = Runtime.getRuntime().exec("su");
            // 获取输出流
            OutputStream outputStream = process.getOutputStream();
            DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
            dataOutputStream.writeBytes(cmd);
            dataOutputStream.flush();
            dataOutputStream.close();
            outputStream.close();
            int code = process.waitFor();
            Log.e(TAG, "process.waitFor() = " + code);
        } catch (Throwable t) {
            Log.e(TAG, "Throwable = " + t.getMessage());
            t.printStackTrace();
        }

但是运行在Android 8.1系统的时候就报错了,当运行dataOutputStream.flush()的时候报Stream.Closed错误,在Android 8.1上可以这样写,将exec("su") 改成 exec("/system/bin/sh"),就可以运行了

  try {
            // 申请获取root权限,这一步很重要,不然会没有作用  将su 改成 /system/bin/sh
            Process process = Runtime.getRuntime().exec("/system/bin/sh");
            // 获取输出流
            OutputStream outputStream = process.getOutputStream();
            DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
            dataOutputStream.writeBytes(cmd);
            dataOutputStream.flush();
            dataOutputStream.close();
            outputStream.close();
            int code = process.waitFor();
            Log.e(TAG, "process.waitFor() = " + code);
        } catch (Throwable t) {
            Log.e(TAG, "Throwable = " + t.getMessage());
            t.printStackTrace();
        }

当然了也可以这么写:

        //new ProcessBuilder("su");Android 5.1  new ProcessBuilder("/system/bin/sh");Android 8.1
        ProcessBuilder pb = new ProcessBuilder("/system/bin/sh");
        pb.directory(new File("/"));//设置shell的当前目录。
        Process proc = null;
        try {
            proc = pb.start();
            // 获取输出流
            PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc
                    .getOutputStream())), true);
            out.write(cmd);
            out.flush();
            out.close();
        } catch (IOException e) {
            Log.e(TAG, "Throwable = " + e.getMessage());
            e.printStackTrace();
        }

其中cmd是运行指令:

input tap 10 20  代表点击屏幕x=10, y=20的坐标事件
input swipe 100 250 200 280 代表将屏幕x=100, y=250的坐标移动到x=200, y=280
input swipe 100 100 100 100 1000 这个可以代表长按事件,在屏幕x=100, y=100的地方长按屏幕 (长按事件有时会触发点击事件,可以返回 true 长按事件的时候取消点击事件)如下
textView1.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                Log.e(TAG, "MainActivity textView1 OnLongClick");
                //返回 true 消费事件
                return true;
            }
        });

 

希望能帮助到你,若有错误,欢迎指出

 

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android 8.0 及以上版本,为了增强应用程序的安全性,Android 引入了后台限制,禁止未在前台运行的应用程序启动服务。如果您想在后台启动服务,需要使用 `startForegroundService()` 方法。这个方法会启动一个前台服务,然后你可以在服务启动后在通知栏显示一个通知,以此来告知用户服务正在运行。 以下是一个使用 `startForegroundService()` 的示例代码: ``` if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 创建一个 NotificationChannel NotificationChannel channel = new NotificationChannel("channel_id", "channel_name", NotificationManager.IMPORTANCE_DEFAULT); // 向系统注册 NotificationChannel NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.createNotificationChannel(channel); } // 创建一个 Intent,启动你的服务 Intent serviceIntent = new Intent(this, YourService.class); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 在 Android 8.0 及以上版本上,需要调用 startForegroundService() 方法启动服务。 startForegroundService(serviceIntent); } else { // 在 Android 8.0 以下版本上,可以直接调用 startService() 方法启动服务。 startService(serviceIntent); } ``` 注意:如果你使用的是 `startForeground()` 方法,会在 Android 8.0 及以上版本上抛出 `IllegalStateException` 异常,因为 Android 8.0 及以上版本禁止在后台启动服务。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值