Android源码开发-Android系统时间时区以及12/24小时制等修改方法详解
来源:互联网 发布:有关打击电信网络诈骗 编辑:程序博客网 时间:2024/05/16 08:50
首先声明一下:以下讲解是在Android4.2源码环境下下开发,一般的手机用户仅作参考,不保证实现。
问题提出:我们知道,Android源码出厂默认勾选在有网络情况下“自动更新时间”与“自动更新时区”,所以不需要我们再手动修改时间,即使修改了一联网也会自动重设,但是,应客户需求,在设备没有网络的情况下,就需要手动修改系统时间。这样问题来了,怎么修改系统时间时区?
参考Android“系统设置”源码可知,非一般应用非root用户不能修改系统时间,时区倒是可以随便修改。所以,那些想要在一般的应用中修改时间的人,只能无可奈何了。现在只剩下root权限下的系统应用才可以修改系统时间的可能性了。问题又来了,这个系统应用该怎么编写呢?有以下两种方式:
方式一:在Android系统源码的环境下用make来编译:
1. 在应用程序的AndroidManifest.xml中的manifest节点中加入android:sharedUserId="android.uid.system"这个属性。
2. 修改Android.mk文件,加入LOCAL_CERTIFICATE := platform这一行
3. 使用mm命令来编译,生成的apk就有修改系统时间的权限了。
方式二:像一般的应用一样开发:
1. 同上,加入android:sharedUserId="android.uid.system"这个属性。
2. 使用eclipse编译出apk文件,但是这个apk文件是不能用的。
3. 用压缩软件打开apk文件,删掉META-INF目录下的CERT.SF和CERT.RSA两个文件。
4. 使用目标系统的platform密钥来重新给apk文件签名。
对于以上两种方式,它们各有优劣。首先方式一虽然步奏简单,但在系统源码下不好调试应用,非常麻烦。方式二生成的应用不能直接安装,必须放在源码编译成功的out目录下级的system/app目录下,然后一起生成镜像文件。根据对比,我选择方式二。
对于方式二,问题又来了。假设我成功签名了,然后成功安装了,那么我怎么调用这个app修改时间呢?当然了,我可以利用以下代码实现在一个应用中打开另外一个应用
Intent intent = getPackageManager().getLaunchIntentForPackage("com.android.aidl.service"); startActivity(intent);其中com.android.aidl.service是所要打开的另外一个应用包名。貌似可以实现哦~但是呢,你想想,两个进程,两个应用,大量的修改时间代码以及界面存在另外一个应用,而不是你的主应用中,是不是很难维护呢?更专业的做法是尽量多的把主要工作统一在一个主应用中完成,另外一个应用知识充当简单的接口或者服务的功能即可。所以我的做法是什么呢?我把需要修改时间的应用定义成一个“服务”,并且提供修改系统时间的“接口”,全部界面代码以及实现代码全部在我的主应用中实现,在主应用中传递时间参数给该服务即可。服务进程没有界面,这是简单实现即可。这样间接实现了“一般应用修改系统时间的愿望”。不知道读者有没有看懂,懂不懂没关系,来跟我一起探索“如何在一般应用中”用“不一般的方法”实现“修改系统时间”吧~
一、首先涉及到的知识点是:跨进程调用Service(AIDL Service),具体知识点读者请自行查找资料,这里只提供实现方法,下面是该服务应用的实现。
以上是该服务应用的目录结构,其实代码非常简单,下面我们详细解读。
1、SetDateTime.aidl
package com.android.aidl.service;interface SetDateTime {int setTimeToSystem(long MilliSec); void setDateTime(int year, int month, int day, int hour, int minute) ;}该文件非常简单,定义了一个接口,并定义了两个函数,这两个函数将实现修改系统时间。在写好这个借口之后,工程将自动在gen目录下生产一个对应的java文件,用户必用干涉。
2、SetDateTimeService.java
package com.android.aidl.service;import java.io.DataOutputStream;import java.io.File;import java.io.IOException;import java.util.Calendar;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;import android.os.SystemClock;import android.util.Log;public class SetDataTimeService extends Service { private final static String TAG = "com.ideal.SetDateTimeService"; @Override public IBinder onBind(Intent intent) { Log.v(TAG, "OnBind-ok"); return new MyBinder(); } private class MyBinder extends SetDateTime.Stub{ @Override public int setTimeToSystem(long MilliSec) throws RemoteException{ if( SystemClock.setCurrentTimeMillis(MilliSec)){ Log.v(TAG, "SetTimeToSystem-ok"); return 0; } else{ Log.v(TAG, "SetTimeToSystem-fail"); return -1; } }@Overridepublic void setDateTime(int year, int month, int day, int hour,int minute) throws RemoteException {/********获得root权限********/File rootUser = new File("/system/xbin/ru");Process myProcess=null;DataOutputStream os = null;try{ if(rootUser.exists()) { myProcess=Runtime.getRuntime().exec(rootUser.getAbsolutePath()); } else { myProcess=Runtime.getRuntime().exec("su"); } os = new DataOutputStream(myProcess.getOutputStream()); os.writeBytes("chmod 666 /dev/alarm" + "\n");os.writeBytes("exit $?\n"); try {myProcess.waitFor();} catch (InterruptedException e) {e.printStackTrace();} }catch (IOException e) { e.printStackTrace(); Log.v(TAG, "getroot-fail"); }finally { if(os != null) { try {os.close();} catch (IOException e) {e.printStackTrace();} } }/**********设置系统时间***********/ Calendar c = Calendar.getInstance(); c.set(Calendar.YEAR, year); c.set(Calendar.MONTH, month-1); c.set(Calendar.DAY_OF_MONTH, day); c.set(Calendar.HOUR_OF_DAY, hour); c.set(Calendar.MINUTE, minute); long when = c.getTimeInMillis(); if (when / 1000 < Integer.MAX_VALUE) { if(SystemClock.setCurrentTimeMillis(when)){ Log.v(TAG, "setDateAndTime-ok"); }else{ Log.v(TAG, "setDateAndTime-fail"); } } long now = Calendar.getInstance().getTimeInMillis(); if(now - when > 1000) Log.v(TAG, "setDateAndTime-fail");} }}该文件定义了一个服务,并实现了接口的两个方法。该两个方法都可以修改系统时间。该段代码是“系统时间设置”代码的简化版,原理是一致的。
3、AndroidManifext.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.aidl.service" android:versionCode="1" android:versionName="1.0" android:sharedUserId="android.uid.system"> <uses-sdk android:minSdkVersion="8" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <service android:name="SetDataTimeService"> <intent-filter> <action android:name="com.android.aidl.setdatetime" /> </intent-filter> </service> </application></manifest>这个文件声明了一个服务,并制定了系统参数android:sharedUserId="android.uid.system",当指定了这个系统参数之后,这个应用将不会像一般的应用一样安装了,只能在源码中的out目录下的system/app目录下运行安装。
以上是服务应用的讲解,如果不是很理解的话请点击下载服务应用源码。
使用eclipse编译出apk文件,但是这个apk文件是不能用的。用压缩软件打开apk文件,删掉META-INF目录下的CERT.SF和CERT.RSA两个文件,然后给apk文件签名。签名方式如下:将源码目录下的build/target/product/secure目录下的platform.pk8和platform.x509.pem两个目录拷出来,放在与签名工具sighapk.jar同一个目录,signapk.jar请点击这里下载,然后打开命令行窗口执行:
java -jar signapk.jar platform.x509.pem platform.pk8 source.apk signed.apk其中souce.apk是已经删掉META-INF目录下的CERT.SF和CERT.RSA两个文件的应用,signed.apk是得到的签过名的应用,可以随便命名。然后将这个应用直接拷贝到out目录下级的system/app目录下即可,在制作镜像时自然后包进去。到目前为止,我们的服务应用已经跑起来了,那么我们一般的应用该怎么调用这个服务实现进程之间的通信呢?请往下看:
二、一般应用调用服务应用实现”进程通信“
以上是一般应用的结构,从上图可以看出,要想调用调用前面系统应用目录下的应用时,必须按着正确的步奏来。首先第一个是新建一个一模一样的aidl文件,接口代码也一样,包结构也一模一样,建好之后工程会自动在gen目录生成相应的java文件。完成以上步奏就可以直接调用该服务接口实现修修改系统时间了哦。一下是代码实现:
private String actionName = "com.android.aidl.setdatetime";private SetDateTime setDateTime=null;private ServiceConnection connection =new ServiceConnection(){@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {setDateTime = SetDateTime.Stub.asInterface(service);Log.v(TAG, "onServiceConnected-ok");if(setDateTime==null){return;}try {//setDateTime.setTimeToSystem(System.currentTimeMillis()+24*3600*1000);setDateTime.setDateTime(2013, 4, 4, 4, 4);} catch (RemoteException e) {e.printStackTrace();}}@Override public void onServiceDisconnected(ComponentName name) {setDateTime=null;Log.v(TAG, "onServiceDisconnected-ok");}};@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_flash);Intent intent = new Intent(actionName);bindService(intent, connection, Context.BIND_AUTO_CREATE);Log.v(TAG, "bindService-ok");}以上只是整个java文件的一部分代码,该部分代码包含了所有的修改系统时间的实现代码。在退出该界面之后记得解绑服务。
@Overrideprotected void onDestroy() {super.onDestroy(); this.unbindService(connection);}
三、时区的修改一般的应用都可以实现,很简单
1、首先在AndroidManifext.xml中假如权限
<uses-permission android:name="android.permission.SET_TIME_ZONE"/>2、设置相应的时区
AlarmManager timeZone= (AlarmManager)getSystemService(ALARM_SERVICE);timeZone.setTimeZone("Asia/Shanghai");
四、修改系统12/24小时制
Android源码中默认使用12小时制,如果想要改成24小时制的话,方法如下:
1、到源码目录 frameworks/base/packages/SettingsProvider/res/values/defaults.xml 文件中增加一行:
<string name="time_12_24">24</string>
2、到源码目录 frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java文件中的loadSystemSettings()方法中增加下面一行设置时间格式:
loadStringSetting(stmt,Settings.System.TIME_12_24,R.string.time_12_24);
3、可以用以下代码查看系统是否是24小时制:
ContentResolver c = getContentResolver(); String strTimeFormat = android.provider.Settings.System.getString(c,android.provider.Settings.System.TIME_12_24); if(strTimeFormat.equals("24")){Log.e("time", "The system time is 24 hour format"); }else{Log.e("time", "The system time is 12 hour format"); }
以上基本全部讲解完了。这种方式确实很好,间接实现了通过一般的应用来修改系统时间。用户可以完全在一般应用中编写界面与实现函数,只是最后简单调用一下服务应用即可修改时间。该方法现在已经运用到我的项目中来了,效果不错~祝你成功~如果在过程中出错或者有什么疑问,欢迎在线留言哦,我一定热心回答~
全部源码工具打包在这里- Android源码开发-Android系统时间时区以及12/24小时制等修改方法详解
- Android系统修改时间格式为24小时制
- Android 修改系统默认时间为24小时制
- Android系统时间24小时制12小时制
- Android 修改系统默认时间为24小时格式
- Android 修改系统默认时间为24小时格式 .
- CentOS 系统时间和时区查看以及修改的方法
- CentOS 系统时间和时区查看以及修改的方法
- Android获得系统时间(24小时制)
- Android获得系统时间(24小时制)
- android获取系统时间24小时制
- Android开发之获取系统12/24小时制的时间
- Android获取当前系统时间(12/24小时制)
- 如何获取Android系统时间是24小时制还是12小时制
- 如何获取Android系统时间是24小时制还是12小时制
- 获取Android系统时间是24小时制还是12小时制
- 如何获取Android系统时间是24小时制还是12小时制
- 如何获取Android系统时间是24小时制还是12小时制
- PHP中include和require的区别详解
- iOS开发工具——网络封包分析工具Charles
- pthread_key_t和pthread_key_create()详解
- 黑马程序员—OC语言基础—构造方法和分类
- 学习笔记:Git内部原理
- Android源码开发-Android系统时间时区以及12/24小时制等修改方法详解
- 一些常用的正则表达式
- “No implementation found for native…… ”--Jni调用注意事项
- Web应用界面设计规范
- 插入排序
- ArcGIS教程:3D 数据的基础知识
- inux 命令行 光标移动技巧
- POJ1741 Tree
- hibernate二级缓存攻略