1、首先把预装的apk拷贝到 /system/app 目录中,并把后缀名改为.nm
2、修改文件 packages\apps\Provision
DefaultActivity.java
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.provision;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import android.content.pm.IPackageInstallObserver;
import android.app.Activity;
import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;
import android.os.SystemProperties;
import java.io.IOException;
import android.util.Log;
import android.app.ActivityManagerNative;
import android.content.res.Configuration;
import android.os.RemoteException;
/**
* Application that sets the provisioned bit, like SetupWizard does.
*/
public class DefaultActivity extends Activity {
private static final String TAG = "PreInstallApps";
private static final String PATH_PREFIX = "/system/app/";
private static final int MSG_INSTALLED_PACKAGE = 0;
private static final int MSG_REMOVE_SELF = 1;
String[] mFileNames;
private int mCount = 0;
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.d(TAG, "Enter handleMessage");
switch (msg.what) {
case MSG_INSTALLED_PACKAGE:
Toast.makeText(DefaultActivity.this, (CharSequence) msg.obj,
Toast.LENGTH_SHORT).show();
if (++mCount >= mFileNames.length) {
Log.d(TAG, "handleMessage MSG_INSTALLED_PACKAGE cnt:"
+ mCount);
Message msgTmp = this.obtainMessage();
msgTmp.what = MSG_REMOVE_SELF;
this.sendMessage(msgTmp);
SystemProperties.set("ctl.start", "whtest");
String mount_rt ;
while(true)
{
mount_rt = SystemProperties.get("init.svc.whtest", "");
Log.d("-----------------------------------** >> **", "mount_rt " + mount_rt);
if(mount_rt != null && mount_rt.equals("stopped"))
{
break;
}
try
{
Thread.sleep(1000);
}catch(Exception ex){
Log.e("-----------------------------------** >> **", "Exception: " + ex.getMessage());
}
}
}
break;
case MSG_REMOVE_SELF:
Toast.makeText(DefaultActivity.this,
(CharSequence) "Install done!", Toast.LENGTH_SHORT)
.show();
Log.d(TAG, "handleMessage MSG_REMOVE_SELF");
// Add a persistent setting to allow other apps to know the
// device has been provisioned.
Settings.Secure.putInt(getContentResolver(),
Settings.Secure.DEVICE_PROVISIONED, 1);
// remove this activity from the package manager.
ComponentName name = new ComponentName(DefaultActivity.this,
DefaultActivity.class);
pm.setComponentEnabledSetting(name,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);
// terminate the activity.
finish();
break;
default:
break;
}
}
};
PackageManager pm;
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
pm = getPackageManager();
settingLargeSysFont();
// Get all apps
mFileNames = getAllAppsFileNames();
if(mFileNames.length <= 0) {
Message msg = mHandler.obtainMessage();
msg.what = MSG_REMOVE_SELF;
mHandler.sendMessage(msg);
}
// Start to install apps
installPackages(mFileNames);
}
class PackageInstallObserver extends IPackageInstallObserver.Stub {
public void packageInstalled(String packageName, int returnCode) {
Message msg = mHandler.obtainMessage();
msg.what = MSG_INSTALLED_PACKAGE;
msg.arg1 = returnCode;
msg.obj = packageName;
mHandler.sendMessage(msg);
Log.d(TAG, "sendMessage MSG_INSTALLED_PACKAGE:" + (String) msg.obj);
}
}
private void installPackages(String[] appsFileName) {
int i;
File file;
Uri mPackageURI;
if(appsFileName.length > 0) {
PackageInstallObserver observer = new PackageInstallObserver();
for (i = 0; i < appsFileName.length; i++) {
file = new File(PATH_PREFIX + appsFileName[i]);// replace with an
// arraylist.
mPackageURI = Uri.fromFile(file);
Log.d(TAG, "Install:" + mPackageURI.toString());
pm.installPackage(mPackageURI, observer, PackageManager.INSTALL_INTERNAL, null);
}
}
}
private String[] getAllAppsFileNames() {
File dir;
String[] fileNames;
dir = new File(PATH_PREFIX);
fileNames = dir.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
if (filename.matches(".*\\.(?i)nm")) {
return true;
}
return false;
}
});
return fileNames;
}
private void settingLargeSysFont() {
try {
Configuration mCurConfig = new Configuration();
try {
mCurConfig.updateFrom(ActivityManagerNative.getDefault().getConfiguration());
} catch (RemoteException re) {
/* ignore */
}
int i = SystemProperties.getInt("ro.default.size",100);
mCurConfig.fontScale=(i*0.01f);
// mCurConfig.fontScale = 1.3f ;
ActivityManagerNative.getDefault().updatePersistentConfiguration(mCurConfig);
} catch (RemoteException re) {
/* ignore */
}
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2008 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.provision"
android:sharedUserId="android.uid.system">
<original-package android:name="com.android.provision" />
<!-- For miscellaneous settings -->
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-permission android:name="android.Manifest.permission.INSTALL_PACKAGES"/>
<application>
<activity android:name="DefaultActivity"
android:excludeFromRecents="true">
<intent-filter android:priority="2">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>