功能需求:限定Mtp目录的大小,比如4G,即使映射的外置存储空间(SD-card)大于4GB,目录容量也就4G,小于 4G的外部存储则按原大小处理。
软件平台:android 4.4.2
看到这个需求,一开始的考虑是单给mtp映射到外置sdcard的目录建立一个4G的分区,当然这不是相对较优的解决方向;后来查看向相关目录拷贝文件时,mtpserver的log看,mtpservice一直在查看存储介质剩余的存储空间,于是打算从获取剩余空间的jni接口中做这层管卡。
--- a/frameworks/av/media/mtp/MtpStorage.cpp
+++ b/frameworks/av/media/mtp/MtpStorage.cpp
@@ -35,6 +35,8 @@
namespace android {
+const uint64_t gbSpace = 1024L*1024L*1024L; //1GB
+
MtpStorage::MtpStorage(MtpStorageID id, const char* filePath,
const char* description, uint64_t reserveSpace,
bool removable, uint64_t maxFileSize)
@@ -87,15 +89,42 @@ uint64_t MtpStorage::getMaxCapacity() {
}
uint64_t MtpStorage::getFreeSpace() {
+ int i = 0;
+ FILE *fstream=NULL;
+ char buff[128];
+ char length[128];
struct statfs stat;
+ memset(buff, 0, sizeof(buff));
+ memset(length, 0, sizeof(length));
+
if (statfs(getPath(), &stat))
return -1;
uint64_t freeSpace = (uint64_t)stat.f_bavail * (uint64_t)stat.f_bsize;
+ if (4*gbSpace > freeSpace)
+ return (freeSpace > mReserveSpace ? freeSpace - mReserveSpace : 0);
//ALPS00120037,Added for USB Develpment debug, more log for more debuging help
+ //sxlog_printf(ANDROID_LOG_INFO, "MtpStorage",
+ // "MtpStorage::getFreeSpace: freeSpace = %lld, mReserveSpace = %lld \n", freeSpace, mReserveSpace);
+ //ALPS00120037,Added for USB Develpment debug, more log for more debuging help
+
+ fstream = popen("du -sk /storage/sdcard1/music/","r");
+ if (NULL != fgets(buff, sizeof(buff), fstream)) {
+ while (buff[i] != '\t') {
+ length[i] = buff[i];
+ i++;
+ }
+ }
+ pclose(fstream);
+
+ unsigned long long used = ((unsigned long long)strtol(length, NULL, 10)) * 1024L;//此处注意红色标示部分,否则到2G的时候,就显示空间为0了(溢出错误)。
+ if (4*gbSpace <= used) {
+ return 0;
+ } else {
+ freeSpace = (4*gbSpace) - used;
+ }
sxlog_printf(ANDROID_LOG_INFO, "MtpStorage",
"MtpStorage::getFreeSpace: freeSpace = %lld, mReserveSpace = %lld \n", freeSpace, mReserveSpace);
return (freeSpace > mReserveSpace ? freeSpace - mReserveSpace : 0);
}
过程还是比较简洁的,但最终达到的效果却是不容小视。。。