你的位置:首页 > 操作系统

[操作系统]使用AIDL调用远程服务设置系统时间


 

在实际工作中,经常遇到客户需要用代码设置系统时间的需求,但是Android非系统应用是无法设置系统时间的。于是,我设计了一个使用系统签名的时间设置服务,客户通过bind调用服务里的方法就能达到设置时间的目的。

 

这里用到的技术有:

1、Signapk签名

2、AIDL

3、bind service

 

将应用变成系统应用

1、AndroidManifest.

2、使用系统密钥签名。系统签名在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"

 

时间设置服务 CustomServices

 

ICustomServices.aidl 里定义了设置日期和设置时间方法

1 interface ICustomServices {2 3   void setDate(int year,int month,int day);4   void setTime(int hourOfDay, int minute);5 6 }


CustomService.Java  
 1 public class CustomService extends Service { 2   private static final String TAG = CustomService.class.getSimpleName(); 3  4   private MyBinder mBinder; 5  6   @Override 7   public void onCreate() { 8     super.onCreate(); 9 10     if (mBinder == null) {11       mBinder = new MyBinder();12     }13 14   }15 16 17   @Override18   public IBinder onBind(Intent intent) {19     return mBinder;20   }21 22 23   class MyBinder extends ICustomServices.Stub {24 25     @Override26     public void setDate(int year, int month, int day) throws RemoteException {27 28       setDate(CustomService.this, year, month - 1, day);29     }30 31     @Override32     public void setTime(int hourOfDay, int minute) throws RemoteException {33       setTime(CustomService.this, hourOfDay, minute);34     }35 36     void setDate(Context context, int year, int month, int day) {37       Calendar c = Calendar.getInstance();38 39       c.set(Calendar.YEAR, year);40       c.set(Calendar.MONTH, month);41       c.set(Calendar.DAY_OF_MONTH, day);42       long when = c.getTimeInMillis();43 44       if (when / 1000 < Integer.MAX_VALUE) {45         ((AlarmManager) context.getSystemService(Context.ALARM_SERVICE)).setTime(when);46       }47     }48 49     void setTime(Context context, int hourOfDay, int minute) {50       Calendar c = Calendar.getInstance();51 52       c.set(Calendar.HOUR_OF_DAY, hourOfDay);53       c.set(Calendar.MINUTE, minute);54       c.set(Calendar.SECOND, 0);55       c.set(Calendar.MILLISECOND, 0);56       long when = c.getTimeInMillis();57 58       if (when / 1000 < Integer.MAX_VALUE) {59         ((AlarmManager) context.getSystemService(Context.ALARM_SERVICE)).setTime(when);60       }61     }62   }63   64 }

 

 AndroidManifest.

 1 <? 2 <manifest  3   package="com.rs.customservices" android:sharedUserId="android.uid.system"> 4   <application 5     android:allowBackup="true" 6     android:icon="@mipmap/ic_launcher" 7     android:label="@string/app_name" 8     android:supportsRtl="true" 9     android:theme="@style/AppTheme">10 11 12     <service13       android:name="com.rs.customservices.CustomService"14       android:enabled="true"15       android:exported="true">16       <intent-filter>17         <action android:name="com.rs.CustomService" />18       </intent-filter>19     </service>20   </application>21 22 </manifest>

 

 

编译完后使用系统签名将APK文件签名成系统应用。

 

 

 客户程序

 将上面工程中的 ICustomServices.aidl 拷入到客户工程中,注意:包的目录结构也需要拷入。

 

CustomServiceActivity.java

 1 public class CustomServiceActivity extends Activity { 2   private static final String TAG="CustomServiceActivity"; 3  4   ICustomServices mCustomServices; 5   @Override 6   protected void onCreate(Bundle savedInstanceState) { 7     super.onCreate(savedInstanceState); 8     setContentView(R.layout.activity_custom_service); 9 10     Intent intentCust = new Intent();11     intentCust.setAction("com.rs.CustomService");12     //在5.0及以上版本必须要加上这个13     intentCust.setPackage("com.rs.customservices");14     bindService(intentCust, mServiceConnection, Context.BIND_AUTO_CREATE);15   }16 17   ServiceConnection mServiceConnection = new ServiceConnection() {18     @Override19     public void onServiceConnected(ComponentName componentName, IBinder iBinder) {20       mCustomServices = ICustomServices.Stub.asInterface(iBinder);21 22       Log.i(TAG,"mServiceConnection2 onServiceConnected");23 24 25       try {26         mCustomServices.setDate(1999, 5,6);27         mCustomServices.setTime(5,45);28       } catch (RemoteException e) {29         e.printStackTrace();30       }31 32     }33 34     @Override35     public void onServiceDisconnected(ComponentName componentName) {36 37     }38   };39 40 41   @Override42   protected void onDestroy() {43     super.onDestroy();44     unbindService(mServiceConnection);45   }46 }