Android中一次性安装多个应用。

之前客户需要实现这么一个需求:


现在有一个外壳,当用户安装了这个外壳之后,集成在外壳里面的其他几个应用也安装好了。

说白了就是需要实现静默安装,类似于流氓软件。

当然想法是好的,如果真的有那么容易实现,Android的安全机制实在是......太弱了。


后来,使用了另外一个解决方案

就是在安装了这个外壳之后,监听这个外壳安装好的广播,然后在该检测广播的onReceive方法里面检测其余的几个apk是否已经安装,如果

安装了就依次检测下一个应用是否安装,如果没有,则启动安装器提示安装。


不过前提条件是需要知道其余几个app的包名。

首先贴几个需要用到的方法:


package com.example.androidinstalltestdemo;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.List;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;

/**
 * <p>
 * </p>
 * 
 * @author xiangxm
 */
public class Common {

	/**
	 * 检查模块是否安装
	 * 
	 * @param context
	 * @param packageName
	 *            需要检查的包名称
	 * @return
	 */
	public static boolean isAppInstalled(Context context, String packageName) {
		final PackageManager packageManager = context.getPackageManager();
		// 获取所有已安装程序的包信息
		List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
		for (int i = 0; i < pinfo.size(); i++) {
			if (pinfo.get(i).packageName.equalsIgnoreCase(packageName)) {
				return true;
			} else {

				continue;
			}
		}
		return false;
	}

	/**
	 * 拷贝apk到应用 目录
	 * 
	 * @param ctx
	 *            Context变量
	 */
	public static void copyApkFromAssets(Context ctx, String apkName) {
		// 所有集成的APK所存放的位置。
		String filePath = "/assets/" + apkName;
		try {
			// 从assets读取文件流
			InputStream is = ctx.getClass().getResourceAsStream(filePath);
			// 将该文件流写入到本应用程序的私有数据区this.getFilesDir().getPath();
			FileOutputStream fos = ctx.openFileOutput(apkName,
					Context.MODE_PRIVATE + Context.MODE_WORLD_READABLE);

			byte[] buffer = new byte[1024];
			int len = 0;
			while ((len = is.read(buffer)) != -1) {
				fos.write(buffer, 0, len);
			}
			fos.flush();
			is.close();
			fos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * 安装apk apk路径在:/data/data/" + ctx.getPackageName() + "/files下
	 * 
	 * @param ctx
	 * @param apkName
	 */
	public static void Install_New(Context ctx, String apkName) {

		// 如果文件不存在则再次复制一遍
		File file = new File(ctx.getFilesDir().getPath() + "/" + apkName);
		if (!file.exists()) {
			// 拷贝apk文件到应用目录下。
			copyApkFromAssets(ctx, apkName);
		}
		Intent intentInstall = new Intent();
		// 开始启动安装器安装apk
		intentInstall.setAction(android.content.Intent.ACTION_VIEW);
		intentInstall.setDataAndType(Uri.fromFile(file),
				"application/vnd.android.package-archive");
		intentInstall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

		ctx.startActivity(intentInstall);
	}

	/**
	 * 安装apk apk们的路径:/data/data/" + ctx.getPackageName() + "/files下
	 * 
	 * @param ctx
	 * @param apkName
	 */
	public static void installApk_New(Context ctx, String apkName) {
		// 应用目录
		File f = new File(ctx.getFilesDir().getPath() + "/" + apkName);

		// 下面执行安装
		Intent intent = new Intent();
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		intent.setAction(Intent.ACTION_VIEW);
		String type = "application/vnd.android.package-archive";
		intent.setDataAndType(Uri.fromFile(f), type);
		ctx.startActivity(intent);

	}
}


大致思路:  启动app时候就检测需要的几个app是否已经安装,然后根据实际情况拷贝apk文件到对应目录。

监听安装完成的广播。

        <!-- 注册安装apk监听 -->
        <receiver android:name=".InstallDeleteBroadcastReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_ADDED" />
                <action android:name="android.intent.action.PACKAGE_REMOVED" />
                <action android:name="android.intent.action.PACKAGE_REPLACED" />

                <data android:scheme="package" >
                </data>
            </intent-filter>
        </receiver>

这里就不贴测试工程了/


检查是否是平板:

	/**
	 * 判断是否是平板
	 * 
	 * @param context
	 * @return
	 */
	public static boolean isTablet(Context context) {
		return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE;
	}

时间关系。。。。。不写了/。。。。。 明天出差到期,可以回家了。

你可能感兴趣的:(Android开发)