您的位置:首页 > 移动开发 > Android开发

android 下代码设置系统时间

2013-08-10 12:51 363 查看
最近做项目涉及到了怎么设置系统时间,起初觉得这个问题是很简单的,但是事实并非如此,在这个问题上卡壳了好几天。

试了好几种方法,总算有了一定的成果。

1:

第一反应是查看android setting的源码(packages\apps\Settings),因为系统-日期和时间里面有能够设置时间的选项。

在其DateTimeSettings里面发现了它是利用 Calendar和系统类SystemClock来进行设置时间,我依样画葫芦,却提示Unable to open alarm driver。

百度了下,对于这个问题众说缤纷,有说是缺少权限配置文件,有说是通过把应用改为系统应用,来达到使用这个api的目的。把应用改为系统应用肯定不能满足我的需求,于是我又去试了下前面的方法,我在配置文件里面增加了这个权限。

Xml代码

<uses-permission android:name="android.permission.WRITE_SETTINGS" />

结果依然提示我 Unable to open alarm driver。

2:

因为我的应用允许Root,所以我第二反应是想到利用linux命令来进行设置系统时间。但是我试了好几种方法,

系统时间虽然可以设置,但是却出现了时间不准确,甚至系统崩溃重启的情况。

Java代码

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

RootTools.sendShell("date -s 20130409 \n",10);

RootTools.sendShell("date -s 1311420409637 \n",10);

3:

搜遍了所有的中文android论坛,对于这个问题的解决方法都是千篇一律,后来总算在stackoverflow上面找到了答案。

给出的解决方法有二种,一种是修改系统的/dev/alarm文件,一种是直接利用date -s 命令。

方法一:

Java代码

public void setTime(long time) {

if (ShellInterface.isSuAvailable()) {

ShellInterface.runCommand("chmod 666 /dev/alarm");

SystemClock.setCurrentTimeMillis(time);

}

}

Java代码

public class ShellInterface {

private static final String TAG = "ShellInterface";

private static String shell;

// uid=0(root) gid=0(root)

private static final Pattern UID_PATTERN = Pattern.compile("^uid=(\\d+).*?");

enum OUTPUT {

STDOUT,

STDERR,

BOTH

}

private static final String EXIT = "exit\n";

private static final String[] SU_COMMANDS = new String[]{

"su",

"/system/xbin/su",

"/system/bin/su"

};

private static final String[] TEST_COMMANDS = new String[]{

"id",

"/system/xbin/id",

"/system/bin/id"

};

public static synchronized boolean isSuAvailable() {

if (shell == null) {

checkSu();

}

return shell != null;

}

public static synchronized void setShell(String shell) {

ShellInterface.shell = shell;

}

private static boolean checkSu() {

for (String command : SU_COMMANDS) {

shell = command;

if (isRootUid()) return true;

}

shell = null;

return false;

}

private static boolean isRootUid() {

String out = null;

for (String command : TEST_COMMANDS) {

out = getProcessOutput(command);

if (out != null && out.length() > 0) break;

}

if (out == null || out.length() == 0) return false;

Matcher matcher = UID_PATTERN.matcher(out);

if (matcher.matches()) {

if ("0".equals(matcher.group(1))) {

return true;

}

}

return false;

}

public static String getProcessOutput(String command) {

try {

return _runCommand(command, OUTPUT.STDERR);

} catch (IOException ignored) {

return null;

}

}

public static boolean runCommand(String command) {

try {

_runCommand(command, OUTPUT.BOTH);

return true;

} catch (IOException ignored) {

return false;

}

}

private static String _runCommand(String command, OUTPUT o) throws IOException {

DataOutputStream os = null;

Process process = null;

try {

process = Runtime.getRuntime().exec(shell);

os = new DataOutputStream(process.getOutputStream());

InputStreamHandler sh = sinkProcessOutput(process, o);

os.writeBytes(command + '\n');

os.flush();

os.writeBytes(EXIT);

os.flush();

process.waitFor();

if (sh != null) {

String output = sh.getOutput();

Log.d(TAG, command + " output: " + output);

return output;

} else {

return null;

}

} catch (Exception e) {

final String msg = e.getMessage();

Log.e(TAG, "runCommand error: " + msg);

throw new IOException(msg);

} finally {

try {

if (os != null) {

os.close();

}

if (process != null) {

process.destroy();

}

} catch (Exception ignored) {}

}

}

public static InputStreamHandler sinkProcessOutput(Process p, OUTPUT o) {

InputStreamHandler output = null;

switch (o) {

case STDOUT:

output = new InputStreamHandler(p.getErrorStream(), false);

new InputStreamHandler(p.getInputStream(), true);

break;

case STDERR:

output = new InputStreamHandler(p.getInputStream(), false);

new InputStreamHandler(p.getErrorStream(), true);

break;

case BOTH:

new InputStreamHandler(p.getInputStream(), true);

new InputStreamHandler(p.getErrorStream(), true);

break;

}

return output;

}

private static class InputStreamHandler extends Thread {

private final InputStream stream;

private final boolean sink;

StringBuffer output;

public String getOutput() {

return output.toString();

}

InputStreamHandler(InputStream stream, boolean sink) {

this.sink = sink;

this.stream = stream;

start();

}

@Override

public void run() {

try {

if (sink) {

while (stream.read() != -1) {}

} else {

output = new StringBuffer();

BufferedReader b = new BufferedReader(new InputStreamReader(stream));

String s;

while ((s = b.readLine()) != null) {

output.append(s);

}

}

} catch (IOException ignored) {}

}

}

}

方法二:

Java代码

public void setDate()

{

try {

Process process = Runtime.getRuntime().exec("su");

DataOutputStream os = new DataOutputStream(process.getOutputStream());

os.writeBytes("date -s 20120419.024012; \n");

} catch (Exception e) {

Log.d(TAG,"error=="+e.toString());

e.printStackTrace();

}

}

总结:出现了这种问题,归根究底在于我自己的知识积累不够,对于linux命令熟悉度不高,应当多加强多接触这方面的知识,弥补不足。

提示,测试机器必须ROOT,否则无法修改。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: