网上看了一下相关的知识,转载一下两篇相关的文章

(一)

在 android 的API中有提供 SystemClock.setCurrentTimeMillis()函数来修改系统时间,可惜无论你怎么调用这个函数都是没用的,无论模拟器还是真机,在logcat中总会得到"Unable to open alarm driver: Permission denied ".这个函数需要root权限或者运行与系统进程中才可以用。

        本来以为就没有办法在应用程序这一层改系统时间了,后来在网上搜了好久,知道这个目的还是可以达到的。

        第一个方法简单点,不过需要在Android系统源码的环境下用make来编译:

        1. 在应用程序的AndroidManifest.xml中的manifest节点中加入android:sharedUserId="android.uid.system"这个属性。

        2. 修改Android.mk文件,加入LOCAL_CERTIFICATE := platform这一行

        3. 使用mm命令来编译,生成的apk就有修改系统时间的权限了。

        第二个方法麻烦点,不过不用开虚拟机跑到源码环境下用make来编译:

        1. 同上,加入android:sharedUserId="android.uid.system"这个属性。

        2. 使用eclipse编译出apk文件,但是这个apk文件是不能用的。

        3. 用压缩软件打开apk文件,删掉META-INF目录下的CERT.SF和CERT.RSA两个文件。

        4. 使用目标系统的platform密钥来重新给apk文件签名。这步比较麻烦,首先找到密钥文件,在我的Android源码目录中的位置是"build/target/product/security",下面的platform.pk8和platform.x509.pem两个文件。然后用Android提供的Signapk工具来签名,signapk的源代码是在"build/tools/signapk"下,用法为"signapk platform.x509.pem platform.pk8 input.apk output.apk",文件名最好使用绝对路径防止找不到,也可以修改源代码直接使用。

        这样最后得到的apk和第一个方法是一样的。

        最后解释一下原理,首先加入android:sharedUserId="android.uid.system"这个属性。通过Shared User id,拥有同一个User id的多个APK可以配置成运行在同一个进程中。那么把程序的UID配成android.uid.system,也就是要让程序运行在系统进程中,这样就有权限来修改系统时间了。

        只是加入UID还不够,如果这时候安装APK的话发现无法安装,提示签名不符,原因是程序想要运行在系统进程中还要有目标系统的platform key,就是上面第二个方法提到的platform.pk8和platform.x509.pem两个文件。用这两个key签名后apk才真正可以放入系统进程中。第一个方法中加入LOCAL_CERTIFICATE := platform其实就是用这两个key来签名。

        这也有一个问题,就是这样生成的程序只有在原始的Android系统或者是自己编译的系统中才可以用,因为这样的系统才可以拿到platform.pk8和platform.x509.pem两个文件。要是别家公司做的Android上连安装都安装不了。试试原始的Android中的key来签名,程序在模拟器上运行OK,不过放到G3上安装直接提示"Package ... has no signatures that match those in shared user android.uid.system",这样也是保护了系统的安全。

        最最后还说下,这个android:sharedUserId属性不只可以把apk放到系统进程中,也可以配置多个APK运行在一个进程中,这样可以共享数据,应该会很有用的。

 

 

 

(二)

昨天写应用,涉及到需要修改系统时间等操作,查了一下Android 的设置源码,里面的一个方法如下:

 

   public void onDateSet(DatePicker view, int year, int month, int day) {
        Calendar c = Calendar.getInstance();

        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, month);
        c.set(Calendar.DAY_OF_MONTH, day);
        long when = c.getTimeInMillis();

        if (when / 1000 < Integer.MAX_VALUE) {
            SystemClock.setCurrentTimeMillis(when);
        }
        updateTimeAndDateDisplay();
    }

 

从上面的 Android 应用程序源码可以看出,修改系统日期需要为Calendar 设置年月日,然后通过调用 SystemClock.setCurrentTimeMillis 方法,设置系统日期,既然源码是这样写的,那我们也依样画葫芦来学一下吧,下面是通过使用datePicker修改日期的代码:

 

canlendar = Calendar.getInstance();
                    year = datePicker.getYear();
                    month = datePicker.getMonth();
                    day = datePicker.getDayOfMonth();
                    canlendar.set(Calendar.YEAR, year);
                    canlendar.set(Calendar.MONTH, month);
                    canlendar.set(Calendar.DAY_OF_MONTH, day);
                    long when = canlendar.getTimeInMillis();
                    if (when / 1000 < Integer.MAX_VALUE) {
                        SystemClock.setCurrentTimeMillis(when);
                        tv_date.setText(canlendar.get(Calendar.YEAR) + "/"
                                + ((canlendar.get(Calendar.MONTH) + 1)) + "/"
                                + canlendar.get(Calendar.DAY_OF_MONTH));
                    }

 

 

Tip:每次需要使用Calendar 必须获得一次实例,否则会它会使用上一次获取实例的日期格式,修改的时候可能会有点小问题

可是,照着上面的代码敲了之后,运行却出现如下的警告:

 

网上查了一下,说SystemClock.setCurrentTimeMillis  这个函数需要root 权限或者运行在系统进程中才可以用,通过参考了这一篇文章我得到了解决办法:http://dev.10086.cn/blog/?uid-49302-action-viewspace-itemid-907 ,不过这篇文章的第二个办法说得有点不是很清楚,这里我重新为大家详细说一下

先进入 Android 源码目录 F:/android_source/build/target/product/security ,具体机器目录自己选择。找到 【platform.pk8】和【platform.x509.pem】这两个文件,这里为了方便将它们复制到根目录,如:F:/sign 文件夹内,本来下一步就是需要打包jar 包了,不过里我们在android系统的源码内找到 out 编绎目录下

signApk.jar 这个包,可以自行打jar 包或者下载我这个jar 包都是可以的,下载地址:signapk 请自行将后缀名改为.jar 格式,把此jar 包放于F:/sign  文件内,打开dos 操作界面,定们到F:/sign,如下:,接着输入如下命令:java -jar signapk.jar platform.x509.pem platform.pk8 test.apk testnew.apk ,在dos 命令名如下图:,其中set.apk 是指我们要签名的原始文件apk,后面setnew.apk 是指我们签名后输出的apk文件的名称

Tip:在签名的时候必须将set.apk事先用rar 文件打开,进入META-INF目录下,将CERT.SF和CERT.RSA这两个文件删除掉,再执行如上操作。到了这一步,程序己经可以正常安装了。

如果提示 FaiLure [INSTALL_FAILED_ALREADY_EXISTS],请使用如下命令,将应用程序移除:,uninstall 后面字符是指应用程序所在的包名,再运行adb install [package name] 就可以安装成功。

Tip:不要忘了在你的manifest文件下注册android:sharedUserId="android.uid.system" 。

如果你照着如上的步骤一步一步写的话,保证可以成功修改系统的时间或者日期等操作。

 

 

 

本文出自 “Terry_龙” 博客,请务必保留此出处http://terryblog.blog.51cto.com/1764499/389843

更多相关文章

  1. Android原生项目集成React Native踩坑记
  2. 网络对讲机C#服务器 Android客户端(三) android客户端代码分析 附
  3. Android入门教程(四)之------Android工程目录结构介绍
  4. Application Fundamentals
  5. Intent的匹配与查找
  6. Android入门教程(四)之-------->Android工程目录结构介绍
  7. Android(安卓)NDK 简介
  8. Ubuntu编译Android使用的FFmpeg
  9. NPM 和webpack 的基础使用

随机推荐

  1. android testing (三)————关于Android(
  2. android 自定义基于组件的注册用户对话框
  3. Android再按一次退出程序实现方法
  4. android 重命名文件
  5. Android利用tcpdump抓包
  6. Android(安卓)旧电视退出效果
  7. Android连接网络
  8. 3. android 自动完成文本框
  9. Android(安卓)TextView 字体描边
  10. Android(安卓)监听手机GPS打开状态实现代