android 如何在手机第一次开机的时候,把用户放在外置SD卡上的APK自动安装到手机的存储卡。
2012-11-22 09:07
585 查看
1. 将APK放到SD卡上某个目录,如apks_preInstall目录.
(对那些有在AndroidManifest.xml中声明了存储路径是internalOnly的apk,不建议使用这种安装方法)
2. 在第一次开机的时候,等sd卡mount上来,去读取这个目录安装APK
blog.csdn.net/sergeycao
实现代码:
1. 修改\packages\apps\PackageInstaller\AndroidManifest.xml
<!-- 增加一个receiver -->
<receiver android:name=".FirstInstallReceiver">
<intent-filter>
<action android:name="android.intent.action.MEDIA_MOUNTED_FOR_FIRTIME" />
</intent-filter>
</receiver>
<!--end -->
2. \packages\apps\PackageInstaller\src\com\android\packageinstaller下增加FirstInstallReceiver.java文件,用于接收第一次SD卡mount上来的广播,以便安装APK,内容如下:
package com.android.packageinstaller;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.BroadcastReceiver;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.util.Log;
import android.content.pm.IPackageInstallObserver;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import java.io.File;
import android.net.Uri;
public class FirstInstallReceiver extends BroadcastReceiver{
private final String TAG="FirstInstallReceiver";
private String action = "android.intent.action.MEDIA_MOUNTED_FOR_FIRTIME";
/*下面变量apksPath是外置sd卡上的某个路径, 要修改默认预置的apk存放路径,请修改这个路径。
GB版本、GB2、ICS单卡项目:sd卡路径是/mnt/sdcard
GB2双卡项目: 默认外置sd卡路径是/mnt/sdcard/sdcard2, 如打开SDSwap Feature,外置SD卡路径则是:/mnt/sdcard
ICS双卡项目: 默认外置SD卡路径是/mnt/sdcard2, 如打开SDSwap Feature,外置SD卡路径则是:/mnt/sdcard
因此修改要针对不同情况,首先需要确认外置SD卡的路径。
*/
blog.csdn.net/sergeycao
private String apksPath = "/mnt/sdcard/apks_preInstall"; //这个例子假设外置SD卡路径为/mnt/sdcard ///////////////////////
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG,"onReceive:"+intent);
new Thread()
{
public void run() {
try
{
File apksFile = new File(apksPath);
PackageManager pm = context.getPackageManager();
int installFlags = 0;
installFlags |= PackageManager.INSTALL_EXTERNAL;
if(apksFile.exists()) {
File[] files = apksFile.listFiles();
for(File f1:files)
{
String filename = f1.getName();
String type = filename.substring(filename.lastIndexOf(".")+1);
if(type!=null&&type.equals("apk"))
{
Uri mPackageURI = Uri.fromFile(f1);
pm.installPackage(mPackageURI, null, installFlags, null);
}
}
}
}
catch(Exception e)
{
Log.d(TAG,"onReceive:install failed:e:"+e);
}
}
}.start();
}
}
3. 修改mountservice.java, 用于发送第一次开机sd卡mount上来的广播
private void notifyVolumeStateChange(String label, String path, int oldState, int newState) { .....
else if (newState == VolumeState.Mounted) {
//mtk added
String isFirstBoot = SystemProperties.get("persist.sys.mount_is_first");
if(isFirstBoot == null || isFirstBoot.equals(""))
{
Slog.i(TAG, "first boot");
SystemProperties.set("persist.sys.mount_is_first", "DONE");
Intent firIntent = new Intent("android.intent.action.MEDIA_MOUNTED_FOR_FIRTIME");
mContext.sendStickyBroadcast(firIntent);
}
//mtk added
if (DEBUG_EVENTS) Slog.i(TAG, "updating volume state mounted");
updatePublicVolumeState(path, Environment.MEDIA_MOUNTED);
.....
(对那些有在AndroidManifest.xml中声明了存储路径是internalOnly的apk,不建议使用这种安装方法)
2. 在第一次开机的时候,等sd卡mount上来,去读取这个目录安装APK
blog.csdn.net/sergeycao
实现代码:
1. 修改\packages\apps\PackageInstaller\AndroidManifest.xml
<!-- 增加一个receiver -->
<receiver android:name=".FirstInstallReceiver">
<intent-filter>
<action android:name="android.intent.action.MEDIA_MOUNTED_FOR_FIRTIME" />
</intent-filter>
</receiver>
<!--end -->
2. \packages\apps\PackageInstaller\src\com\android\packageinstaller下增加FirstInstallReceiver.java文件,用于接收第一次SD卡mount上来的广播,以便安装APK,内容如下:
package com.android.packageinstaller;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.BroadcastReceiver;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.util.Log;
import android.content.pm.IPackageInstallObserver;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import java.io.File;
import android.net.Uri;
public class FirstInstallReceiver extends BroadcastReceiver{
private final String TAG="FirstInstallReceiver";
private String action = "android.intent.action.MEDIA_MOUNTED_FOR_FIRTIME";
/*下面变量apksPath是外置sd卡上的某个路径, 要修改默认预置的apk存放路径,请修改这个路径。
GB版本、GB2、ICS单卡项目:sd卡路径是/mnt/sdcard
GB2双卡项目: 默认外置sd卡路径是/mnt/sdcard/sdcard2, 如打开SDSwap Feature,外置SD卡路径则是:/mnt/sdcard
ICS双卡项目: 默认外置SD卡路径是/mnt/sdcard2, 如打开SDSwap Feature,外置SD卡路径则是:/mnt/sdcard
因此修改要针对不同情况,首先需要确认外置SD卡的路径。
*/
blog.csdn.net/sergeycao
private String apksPath = "/mnt/sdcard/apks_preInstall"; //这个例子假设外置SD卡路径为/mnt/sdcard ///////////////////////
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG,"onReceive:"+intent);
new Thread()
{
public void run() {
try
{
File apksFile = new File(apksPath);
PackageManager pm = context.getPackageManager();
int installFlags = 0;
installFlags |= PackageManager.INSTALL_EXTERNAL;
if(apksFile.exists()) {
File[] files = apksFile.listFiles();
for(File f1:files)
{
String filename = f1.getName();
String type = filename.substring(filename.lastIndexOf(".")+1);
if(type!=null&&type.equals("apk"))
{
Uri mPackageURI = Uri.fromFile(f1);
pm.installPackage(mPackageURI, null, installFlags, null);
}
}
}
}
catch(Exception e)
{
Log.d(TAG,"onReceive:install failed:e:"+e);
}
}
}.start();
}
}
3. 修改mountservice.java, 用于发送第一次开机sd卡mount上来的广播
private void notifyVolumeStateChange(String label, String path, int oldState, int newState) { .....
else if (newState == VolumeState.Mounted) {
//mtk added
String isFirstBoot = SystemProperties.get("persist.sys.mount_is_first");
if(isFirstBoot == null || isFirstBoot.equals(""))
{
Slog.i(TAG, "first boot");
SystemProperties.set("persist.sys.mount_is_first", "DONE");
Intent firIntent = new Intent("android.intent.action.MEDIA_MOUNTED_FOR_FIRTIME");
mContext.sendStickyBroadcast(firIntent);
}
//mtk added
if (DEBUG_EVENTS) Slog.i(TAG, "updating volume state mounted");
updatePublicVolumeState(path, Environment.MEDIA_MOUNTED);
.....
相关文章推荐
- android 如何在手机第一次开机的时候,把用户放在外置SD卡上的APK自动安装到手机的存储卡。
- 如何在手机第一次开机的时候,把用户放在外置SD卡上的APK预置安装到手机的存储卡
- Android开发实践经验谈:如何让各式手机浏览器可以直接下载apk安装文件且实现自动安装APP
- mac shell脚本自动安装指定apk到安装android手机
- Android如何判断应用程序是安装在手机内存中还是SD卡
- 浅析android中的权限管理--用户安装的apk的uid,gid是如何分配的
- Android如何实现文件下载并自动安装apk包!!!
- 获取android手机内部存储空间和外部存储空间的参数 && 如何决定一个apk的安装位置
- android如何使得电阻屏在第一次开机时自动叫起屏幕校准程序
- Android如何将第三方预装的AP安装在data/app下面,用户可以选择卸载,但是在用户恢复出厂设置后,会再次自动安装
- Android如何将第三方预装的AP安装在data/app下面,用户可以选择卸载,但是在用户恢复出厂设置后,会再次自动安装
- (转)获取android手机内部存储空间和外部存储空间的参数 && 如何决定一个apk的安装位置
- 安卓(Android)手机如何安装APK?
- Android 没有SD卡,利用手机存储下载、自动安装,解决Parse error when parsing manifest问题
- 插入SD卡后自动运行SD卡根目录中的AutoRun.sh以实现动态替换linux logo,init logo和开机动画、安装SD卡中指定目录中的apk到系统中等
- Android无SD卡如何从内存中安装apk?
- 如何自动获取android 安装APK成功后的状态
- android如何使得电阻屏在第一次开机时自动叫起屏幕校准程序
- 如何在android手机上实现app开机自动运行启动(可以打开应用界面)。
- Android 源码编译的系统apk如何安装到手机