我想将SD卡中的TTF文件复制到/ system / fonts并更改其权限。
这是我的代码:
try {
Runtime.getRuntime().exec("su");
} catch (IOException e) {
Log.e("Font", "su", e);
}
exec("cp /mnt/sdcard/some.ttf /system/fonts/DroidSans.ttf");
exec("chmod 644 /system/fonts/DroidSans.ttf");
void exec(String cmd) {
Log.e("Font", cmd);
try {
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
Process p = pb.start();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = br.readLine()) != null)
Log.e("Font", cmd + ": " + line);
Log.e("Font", cmd + ": " + p.waitFor());
} catch (Exception e) {
Log.e("Font", cmd, e);
}
}
授予root权限& / system / fonts安装了R / W.但是我仍然有以下例外情况:
E/Font ( 4120): java.io.IOException: Error running exec(). Command: [cp /mnt/sdcard/some.ttf /system/fonts/DroidSans.ttf] Working Directory: null Environment: [ANDROID_SOCKET_zygote=10, ANDROID_BOOTLOGO=1, EXTERNAL_STORAGE=/mnt/sdcard, ANDROID_CACHE=/cache, ANDROID_ASSETS=/system/app, PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin, ASEC_MOUNTPOINT=/mnt/asec, LOOP_MOUNTPOINT=/mnt/obb, BOOTCLASSPATH=/system/framework/core.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/core-junit.jar, SD_EXT_DIRECTORY=/sd-ext, PHONE_STORAGE=/mnt/emmc, ANDROID_DATA=/data, LD_LIBRARY_PATH=/vendor/lib:/system/lib, ANDROID_ROOT=/system, ANDROID_PROPERTY_WORKSPACE=9,32768]
E/Font ( 4120): at java.lang.ProcessManager.exec(ProcessManager.java:224)
E/Font ( 4120): at java.lang.ProcessBuilder.start(ProcessBuilder.java:202)
E/Font ( 4120): at hh.font.FontManagerActivity.exec(FontManagerActivity.java:94)
E/Font ( 4120): at hh.font.FontManagerActivity.onContextItemSelected(FontManagerActivity.java:84)
E/Font ( 4120): at android.app.Activity.onMenuItemSelected(Activity.java:2209)
E/Font ( 4120): at com.android.internal.policy.impl.PhoneWindow$ContextMenuCallback.onMenuItemSelected(PhoneWindow.java:2831)
E/Font ( 4120): at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:143)
E/Font ( 4120): at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:855)
E/Font ( 4120): at com.android.internal.view.menu.MenuDialogHelper.onClick(MenuDialogHelper.java:137)
E/Font ( 4120): at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:873)
E/Font ( 4120): at android.widget.AdapterView.performItemClick(AdapterView.java:284)
E/Font ( 4120): at android.widget.ListView.performItemClick(ListView.java:3513)
E/Font ( 4120): at android.widget.AbsListView$PerformClick.run(AbsListView.java:1849)
E/Font ( 4120): at android.os.Handler.handleCallback(Handler.java:587)
E/Font ( 4120): at android.os.Handler.dispatchMessage(Handler.java:92)
E/Font ( 4120): at android.os.Looper.loop(Looper.java:130)
E/Font ( 4120): at android.app.ActivityThread.main(ActivityThread.java:3835)
E/Font ( 4120): at java.lang.reflect.Method.invokeNative(Native Method)
E/Font ( 4120): at java.lang.reflect.Method.invoke(Method.java:507)
E/Font ( 4120): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
E/Font ( 4120): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
E/Font ( 4120): at dalvik.system.NativeStart.main(Native Method)
E/Font ( 4120): Caused by: java.io.IOException: No such file or directory
E/Font ( 4120): at java.lang.ProcessManager.exec(Native Method)
E/Font ( 4120): at java.lang.ProcessManager.exec(ProcessManager.java:222)
E/Font ( 4120): ... 21 more
我可以执行这些命令而不会出现adb shell问题,因此路径应该没问题。
花了好几个小时没有线索。有人可以帮帮我吗?非常感谢!
答案 0 :(得分:0)
您无法在命令提示符下访问设备/模拟器的SD卡,因为adb具有Android环境的所有资源,因此可以访问
答案 1 :(得分:0)
请参阅以下有关如何使用exec的示例。你应该传递一个字符串数组而不是一个字符串。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import android.util.Log;
public class ExecShell {
private static final int BUFFER_SIZE = 65536;
private static final long DEFAULT_TIMEOUT = 4000L;
public static List<String> executeCommand(Command command, String args) {
return executeCommand(command, args, DEFAULT_TIMEOUT);
}
public static List<String> executeCommand(Command command, String args, long timeout) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Collection<Callable<List<String>>> commands = new ArrayList<Callable<List<String>>>();
Log.d(Global.TAG,"--> Starting command:" + command.name());
commands.add(command.run(args));
try {
List<Future<List<String>>> result = executor.invokeAll(commands);
Log.d(Global.TAG,"--> Command completed: " + command.name());
return result.get(0).get(timeout, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
Log.d(Global.TAG,"--> Command interrupted: " + command.name());
return null;
} catch (ExecutionException e) {
return null;
} catch (TimeoutException e) {
Log.d(Global.TAG,"--> Command timed out: " + command.name());
return null;
}
}
public enum Command {
RESTART_DEVICE("reboot now", 0),
MOUNT_FLASH_DRIVE("mkdir /mnt/usb; chmod 777 /mnt/usb; mount -o rw -t vfat /dev/block/%s1 /mnt/usb", 1),
CHMOD_SERIAL("chmod 777 /dev/ttyUSB*", 0),
SETUP_ETH0_DHCP("netcfg eth0 up; netcfg eth0 dhcp", 0),
SETUP_ETH0_STATIC("netcfg eth0 up; ifconfig eth0 %s", 1),
SETUP_ETH0_DEFAULT_GW("route add default gw %s dev eth0", 1),
OFFLINE_ETH0("netcfg eth0 down", 0),
START_ADBD("start adbd", 0),
STOP_ADBD("stop adbd", 0),
UPDATE_FIRMWARE("cd /mnt/usb; ./update.sh", 0),
KILL_PROCESS("kill %s", 1),
SET_DATETIME("date %s", 1),
GET_APK_MD5("busybox md5sum /data/app/com.atClass.cardShoe-*.apk", 0),
FIND_FLASH_DRIVE("dmesg | busybox grep SCSI | busybox tail -1", 0),
GET_PROCESSES("ps | busybox grep 'com.atClass.cardShoe'", 0),
LINK_DATABASE("",0);
;
private static String SHELL = "/system/bin/self_su1";
private static String SHELL_OPTIONS = "-c";
private final String command;
private final int numArgs;
private Command(String command, int numArgs) {
this.command = command;
this.numArgs = numArgs;
}
public Callable<List<String>> run(final String ... args) {
int argCount = 0;
for (String arg : args) {
if (arg != null) {
++argCount;
}
}
if (argCount != numArgs) {
throw new IllegalArgumentException();
}
return new Callable<List<String>>() {
public List<String> call() throws IOException {
Process p = null;
List<String> result = null;
try {
p = execute(args);
} catch (IOException e) {
Log.d(Global.TAG, String.format("--> Unable to execute command: '%s'", name()));
throw e;
}
if (p != null) {
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(p.getInputStream()), BUFFER_SIZE);
String line = null;
result = new ArrayList<String>();
while ((line = in.readLine()) != null) {
result.add(line);
Log.d(Global.TAG, String.format("--> ExecShell (%s) : %s", name(), line));
}
} catch (IOException e) {
Log.d(Global.TAG, String.format("--> Unable to execute command: '%s'", name()));
throw e;
} finally {
if (in != null) {
in.close();
}
if (p != null) {
p.destroy();
}
}
}
return result;
}
};
}
public Process execute(String ... args) throws IOException {
int argCount = 0;
for (String arg : args) {
if (arg != null) {
++argCount;
}
}
if (argCount != numArgs) {
throw new IllegalArgumentException();
}
String cmd = String.format(command, (Object[]) args);
Log.d(Global.TAG, String.format("Command String: %s", cmd));
Process p = new ProcessBuilder().command(SHELL, SHELL_OPTIONS, cmd).redirectErrorStream(true).start();
return p;
}
}
}