1.把要预置的文件放到代码中:
device/rockchip/rk3588/rk3588s_s/tools/test.mp4
2.将要预置的文件拷贝到内部存储:
device/rockchip/rk3588/rk3588s_s/rk3588s_s.mk
+PRODUCT_COPY_FILES += $(LOCAL_PATH)/tools/test.mp4:$(TARGET_COPY_OUT_ODM)/pre_set/Movies/test.mp4
3.第一次开机时执行拷贝操作,把内部存储中要预置的文件拷贝到外部存储:
packages/providers/MediaProvider
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 336e8eb..7336071 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -98,6 +98,11 @@
</intent-filter>
</receiver>
+ <service
+ android:name="com.android.providers.media.CopyFileService"
+ android:enabled="true"
+ android:exported="true" />
+
<service
android:name="com.android.providers.media.IdleService"
android:exported="true"
diff --git a/src/com/android/providers/media/CopyFileService.java b/src/com/android/providers/media/CopyFileService.java
new file mode 100644
index 0000000..3248646
--- /dev/null
+++ b/src/com/android/providers/media/CopyFileService.java
@@ -0,0 +1,149 @@
+package com.android.providers.media;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Environment;
+import android.os.IBinder;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import android.Manifest;
+
+public class CopyFileService extends Service {
+
+ private final static String TAG = CopyFileService.class.getSimpleName();
+
+ private static String PRELOAD_SRC = Environment.getOdmDirectory() + "/pre_set";//从这个目录拷贝:/odm/pre_set
+ private static String PRELOAD_DEST = Environment.getExternalStorageDirectory().getAbsolutePath();//需要拷贝到的路径:/storage/emulated/0
+
+ private CopyThread mCopyThread;
+
+ private static final int MY_PERMISSION_REQUEST_CODE = 10000;
+ private static final String permission[] = {
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.WRITE_EXTERNAL_STORAGE
+ };
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ if (mCopyThread == null) {
+ mCopyThread = new CopyThread();
+ mCopyThread.start();
+ }
+ return Service.START_REDELIVER_INTENT;
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ }
+
+ public class CopyThread extends Thread {
+ @Override
+ public void run() {
+ if (copyFolder(new File(PRELOAD_SRC), new File(PRELOAD_DEST))) {
+ Log.e(TAG, "doPreloadMedia success !");
+ } else {
+ Log.e(TAG, "doPreloadMedia failed 。");
+ }
+ stopSelf();
+ }
+ }
+
+ public boolean copyFolder(File srcFile, File destFile) {
+ if (!srcFile.isDirectory()) {
+ Log.i(TAG, "srcFile no isDirectory :"+srcFile.getName());
+ return false;
+ }
+ if (!srcFile.canRead()) {
+ Log.i(TAG, "no canRead :"+srcFile.getName());
+
+ }
+ if (!srcFile.canWrite()) {
+ Log.i(TAG, "no canWrite :"+srcFile.getName());
+ }
+
+ if (!destFile.exists()) {
+ boolean r = false;
+ synchronized (this) {
+ r = destFile.mkdirs();
+ }
+ Log.i(TAG, "destFile:exists " + r);
+ }
+ boolean result = true;
+ File[] list = srcFile.listFiles();
+
+ if (list == null) {
+ Log.i(TAG, "copyFolder: list null =" + srcFile.getName());
+ return false;
+ }
+ for (File f : list) {
+ if (f.isDirectory()) {
+ result &= copyFolder(f, new File(destFile, f.getName()));
+ } else if(f.isFile()){
+ result &= copyFile(f, new File(destFile, f.getName()));
+ }
+ }
+ return result;
+ }
+
+ public boolean copyFile(File srcFile, File destFile) {
+ boolean result = false;
+ try {
+ InputStream in = new FileInputStream(srcFile);
+ try {
+ result = copyToFile(in, destFile);
+ } finally {
+ in.close();
+ }
+ } catch (IOException e) {
+ result = false;
+ }
+ return result;
+ }
+
+ /**
+ * Copy data from a source stream to destFile.
+ * Return true if succeed, return false if failed.
+ */
+ public boolean copyToFile(InputStream inputStream, File destFile) {
+ try {
+ if (destFile.exists()) {
+ destFile.delete();
+ }
+ FileOutputStream out = new FileOutputStream(destFile);
+ try {
+ byte[] buffer = new byte[4096];
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) >= 0) {
+ out.write(buffer, 0, bytesRead);
+ }
+ } finally {
+ out.flush();
+ try {
+ out.getFD().sync();
+ } catch (IOException e) {
+ }
+ out.close();
+ }
+ return true;
+ } catch (IOException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+}
diff --git a/src/com/android/providers/media/MediaReceiver.java b/src/com/android/providers/media/MediaReceiver.java
index a10a71d..1b1f1af 100644
--- a/src/com/android/providers/media/MediaReceiver.java
+++ b/src/com/android/providers/media/MediaReceiver.java
@@ -21,8 +21,12 @@ import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
public class MediaReceiver extends BroadcastReceiver {
+
+ private SharedPreferences sharedPreferences;
+
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
@@ -30,6 +34,17 @@ public class MediaReceiver extends BroadcastReceiver {
// Register our idle maintenance service
IdleService.scheduleIdlePass(context);
+ sharedPreferences = context.getSharedPreferences("first_boot",Context.MODE_PRIVATE);
+ boolean first_boot= sharedPreferences.getBoolean("first_boot", true);//如果是第一次开机,则sharedPreferences 的值为空,赋值true
+ if (first_boot) {
+ Intent activityIntent = new Intent(context,CopyFileService.class);
+ context.startService(activityIntent);//启动拷贝文件的Services,由于文件比较大,onReceive方法里不能做耗时操作,可以用service解决
+ }
+
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putBoolean("first_boot", false);//赋值false,表示下次开机不用再拷贝了
+ editor.commit();
+
} else {
// All other operations are heavier-weight, so redirect them through
// service to ensure they have breathing room to finish