設定內部sdcard儲存下限,sdcard儲存下限
在Android中,內部儲存有一部分地區是必須預留出來供系統運行應用程式的。
但是在Android原生設計中沒有考慮這點,內部儲存是可以完全填充滿的。
這樣會導致系統在運行程式,尤其是需要操作資料庫的程式時,出現SQLiteFullException的錯誤。
解決的方法是在sdcard.c檔案中加入一個限制,比如限制當儲存低於100M時,不再允許第三方應用儲存媒體檔案。
如adb push 檔案到/storage/sdcard0/中,或錄音,拍照等儲存到/storage/sdcard0/中。
這100M的空間專門預留出來保證系統程式的運行。
sdcard.c檔案所在路徑為源碼中:system/com/sdcard/sdcard.c
修改完後可直接編譯sdcard目錄,會產生一個sdcard檔案,push到系統/system/bin目錄下,重啟後即生效。
修改代碼:
1.在sdcard.c的開始位置定義宏
// begin:SQLiteFullException happened when device memory is empty.
#define LIMIT_USEDATA_SIZE (100 * 1024 * 1024)
// end:SQLiteFullException happened when device memory is empty.
2.在fuse結構體中增加變數free_blksize
struct fuse {
......
__u64 next_generation;
// begin:SQLiteFullException happened when device memory is empty.
__u64 free_blksize;
// end:SQLiteFullException happened when device memory is empty.
......
}
3.在init方法中做初始化
static void fuse_init(struct fuse *fuse, int fd, const char *source_path,
gid_t write_gid, derive_t derive, bool split_perms) {
......
fuse->next_generation = 0;
// begin:SQLiteFullException happened when device memory is empty.
struct statfs stat;
if (statfs(source_path, &stat) < 0) {
fuse->free_blksize = 0;
} else {
fuse->free_blksize = stat.f_bfree * stat.f_bsize;
}
// end:SQLiteFullException happened when device memory is empty.
fuse->derive = derive;
......
}
4.在handle_write方法中實現功能
static int handle_write(struct fuse* fuse, struct fuse_handler* handler,
const struct fuse_in_header* hdr, const struct fuse_write_in* req,
const void* buffer) {
......
TRACE("[%d] WRITE %p(%d) %u@%llu\n", handler->token,
h, h->fd, req->size, req->offset);
// begin:SQLiteFullException happened when device memory is empty.
if (!strncmp(fuse->root.name, "/data/media", fuse->root.namelen)) {
pthread_mutex_lock(&fuse->lock);
fuse->free_blksize -= req->size;
pthread_mutex_unlock(&fuse->lock);
if (fuse->free_blksize <= LIMIT_USEDATA_SIZE) {
struct statfs stat;
if (statfs(fuse->root.name, &stat) < 0) {
fuse->free_blksize = 0;
return -errno;
} else {
pthread_mutex_lock(&fuse->lock);
fuse->free_blksize = stat.f_bfree * stat.f_bsize;
pthread_mutex_unlock(&fuse->lock);
}
errno = ENOSPC;
return -errno;
}
}
// end:SQLiteFullException happened when device memory is empty.
res = pwrite64(h->fd, buffer, req->size, req->offset);
......
}
我手機的首選安裝位置有這三個選項:1裝置內部儲存,2內部SD卡,3由系統確認-內部儲存與內部
內部儲存是指data分區。內部sd卡是指sdcard分區。
你手機上的儲存晶片被分成 system (系統檔案在這裡)、cache(緩衝)、data、sdcard、recovery(復原模式程式在這裡)等幾個分區。
其中data和sdcard是用來安裝程式的。
sdcard就是指SD卡,當有內建sd卡的時候他就是內建sd卡,當手機不具備內建sd卡的時候,他指你插入的tf卡。
data就是內部儲存。
華為C8650(安卓23) 設定裡有個“首選安裝位置”裡邊有三項:1手機內部儲存 2可卸載的SD卡
安裝到記憶卡比較好。如果裝在手機記憶體裡你的手機就會越來越卡 運行緩慢
設定 應用程式管理 軟體裝在什麼位置都可以查看