1 、通过内置Sys APPS 实现资源预置

                  1 、通过内置Sys APPS 实现资源预置

简介:

设计之初idea来自于的资源copy demo。在此基础上完成了自己的一点想法。请大家评审、讨论,给予宝贵的改进意见。

 

一、文件 tree :

1 、通过内置Sys APPS 实现资源预置

 

二、流程图 与 相关点

      Adroid 的 init & vold 过程, encrypt 过程、 mnt 分区挂载过程。

      注意:

      1、boot_complete 和 media_mount 广播对顺序;

      2、cts 检查权限,pm (packageName)等;

      3、apk disable 之后,settings中是否还存在包;

 

三,主要功能代码:

1、修改配置文件 :/xxx/config/sdm660_64/xxx/shipping/xxx.mk

添加:

PRODUCT_PACKAGES +=  MediaFilePreset

 

2、设置Android.mk

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(call all-java-files-under, src)

$(warning $(LOCAL_SRC_FILES))

LOCAL_JAVA_LIBRARIES += telephony-common
LOCAL_PACKAGE_NAME := MediaFilePreset
LOCAL_CERTIFICATE := platform
LOCAL_MANIFEST_FILE := AndroidManifest.xml
LOCAL_PRIVILEGED_MODULE := true

include $(BUILD_PACKAGE)
include $(call all-makefiles-under,$(LOCAL_PATH))

 

3、写AndroidManifest.xml

<!--
/*
 * Code by author  at  2018.08.02.
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.demo.mediafilepreset"
    android:sharedUserId="android.uid.system" >
    <uses-sdk
        android:minSdkVersion="9"
        android:targetSdkVersion="23" />

    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        >
        <receiver android:name="com.demo.mediafilepreset.MediaFilePresetReceiver">
            <intent-filter >
                <action android:name="android.intent.action.MEDIA_MOUNTED"/>
                <data android:scheme="file">
                </data>
            </intent-filter>
        </receiver>
    </application>

</manifest>

4、定义theme

packages/MediaFilePreset/res/values-v11/styles.xml    

    <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
        <!-- API 11 theme customizations can go here. -->
    </style>


packages/MediaFilePreset/res/values-v14/styles.xml

    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
        <!-- API 14 theme customizations can go here. -->
    </style>


packages/MediaFilePreset/res/values/styles.xml

    <style name="AppBaseTheme" parent="android:Theme.Light">
        <!--
            Theme customizations available in newer API levels can go in
            res/values-vXX/styles.xml, while customizations related to
            backward-compatibility can go here.
        -->
    </style>

    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">
        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
    </style>

 

5. 功能代码

./custorm/packages/MediaFIlePreset/src/com/android/mediafilepreset/MediaFilePresetReceiver.java

package com.hq.mediafilepreset;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.Intent;
import android.media.MediaScanner;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipEntry;

public class MediaFilePresetReceiver extends BroadcastReceiver {
    private static final String TAG = "MediaFilePresetReceiver";
    private static final String ACTIVITIES[] = {
        "com.hq.mediafilepreset.MediaFilePresetReceiver",
    };
    private static final String DCIM_ZIP = "DCIM.zip";
    private static final String MUSIC_ZIP = "Music.zip";
    //private static final String MOVIES_ZIP = "Movies.zip";

    private static final String DCIM_PATH = "/mnt/sdcard/DCIM/";
    private static final String MUSIC_PATH = "/mnt/sdcard/Music/";
    //private static final String MOVIES_PATH = "/mnt/sdcard/Movies/";

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(TAG,"onReceive:"+ intent.getAction());
        boolean copied = false;
        boolean sdCardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
        if (sdCardExist) {
            try {
                copied = compressZip(context,DCIM_ZIP,DCIM_PATH)
                    && compressZip(context,MUSIC_ZIP,MUSIC_PATH)
                    /*&& compressZip(context,MOVIES_ZIP,MOVIES_PATH)*/;

            } catch (IOException ioe){
                ioe.printStackTrace();
            }
        }else {
            Log.w(TAG,"sdcard mount failed");
        }

        if (copied) {
            Log.i(TAG, "disable activities");
            for (int i = 0; i < ACTIVITIES.length; i++) {
                disableComponent(context, ACTIVITIES[i]);
            }
            disableComponent(context, "com.hq.mediafilepreset.MediaFilePresetReceiver");
        }
    }


    /**
     * Uncompress assets zip files.
     * @param context
     * @param fileName
     * @param outputDirectory
     * @throws IOException
     */
    private boolean compressZip(Context context, String fileName, String outputDirectory) throws IOException {
        File file = new File(outputDirectory);
        if (!file.exists()) {
            Log.d(TAG,"creat the folder");
            file.mkdirs();
        }

        InputStream inputStream = context.getAssets().open(fileName);
        ZipInputStream zipInputStream = new ZipInputStream(inputStream);
        ZipEntry zipEntry = zipInputStream.getNextEntry();
        byte[] buffer = new byte[1024 * 100];
        int count = 0;
        while (zipEntry != null) {
            if (zipEntry.isDirectory()) {
                file = new File(outputDirectory + File.separator + zipEntry.getName());
                if (!file.exists()) {
                    Log.d(TAG,"creat the subfolder");
                    file.mkdir();
                }

            } else {
                file = new File(outputDirectory + File.separator + zipEntry.getName());
                if (file.exists() && file.length() < zipEntry.getSize()) {
                    file.delete();
                    file.createNewFile();
                    FileOutputStream fileOutputStream = new FileOutputStream(file);
                    while ((count = zipInputStream.read(buffer)) > 0) {
                        fileOutputStream.write(buffer, 0, count);
                    }
                    fileOutputStream.close();
                } else {
                    file.createNewFile();
                    FileOutputStream fileOutputStream = new FileOutputStream(file);
                    while ((count = zipInputStream.read(buffer)) > 0) {
                        fileOutputStream.write(buffer, 0, count);
                    }
                    fileOutputStream.close();
                }
                //touchMediaScan(context, file.getPath());
            }
            zipEntry = zipInputStream.getNextEntry();
        }
        zipInputStream.close();

        touchMediaScan(context, outputDirectory);
        return true;
    }


    private void disableComponent(Context context, String klass) {
        Log.i(TAG,"disableComponent");
        ComponentName name = new ComponentName(context, klass);
        PackageManager pm = context.getPackageManager();
        pm.setComponentEnabledSetting(name,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);
    }

    private void touchMediaScan(Context context, String dir) {
        Log.i(TAG,"Touch Media Scanner");

        //Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        //scanIntent.setData(Uri.fromFile(new File(path)));
        //context.sendBroadcast(scanIntent);
        MediaScanner mMediaScanner = new MediaScanner(context, "external");
        String[] directories = null;
        if (dir == DCIM_PATH) {
            directories = new String[] {"/storage/emulated/0/DCIM/"};
        } else if (dir == MUSIC_PATH) {
            directories = new String[] {"/storage/emulated/0/Music/"};
        } else {
            directories = new String[] {dir};
        }

        if (directories != null) {
            mMediaScanner.scanDirectories(directories);
        }
    }
}