android 下代码设置系统时间

来源:互联网 发布:手机办公室软件下载 编辑:程序博客网 时间:2024/05/22 10:27

 

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

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

 

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,否则无法修改。

 

原创粉丝点击