尝试使用Runtime.exec()将文件从SD卡复制到系统时,“没有这样的文件或目录”?

时间:2011-08-17 14:53:21

标签: android

我想将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问题,因此路径应该没问题。

花了好几个小时没有线索。有人可以帮帮我吗?非常感谢!

2 个答案:

答案 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;
        }   
    }
}