如何在手机第一次开机的时候,把用户放在外置SD卡上的APK预置安装到手机的存储卡

[Description]

如何在手机第一次开机的时候,把用户放在外置SD卡上的APK自动安装到手机的存储卡。

[Solution]

设计思路

1.   APK放到SD卡上某个目录,如apks_preInstall目录.

对那些有在AndroidManifest.xml中声明了存储路径是internalOnlyapk不建议使用这种安装方法

2.    在第一次开机的时候,等sdmount上来,去读取这个目录安装APK

 

实现代码:

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版本、GB2ICS单卡项目:sd卡路径是/mnt/sdcard

                 GB2双卡项目默认外置sd卡路径是/mnt/sdcard/sdcard2,如打开SDSwap Feature,外置SD卡路径则是:/mnt/sdcard

                 ICS双卡项目:默认外置SD卡路径是/mnt/sdcard2,如打开SDSwap Feature,外置SD卡路径则是:/mnt/sdcard

                 因此修改要针对不同情况,首先需要确认外置SD卡的路径。

              */

 

         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) {

         //mtkadded

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);

          }

         //mtkadded

          

 if (DEBUG_EVENTS)  Slog.i(TAG, "updating volume state mounted");

              updatePublicVolumeState(path, Environment.MEDIA_MOUNTED);

.....

你可能感兴趣的:(android,apk,sd)