You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用无法修改input_suspend值,求充电停止实现方案

问题描述

我正在开发一款可停止电池充电的Android应用,设备运行Android 12,应用compileSdk版本为32,且设备已Root,已执行setenforce 0关闭SELinux。

经测试,通过PC连接设备后分步执行以下命令可成功停止充电:

adb shell su
echo 1 > /sys/class/power_supply/battery/input_suspend

但在应用中使用两种方式执行Root命令均无效:

第一种代码实现

package com.example.chargedisabler;

import static android.content.ContentValues.TAG;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;

import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        try {
            Runtime.getRuntime().exec("su -c \"echo 1 > /sys/class/power_supply/battery/input_suspend\"");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

第二种代码实现

package com.example.chargedisabler;

import static android.content.ContentValues.TAG;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;

import java.io.IOException;
import java.io.OutputStream;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        try {
            Process p = Runtime.getRuntime().exec("su");
            OutputStream OStrm = p.getOutputStream();
            OStrm.write(("echo 1 > /sys/class/power_supply/battery/input_suspend\n").getBytes("UTF-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

另外,直接执行adb shell su -c "echo 1 > /sys/class/power_supply/battery/input_suspend"会提示/system/bin/sh: can't create /sys/class/power_supply/battery/input_suspend: Permission denied,但可通过adb shell su -c "cat /sys/class/power_supply/battery/input_suspend"读取该文件值为"0"。

现询问如何在应用内修改该文件值,或是否有通用的设备充电停止方案?


解决方案

1. 修复应用内Root命令执行问题

问题根源

分步执行su再写命令能成功,但su -c直接执行失败,是因为重定向操作>是由shell处理的,若命令参数引号处理不当,重定向会被当前非root的shell解析,而非root环境无写入权限。第二种代码未刷新输出流、未等待命令执行完成,也未处理错误输出,导致命令可能未真正执行。

修正后的代码实现

方式一:使用字符串数组传递su参数

用字符串数组传递命令,避免本地shell解析引号,同时等待执行并检查退出码:

import static android.content.ContentValues.TAG;
import android.util.Log;
import java.io.IOException;

// 在Activity中执行
try {
    Process process = Runtime.getRuntime().exec(new String[]{"su", "-c", "echo 1 > /sys/class/power_supply/battery/input_suspend"});
    int exitCode = process.waitFor();
    if (exitCode != 0) {
        String error = new String(process.getErrorStream().readAllBytes());
        Log.e(TAG, "命令执行失败,退出码:" + exitCode + ",错误信息:" + error);
    } else {
        Log.d(TAG, "充电已成功停止");
    }
} catch (IOException | InterruptedException e) {
    e.printStackTrace();
}

方式二:完善OutputStream写入逻辑

确保刷新输出流、关闭流,等待进程执行完成:

import static android.content.ContentValues.TAG;
import android.util.Log;
import java.io.IOException;
import java.io.OutputStream;

// 在Activity中执行
try {
    Process p = Runtime.getRuntime().exec("su");
    OutputStream os = p.getOutputStream();
    os.write(("echo 1 > /sys/class/power_supply/battery/input_suspend\n").getBytes("UTF-8"));
    os.flush();
    os.close();
    int exitCode = p.waitFor();
    if (exitCode != 0) {
        String error = new String(p.getErrorStream().readAllBytes());
        Log.e(TAG, "错误信息:" + error);
    }
} catch (IOException | InterruptedException e) {
    e.printStackTrace();
}

2. 通用充电停止方案(适配更多设备)

不同厂商设备的充电控制sysfs路径存在差异,可尝试以下方案:

  • 排查其他sysfs节点:通过adb shell su -c ls /sys/class/power_supply/battery/查看所有节点,常见替代路径如/sys/class/power_supply/battery/charging_enabled(写入0停止充电)、/sys/class/power_supply/usb/charging_enabled(控制USB充电)。
  • Magisk模块方案:编写简单的Magisk模块,修改系统充电相关服务或脚本,应用通过调用模块提供的接口控制充电,兼容性更强,避免直接操作sysfs的权限问题。
  • 系统签名API(受限):若能获取系统签名,可调用PowerManager的隐藏API(如setChargingEnabled(false)),但普通第三方应用无法直接使用。

内容的提问来源于stack exchange,提问作者TranslucentFoxHuman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 06:25:11