在处理Android平台的项目时,遇到客户提出的要求预置一个MP4类型的视频文件在系统目录。
经过参考一些文档,处理方案如下:
一、将媒体文件拷贝在out目录
方法类似预置第三方app
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_POST_PROCESS_COMMAND := $(shell mkdir -p $(TARGET_OUT)/media/demo/)
LOCAL_POST_PROCESS_COMMAND := $(shell cp $(LOCAL_PATH)/demo.mp4 $(TARGET_OUT)/media/demo/)
需要拷贝的媒体文件为demo.mp4,预置在system/media/demo/
注意:此时媒体文件还未在系统存储的目录,还需要上层进行一次拷贝动作
二、第一次开机时将该文件拷贝进/storage/emulated/0/Movies
添加权限以及service的注册
--- a/alps/vendor/mediatek/proprietary/packages/providers/MediaProvider/AndroidManifest.xml
+++ b/alps/vendor/mediatek/proprietary/packages/providers/MediaProvider/AndroidManifest.xml
@@ -13,6 +13,7 @@
<uses-permission android:name="android.permission.ACCESS_MTP" />
<uses-permission android:name="android.permission.MANAGE_USERS" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+ <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!-- M: Google protect using am.getRunningAppProcesse get other process info in diff uid,
so we need add this permission to permit process.media, so that DrmHelper can use pid to
query out process name. -->
@@ -82,6 +83,10 @@
<action android:name="mediatek.intent.action.OVERTIME_REMOVAL" />
</intent-filter>
</receiver>
+
+ <service android:name="CopyFileService" android:exported="true">
+
+ </service>
<service android:name="MediaScannerService" android:exported="true">
<intent-filter>
--- a/alps/vendor/mediatek/proprietary/packages/providers/MediaProvider/src/com/android/providers/media/MediaScannerReceiver.java
+++ b/alps/vendor/mediatek/proprietary/packages/providers/MediaProvider/src/com/android/providers/media/MediaScannerReceiver.java
@@ -63,6 +63,18 @@ public class MediaScannerReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
Log.v(TAG, "onReceive action = " + action);
+ SharedPreferences sharedPreferences = context.getSharedPreferences("first_boot",Context.MODE_PRIVATE);
+ boolean first_boot= sharedPreferences.getBoolean("first_boot", true);//如果是第一次开机,则sharedPreferences 的值为空,赋值true
+ if (first_boot) {
+ Log.v(TAG,"->CopyFileService");
+ Intent activityIntent = new Intent();
+ activityIntent.setClassName("com.android.providers.media", "com.android.providers.media.CopyFileService");
+ context.startService(activityIntent);//启动拷贝文件的Services,由于文件比较大,onReceive方法里不能做耗时操作,可以用service解决
+ }
+ SharedPreferences.Editor editor1 = sharedPreferences.edit();
+ editor1.putBoolean("first_boot", false);//赋值false,表示下次开机不用再拷贝了
+ editor1.commit();
+
if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Log.v(TAG,
"onReceive BOOT_COMPLETED,begin to scan internal and external storage.");
(END)
只需要第一次开机进行拷贝就可以,防止后续重启每次都要进行重复操作。
CopyFileService.java
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;
public class CopyFileService extends Service {
private final static String TAG = "Monkey_CopyFileService";
private static String PRELOAD_SRC = Environment.getRootDirectory()+"/media/demo";//*** 这个路径是/system/loadmedia
private static String PRELOAD_DEST = "/storage/emulated/0/Movies";
private CopyThread mCopyThread;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
Log.d(TAG,"CopyFileService---------------");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG,"onStartCommand---------------");
if (mCopyThread == null) {
mCopyThread = new CopyThread();
mCopyThread.start();
}
return Service.START_REDELIVER_INTENT;
}
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 。");
}
Log.e(TAG, "PRELOAD_SRC:"+PRELOAD_SRC);
Log.e(TAG, "PRELOAD_DEST:"+PRELOAD_DEST);
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) {
Log.i(TAG,"f.getName():"+f.getName());
if (f.isDirectory()) {
result &= copyFolder(f, new File(destFile, f.getName()));
} else if(f.isFile()){
result &= copyFile(f, new File(destFile, f.getName()));
}
}
Log.i(TAG,"result:"+result);
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) {
return false;
}
}
}
PRELOAD_DEST 代表的是你要放置的目录这个可以通过adb进行获取。
PRELOAD_SRC 代表的是编译到system/media/demo/这个目录,位于out下。
Android系统预置MP4视频文件的实现方法
本文详细介绍了如何在Android系统中预置一个MP4视频文件。首先,通过Android.mk文件将媒体文件拷贝到out目录,然后在开机时利用service和CopyFileService类将文件拷贝到指定的用户存储目录。此过程只在第一次开机时执行,避免重复操作。涉及到的关键步骤包括修改AndroidManifest.xml以添加权限和服务注册,以及实现CopyFileService来实际执行文件复制。
1119

被折叠的 条评论
为什么被折叠?



