赞
踩
前言:客户需要预置他们的应用为系统应用,并且除了他们的应用更新外,无法安装其他应用。
对于预置应用到/system/priv-app/下,可以在makefile中添加:
LOCAL_PRIVILEGED_MODULE := true
正文:
在安装应用时,通过白名单判断是否是用户指定需要安装的应用,如果是,则继续安装;如果不是,则返回未知来源,安装失败。
白名单由一个xml文件构成,放到/system/etc/下:
pkgname_filterlist.xml
<gapps-packages>
<app package="com.customer.packagename"/>
</gapps-packages>
安装的具体流程就不在这里赘述了,最后在PackageManagerService.java中判断:
PackageManagerService.java(/frameworks/base/services/java/com/android/server/pm/)
private void installPackageLI(InstallArgs args,
boolean newInstall, PackageInstalledInfo res) {
...
if (GET_CERTIFICATES && !pp.collectCertificates(pkg, parseFlags)) {
res.returnCode = pp.getParseError();
return;
}
// add {
mFilterPkgNameList.clear();
fillFilterPkgNameList();
for (int i = 0; i < mFilterPkgNameList.size(); i++){
if (pkg.packageName.contains(mFilterPkgNameList.get(i))){
break;
}
if (i == mFilterPkgNameList.size() - 1){
Slog.w(TAG, "Not allowed to install unknown apk!");
res.returnCode = PackageManager.INSTALL_FAILED_UNKNOWN_SOURCES;
return;
}
}
// add }
/* If the installer passed in a manifest digest, compare it now. */
...
}
添加方法fillFilterPkgNameList()
private ArrayList<String> mFilterPkgNameList = new ArrayList<String>();
private void fillFilterPkgNameList() {
File configureDir = Environment.getRootDirectory();
File gappsInfoDir = new File(configureDir, "etc/pkgname_filterlist.xml");
FileInputStream stream = null;
if (gappsInfoDir.exists()) {
try {
stream = new FileInputStream(gappsInfoDir);
XmlPullParser parser = Xml.newPullParser();
parser.setInput(stream, null);
int type;
do {
type = parser.next();
if (type == XmlPullParser.START_TAG) {
String tag = parser.getName();
if ("app".equals(tag)) {
String pkgName = parser.getAttributeValue(null, "package");
mFilterPkgNameList.add(pkgName);
}
}
} while (type != XmlPullParser.END_DOCUMENT);
} catch (FileNotFoundException e) {
Log.w(TAG, "FileNotFoundException " + gappsInfoDir, e);
} catch (NullPointerException e) {
Log.w(TAG, "NullPointerException " + gappsInfoDir, e);
} catch (NumberFormatException e) {
Log.w(TAG, "NumberFormatException " + gappsInfoDir, e);
} catch (XmlPullParserException e) {
Log.w(TAG, "XmlPullParserException " + gappsInfoDir, e);
} catch (IOException e) {
Log.w(TAG, "IOException " + gappsInfoDir, e);
} catch (IndexOutOfBoundsException e) {
Log.w(TAG, "IndexOutOfBoundsException " + gappsInfoDir, e);
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
Log.w(TAG, "IOException " + gappsInfoDir, e);
}
}
}
}
}
另外,为了方便客户,将未知来源默认勾选:
SecuritySettings.java(/packages/apps/Settings/src/com/android/settings/)
private PreferenceScreen createPreferenceHierarchy() {
...
mToggleAppInstallation.setChecked(isNonMarketAppsAllowed());
...
}
private boolean isNonMarketAppsAllowed() {
return Settings.Global.getInt(getContentResolver(),
Settings.Global.INSTALL_NON_MARKET_APPS, 0) > 0;
}
加载global变量:
DatabaseHelper.java(/frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/)
loadBooleanSetting(stmt, Settings.Global.INSTALL_NON_MARKET_APPS,
R.bool.def_install_non_market_apps);
def_install_non_market_apps定义在defaults.xml中(注意项目的overlay)
defaults.xml(/frameworks/base/packages/SettingsProvider/res/values/)
<bool name="def_install_non_market_apps">true</bool>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。