Android_StorageManager storage module

Preface

Some time ago, I listened to the training on the external storage module of Android StorageManager. Now I have organized the knowledge I understand and expanded my knowledge horizontally.

The StorageManager module is a module that manages Android storage, so we will explain it from two aspects:

Understand internal storage vs. external storage in Android

Understand the StorageManager module structure

text

The main text will be described from two aspects:

1. Storage in Android

This part is more complicated, and there are different opinions. This part will summarize the relevant knowledge stored in combination with official documents.

2. Introduction to Storage storage module

This part mainly describes Storage storage from an architectural perspective.

1 Storage in Android

1.1 Android storage classification

Android provides two types of physical storage locations: internal storage and external storage.

Internal storage is generally smaller than external storage, however, internal storage is more reliable for data storage.

Internal storage directories: Includes dedicated locations for storing persistent files, as well as other locations for storing cached data. Access to these locations by other apps is blocked and, in Android 10 (API level 29) and higher, they are encrypted. These characteristics make these locations ideal for storing sensitive data that only the application itself can access.

External storage directories: include dedicated locations for storing persistent files, as well as other locations for storing cached data. Although other applications can access these directories with the appropriate permissions, the files stored in these directories are used only by the corresponding application. If it is clear that other applications can access the data, the data should be stored in a shared storage portion of external space. It means that the external storage space also has a public part and a private part. The data in the public part can be accessed by all applications under certain permissions, and the data in the private part can only be accessed by the application itself.

1.2 Internal storage

Concept: Internal storage is not memory. Files stored in internal storage can only be accessed by yourself, and all files created by an application are in the directory of its application package name. That is, the internal storage files created by the application are associated with the application, and the internal storage space is very limited. , when the app is uninstalled, the internally stored files will also be deleted to manage valuable internal storage space.

For applications, the internal storage space is the "/data/data" directory (the actual mounting is under the /data/user/0/ path, and /data/data/ is a soft link to the former), which contains two folders Worth paying attention to.

  • /data/app/ folder: stores apk files of all apps
  • /data/data/ folder: Inside is the package name of the app, which stores application-related data (shared_prefs, database, files, cache)

1.3 External storage

Concept: External storage is easy to confuse because there are differences between older Android versions and newer Android versions. Before Android 4.4, the storage space that comes with the phone is used as internal storage, and the expanded SD card is the most external storage. But starting from the Android 4.4 system, Google has conceptually divided Android's body storage into two parts: "Internal" and "External Internal".

[External link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-xBntJj97-1689213386723) (D:\Workspace\Module Analysis\Native-StorageManager\Picture\Body Storage Structure. png)]

External storage space also has public and private distinctions. For applications, external public spaces can be shared under certain permissions, while external private spaces cannot be accessed by applications.

For removable storage media, such as SD cards, USB disks and other external storage spaces, the external storage is the storage directory or mnt directory.

Regarding the mounting of external storage, it has been changing in Android native, and it has been mounted at /storage/emulated/legacy after Android 4.2. The previous /storage/sdcard0, /sdcard, and /mnt/sdcard are all soft links to /storage/emulated/legacy.

The "0" that appears in the path is due to Google adding the concept of multiple users.

1.3.1 User space file system FUSE

FUSE, implementing filesystems in user space, implementing file systems in user space. In order to achieve more flexible permission management capabilities, Android introduced the fuse file system.

Simply put, users can customize and implement their own file system in user space through fuse. Fuse itself is a function provided by the kernel. After the kernel turns on fuse support, it will generate a fuse device node in the /dev directory. The application layer can complete the user-mode file system through this device node.

libfuse is a library that encapsulates the fuse function. It provides a series of APIs so that users can use the fuse function more conveniently and simply. The following content is explained based on libfuse. After the fuse driver is loaded, you can see that a device file named fuse has been created in /dev/. fuse uses this device to transfer information between user mode and the kernel.

The figure below is a flow chart of a simple APP accessing/storage the U disk below. It can be seen that the APP's reading and writing of U disk files is not directly opened within the APP process, but is accessed through FuseDaemon. document. Therefore, when the USB disk is removed, if the used APP does not release the occupied file handle in time, the MediaProvider will be killed instead of the used APP being killed directly. However, since MediaProvider implements FuseDasemon, when MediaProvider is killed, it will restart and re-establish the fuse connection. At this time, all mounted storage will be unmounted and remounted.

Insert image description here

1.4 Internal and external storage paths of applications in Android

For application access to internal and external storage paths, output the following api.

public void getStorageDirPath() {
    
    
        // 获取应用在内部存储的根路径
        File file = getContext().getDataDir();
        Log.d("Context().getDataDir()" , file.getAbsolutePath());

        // 获取应用在内部存储的 files 路径
        File file1 = getContext().getFilesDir();
        Log.d("Context().getFilesDir()" , file1.getAbsolutePath());

        // 获取应用在内部存储的 cache 缓存路径
        File file2 = getContext().getCacheDir();
        Log.d("Context().getCacheDir()" , file2.getAbsolutePath());

        // 获取外部存储根路径
        File file3 = Environment.getExternalStorageDirectory();
        Log.d("Environment.getExternalStorageDirectory()" , file3.getAbsolutePath());

        // 获取外部存储具体公共路径
        /*
         * 参数如下:
         * public static String DIRECTORY_MUSIC = "Music"
         * public static String DIRECTORY_PODCASTS = "Podcasts"
         * public static String DIRECTORY_RINGTONES = "Ringtones"
         * public static String DIRECTORY_ALARMS = "Alarms"
         * public static String DIRECTORY_NOTIFICATIONS = "Notifications"
         * public static String DIRECTORY_PICTURES = "Pictures"
         * public static String DIRECTORY_MOVIES = "Movies"
         * public static String DIRECTORY_DOWNLOADS = "Download"
         * public static String DIRECTORY_DCIM = "DCIM"
         * public static String DIRECTORY_DOCUMENTS = "Documents"
         */
        File file4 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
        Log.d("Environment.getExternalStoragePublicDirectory(Music)" , file4.getAbsolutePath());

        // 获取应用在外部存储中的 Files 路径
        File[] file5 = getContext().getExternalFilesDirs("");
        for (File file6 : file5) {
    
    
            Log.d("Context().getExternalFilesDirs()" , file6.getAbsolutePath());
        }

        // 获取应用在外部存储中的 cache 缓存路径
        File file7 = getContext().getExternalCacheDir();
        Log.d("Context().getExternalCacheDir()" , file7.getAbsolutePath());
    }

--------------------------------------------------------------------------------------------------------------------------------

输出如下:
D/Context().getDataDir(): /data/user/0/com.example.androidstudiotest
D/Context().getFilesDir(): /data/user/0/com.example.androidstudiotest/files
D/Context().getCacheDir(): /data/user/0/com.example.androidstudiotest/cache
D/Environment.getExternalStorageDirectory(): /storage/emulated/0
D/Environment.getExternalStoragePublicDirectory(Music): /storage/emulated/0/Music
D/Context().getExternalFilesDirs(): /storage/emulated/0/Android/data/com.example.androidstudiotest/files
D/Context().getExternalCacheDir(): /storage/emulated/0/Android/data/com.example.androidstudiotest/cache

The form is as follows:

storage area method Remark
Internal Storage Internal Storage Context.getDataDir() /data/user/0/package name
Context.getFilesDir() /data/user/0/package name/files
Context.getCacheDir() /data/user/0/package name/cache
External Storage External Storage Environment.getExternalStoragePublicDirectory(String type) /storage/emulated/0/type
Context.getExternalFilesDirs() /storage/emulated/0/Android/data/包名/files
Context.getExternalCacheDir() /storage/emulated/0/Android/data/package name/cache

2 Storage storage module introduction

2.1 StorageManagerService Introduction

Android external storage space is jointly managed by the Vold service and the StorageManagerService system service. Mounting of external entity storage volumes is handled by Vold, and when ready, it is reported to the StorageManagerService, which then makes it available to applications. In Android 8.0 and later, the MountService service has been renamed StorageManagerServic, and the communication between StorageManagerService and Vold has been changed from socket to binder.

Code path distribution:

Hierarchy main document code path
application api interface layer StorageManager.java android/frameworks/base/core/java/android/os/storage
System framework layer StorageManagerService.java android/frameworks/base/services/core/java/com/android/server
Services VoldNativeService.cpp android/system/violence

2.2 StorageManagerService architecture

The following figure is the architecture diagram of StorageManagerService

Insert image description here

The figure describes the architecture of the StorageManagerService module. The upper-layer framework service StorageManagerService is started by SystemService in the startup phase; the Vold service is started by the rc file in the init phase. StorageManagerService interacts with the Vold service through aidl. The VoldNativeService in the Vold service implements the aidl interface. It is used as the server of aidl, but the actual processing is implemented in VolumeManager. NetlinkManager is the processing class for reporting communication events between VolumeManager and the driver layer. NetlinkManager establishes socket communication with the kernel and monitors the uevent event of the kernel. When the driver detects that a USB disk is connected, When incoming/outgoing, the event event will be reported to NetlinkHandler for processing, and the mount/unmount process will be entered.

Android provides a series of broadcasts through which applications can obtain the current U disk status.

broadcast meaning
Intent.ACTION_MEDIA_CHECKING examine
Intent.ACTION_MEDIA_MOUNTED mount
Intent.ACTION_MEDIA_UNMOUNTABLE Unable to mount, mount failed (commonly, the USB disk mounting node already exists and cannot be mounted further)
Intent.ACTION_MEDIA_EJECT Hardware eject
Intent.ACTION_MEDIA_UNMOUNTED uninstall
Intent.ACTION_MEDIA_REMOVED The volume has been removed, which means the removal process has been completed.
Intent.ACTION_MEDIA_BAD_REMOVAL The volume has been removed, which means that the removal process has been completed. The node may not have been uninstalled cleanly.

2.3 StorageManagerService startup

2.3.1 SystemServer stage

SystemServer will start the StorageManagerService service in the startOtherServices() stage

路径:android/frameworks/base/services/java/com/android/server/SystemServer.java

	traceBeginAndSlog("StartStorageManagerService");
	try {
    
    
    	/*
   		 * NotificationManagerService is dependant on StorageManagerService,
   		 * (for media / usb notifications) so we must start StorageManagerService first.
   		 */
    	mSystemServiceManager.startService(STORAGE_MANAGER_SERVICE_CLASS);
        storageManager = IStorageManager.Stub.asInterface( ServiceManager.getService("mount"));
    } catch (Throwable e) {
    
    
         reportWtf("starting StorageManagerService", e);
    }
    traceEnd();
    traceBeginAndSlog("StartStorageStatsService");
2.3.2 StorageManagerService stage
2.3.2.1 onStart()

SystemManagerService builds LifeCycle through reflection and calls the onStart() method

路径:android/frameworks/base/services/core/java/com/android/server/StorageManagerService.java

public static class Lifecycle extends SystemService {
    
    
        private StorageManagerService mStorageManagerService;

        public Lifecycle(Context context) {
    
    
            super(context);
        }

        @Override
        public void onStart() {
    
    
            mStorageManagerService = new StorageManagerService(getContext());
            publishBinderService("mount", mStorageManagerService);
            mStorageManagerService.start();
        }

        @Override
        public void onBootPhase(int phase) {
    
    
            if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
    
    
                mStorageManagerService.servicesReady();
            } else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
    
    
                mStorageManagerService.systemReady();
            } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
    
    
                mStorageManagerService.bootCompleted();
            }
        }

        @Override
        public void onSwitchUser(int userHandle) {
    
    
            mStorageManagerService.mCurrentUserId = userHandle;
        }

        @Override
        public void onUnlockUser(int userHandle) {
    
    
            mStorageManagerService.onUnlockUser(userHandle);
        }

        @Override
        public void onCleanupUser(int userHandle) {
    
    
            mStorageManagerService.onCleanupUser(userHandle);
        }
    }
2.3.2.2 StorageManagerService()

StorageManagerService starts

路径:android/frameworks/base/services/core/java/com/android/server/StorageManagerService.java

public StorageManagerService(Context context) {
    
    
        sSelf = this;

        // 前面先是读取一些属性状态,其中关于FUSE下面会稍微介绍一下
        // Snapshot feature flag used for this boot
        SystemProperties.set(StorageManager.PROP_ISOLATED_STORAGE_SNAPSHOT, Boolean.toString(
                SystemProperties.getBoolean(StorageManager.PROP_ISOLATED_STORAGE, true)));

        // If there is no value in the property yet (first boot after data wipe), this value may be
        // incorrect until #updateFusePropFromSettings where we set the correct value and reboot if
        // different
        mIsFuseEnabled = SystemProperties.getBoolean(PROP_FUSE, DEFAULT_FUSE_ENABLED);
        mVoldAppDataIsolationEnabled = mIsFuseEnabled && SystemProperties.getBoolean(
                ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY, false);
        mContext = context;
        mResolver = mContext.getContentResolver();
        mCallbacks = new Callbacks(FgThread.get().getLooper());
        mLockPatternUtils = new LockPatternUtils(mContext);
        // 创建名为“StorageManagerService”的线程,并创建对应的Handler
        HandlerThread hthread = new HandlerThread(TAG);
        hthread.start();
        mHandler = new StorageManagerServiceHandler(hthread.getLooper());
        // mObbActionHandler对应“android.io”线程
        // Add OBB Action Handler to StorageManagerService thread.
        mObbActionHandler = new ObbActionHandler(IoThread.get().getLooper());

        mStorageSessionController = new StorageSessionController(mContext, mIsFuseEnabled);

        // 启动installd服务
        mInstaller = new Installer(mContext);
        mInstaller.onStart();

        // Initialize the last-fstrim tracking if necessary
        File dataDir = Environment.getDataDirectory();
        File systemDir = new File(dataDir, "system");
        mLastMaintenanceFile = new File(systemDir, LAST_FSTRIM_FILE);
        //判断/data/system/last-fstrim文件,不存在则创建,存在则更新最后修改时间
        if (!mLastMaintenanceFile.exists()) {
    
    
            // Not setting mLastMaintenance here means that we will force an
            // fstrim during reboot following the OTA that installs this code.
            try {
    
    
                (new FileOutputStream(mLastMaintenanceFile)).close();
            } catch (IOException e) {
    
    
                Slog.e(TAG, "Unable to create fstrim record " + mLastMaintenanceFile.getPath());
            }
        } else {
    
    
            mLastMaintenance = mLastMaintenanceFile.lastModified();
        }

        // 读取data/system/storage.xml配置
        mSettingsFile = new AtomicFile(
                new File(Environment.getDataSystemDirectory(), "storage.xml"), "storage-settings");

        synchronized (mLock) {
    
    
            readSettingsLocked();
        }

        LocalServices.addService(StorageManagerInternal.class, mStorageManagerInternal);

        // 监听ACTION_USER_ADDED、ACTION_USER_REMOVED广播
        final IntentFilter userFilter = new IntentFilter();
        userFilter.addAction(Intent.ACTION_USER_ADDED);
        userFilter.addAction(Intent.ACTION_USER_REMOVED);
        mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);

        // 内部私有volume的路径为/data,该volume通过dumpsys mount是不会显示的
        synchronized (mLock) {
    
    
            addInternalVolumeLocked();
        }

        // Add ourself to the Watchdog monitors if enabled.
        if (WATCHDOG_ENABLE) {
    
    
            Watchdog.getInstance().addMonitor(this);
        }

        // 汽车应用支持
        mIsAutomotive = context.getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_AUTOMOTIVE);
    }

2.4 AIDL interface layer

Vold's aidl file is defined in the /system/vold/binder/android/os/ directory. There are three files: IVold.aidl, IVoldListener.aidl, and IVoldTaskListener.aidl.

Insert image description here

The compilation in Android.bp is as follows

路径:android/system/vold/Android.bp

filegroup {
    name: "vold_aidl",
    srcs: [
        "binder/android/os/IVold.aidl",
        "binder/android/os/IVoldListener.aidl",
        "binder/android/os/IVoldTaskListener.aidl",
    ],
}

cc_library_static {
    name: "libvold_binder",
    defaults: ["vold_default_flags"],

    srcs: [
        ":vold_aidl",
    ],
    shared_libs: [
        "libbinder",
        "libutils",
    ],
    aidl: {
        local_include_dirs: ["binder"],
        include_dirs: ["frameworks/native/aidl/binder"],
        export_aidl_headers: true,
    },
}

2.5 Vold service layer

2.5.1 Vold module compilation
路径:android/system/vold/Android.bp

cc_binary {
    name: "vold",
    defaults: [
        "vold_default_flags",
        "vold_default_libs",
    ],

    srcs: ["main.cpp"],
    static_libs: ["libvold"],
    product_variables: {
        arc: {
            static_libs: [
                "arc_services_aidl",
                "libarcappfuse",
                "libarcobbvolume",
            ],
        },
    },
    init_rc: [
        "vold.rc",
        "wait_for_keymaster.rc",
    ],

    required: [
        "mke2fs",
        "vold_prepare_subdirs",
        "wait_for_keymaster",
    ],

    shared_libs: [
        "[email protected]",
        "libhidltransport",
    ],
}

From the compilation configuration of the vold binary executable file, we found that the service entry is the main.cpp file, and the startup rc is vold.rc and wait_for_keymaster.rc.

2.5.2 rc file
路径:android/system/vold/vold.rc

service vold /system/bin/vold \
        --blkid_context=u:r:blkid:s0 --blkid_untrusted_context=u:r:blkid_untrusted:s0 \
        --fsck_context=u:r:fsck:s0 --fsck_untrusted_context=u:r:fsck_untrusted:s0
    class core
    ioprio be 2
    writepid /dev/cpuset/foreground/tasks
    shutdown critical
    group root reserved_disk

The vold executable file is in the /system/bin/ directory.

2.5.3 Service entry file

The entry file of vold service is main.cpp.

路径:android/system/vold/main.cpp

int main(int argc, char** argv) {
    
    // 初始化日志相关服务
    atrace_set_tracing_enabled(false);
    setenv("ANDROID_LOG_TAGS", "*:d", 1);  // Do not submit with verbose logs enabled
    android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));

    LOG(INFO) << "Vold 3.0 (the awakening) firing up";

    ATRACE_BEGIN("main");

    LOG(DEBUG) << "Detected support for:"
               << (android::vold::IsFilesystemSupported("exfat") ? " exfat" : "")
               << (android::vold::IsFilesystemSupported("ext4") ? " ext4" : "")
               << (android::vold::IsFilesystemSupported("f2fs") ? " f2fs" : "")
               << (android::vold::IsFilesystemSupported("ntfs") ? " ntfs" : "")
               << (android::vold::IsFilesystemSupported("vfat") ? " vfat" : "");

	// 定义 VolumeManager、NetlinkManager 对象
	// VolumeManager 对象是 vold aidl 接口的实际处理类
	// NetlinkManager 对象是用于 vold 与 驱动通信的处理类
    VolumeManager* vm;
    NetlinkManager* nm;

    parse_args(argc, argv);

    sehandle = selinux_android_file_context_handle();
    if (sehandle) {
        selinux_android_set_sehandle(sehandle);
    }

    // 建立 /dev/block/vold 文件夹
    mkdir("/dev/block/vold", 0755);

    /* For when cryptfs checks and mounts an encrypted filesystem */
    klog_set_level(6);

    /* Create our singleton managers */
    // 初始化 VolumeManager 对象
    if (!(vm = VolumeManager::Instance())) {
        LOG(ERROR) << "Unable to create VolumeManager";
        exit(1);
    }

    // 初始化 NetlinkManager 对象
    if (!(nm = NetlinkManager::Instance())) {
        LOG(ERROR) << "Unable to create NetlinkManager";
        exit(1);
    }

    // debug 属性
    if (android::base::GetBoolProperty("vold.debug", false)) {
        vm->setDebug(true);
    }

    // 调用 volumeManager 类的 start() 函数
    if (vm->start()) {
        PLOG(ERROR) << "Unable to start VolumeManager";
        exit(1);
    }

    bool has_adoptable;
    bool has_quota;
    bool has_reserved;

    if (process_config(vm, &has_adoptable, &has_quota, &has_reserved)) {
        PLOG(ERROR) << "Error reading configuration... continuing anyways";
    }

    android::hardware::configureRpcThreadpool(1, false /* callerWillJoin */);

    ATRACE_BEGIN("VoldNativeService::start");
    if (android::vold::VoldNativeService::start() != android::OK) {
        LOG(ERROR) << "Unable to start VoldNativeService";
        exit(1);
    }
    ATRACE_END();

    LOG(DEBUG) << "VoldNativeService::start() completed OK";

    ATRACE_BEGIN("NetlinkManager::start");
    // 调用 NetlinkManager 对象的 start() 函数
    if (nm->start()) {
        PLOG(ERROR) << "Unable to start NetlinkManager";
        exit(1);
    }
    ATRACE_END();

    // This call should go after listeners are started to avoid
    // a deadlock between vold and init (see b/34278978 for details)
    android::base::SetProperty("vold.has_adoptable", has_adoptable ? "1" : "0");
    android::base::SetProperty("vold.has_quota", has_quota ? "1" : "0");
    android::base::SetProperty("vold.has_reserved", has_reserved ? "1" : "0");

    // Do coldboot here so it won't block booting,
    // also the cold boot is needed in case we have flash drive
    // connected before Vold launched
    coldboot("/sys/block");

    ATRACE_END();

    android::IPCThreadState::self()->joinThreadPool();
    LOG(INFO) << "vold shutting down";

    exit(0);
}

3 ChatGPT conversations

Q: Android internal storage and external storage

ChatGPT Answer:

The storage of Android devices is divided into internal storage and external storage.

Internal storage refers to a device's fixed storage space, usually the device's flash memory. It is used to store operating system, application and user data. Internal storage is private to the application, and only the application itself can access and modify its stored data. Internal storage usually has a smaller capacity, generally ranging from tens to hundreds of GB.

External storage refers to removable storage media on the device, such as SD cards or USB storage devices. It is used to store the user's media files, documents, and other data. External storage is shared among applications, and multiple applications can access and modify externally stored data. External storage usually has a larger capacity and can be expanded according to the user's needs.

In Android, you can save and get data using internal storage and external storage. For an application's private data, internal storage is typically used; for user-shared data, external storage can be used. You can use Android's API to access and manage internally stored and externally stored data.

Q: What is the difference between Android internal storage and external storage?

ChatGPT Answer:

Android’s internal storage and external storage have the following differences:

  1. Access permissions: Internal storage is private to the application, and only the application itself can access and modify its stored data. External storage is shared, and multiple applications can access and modify externally stored data.

  2. Storage capacity: Internal storage usually has a smaller capacity, generally ranging from tens to hundreds of GB. External storage usually has a larger capacity and can be expanded according to the user's needs.

  3. Data retention: When the app is uninstalled, data in internal storage is deleted. Data in external storage will not be automatically deleted unless deleted manually by the user.

  4. Mobility: Internal storage is a fixed storage space of the device and cannot be moved to other devices. External storage is removable storage media that allows the stored data to be moved from one device to another.

  5. Backup and Restore: Data in internal storage is usually not included in the device's backup, as this data can be restored by reinstalling the app. Data from external storage can be included in the device's backup so that it can be restored if needed.

In general, internal storage is suitable for storing the application's private data, while external storage is suitable for storing the user's shared data and media files. Depending on the specific needs and data type, you can choose to use internal storage or external storage to store and manage data.

Q: What is internal storage and what is external storage in Android?

ChatGPT Answer:

In Android devices, generally, the following are common examples of internal storage and external storage:

Internal storage:

  1. /data directory: This is the root directory of the Android device's internal storage, containing the application's private data, databases, caches, etc.
  2. /data/data/<package_name>/ directory: Each application has a private directory where the application's data and files are stored.
  3. /data/app directory: This is the directory where installed applications are stored, including the application's APK files and related data.

External storage:

  1. SD card: External storage usually refers to removable storage media on the device, such as an SD card. It can be used to store a user's media files, documents, and other data.
  2. External storage directory: On Android devices, there is usually a directory named "sdcard" or "external", which is used to represent the root directory of the external storage. This directory can be a built-in memory card, or an externally inserted SD card or USB storage device.
  3. Public storage directories: Android provides some public storage directories, such as Music, Pictures, Downloads, etc., for storing specific types of media files.

It should be noted that the specific storage path may vary depending on the device and Android version. You can use Android's API to get the correct internal storage and external storage paths.

Q: Android internal storage path

ChatGPT Answer:

In Android devices, the root directory path of internal storage is "/data". Each application has a private directory whose path format is "/data/data/<package_name>", where "<package_name>" is the package name of the application. Within this private directory, applications can create subdirectories to store their data and files.

For example, if the application's package name is "com.example.app", then the path to its private directory will be "/data/data/com.example.app".

It should be noted that since the internal storage is the private space of the application, other applications cannot directly access or modify the data in this directory. Only applications with the same user ID (UID) can access each other's internal storage data.

In addition, Android also provides some specific directories for storing different types of data, such as:

  1. /data/data/<package_name>/databases: Database files used to store applications.
  2. /data/data/<package_name>/cache: used to store cache files for applications.
  3. /data/app: Used to store APK files and related data of installed applications.

It should be noted that the internally stored data will be deleted when the application is uninstalled, so it is not suitable for storing important data that needs to be saved for a long time. For data that requires long-term retention, you should consider using external storage or other persistent storage solutions.

Q: Android external storage path

ChatGPT Answer:

In Android devices, there can be multiple paths to external storage, depending on the configuration of the device and the type of external storage media. Here are some common examples of external storage paths:

  1. SD card path: If the device has an SD card slot, the path to external storage is usually "/mnt/sdcard" or "/storage/sdcard". It should be noted that the specific path may vary depending on the device and Android version.

  2. External SD card path: If the device supports external SD cards, the path to external storage is usually "/mnt/external_sd" or "/storage/extSdCard". Similarly, the exact path may vary depending on the device and Android version.

  3. USB storage path: If the device supports USB storage devices, the path of the external storage is usually "/mnt/usb_storage" or "/storage/usb". Again, the exact path may vary depending on the device and Android version.

It should be noted that the path to external storage may vary depending on the device and Android version. In order to obtain the correct external storage path, you can use Android's API to dynamically obtain the path instead of hard-coding the path.

In addition, Android also provides some public storage directories, such as:

  1. Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS): used to store document files.
  2. Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES): used to store picture files.
  3. Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC): used to store music files.
  4. Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS): used to store downloaded files.

The paths to these public storage directories may vary depending on the device and Android version. The correct public storage directory path can be obtained using the above API.

Q: Google’s official explanation of internal storage and external storage

ChatGPT Answer:

According to Google's official explanation, internal storage and external storage have different characteristics and uses in Android.

Internal Storage (Internal Storage) is the private storage space of the application and is used to store the application's data and files. Each application has a private directory, and other applications cannot directly access or modify the data in this directory. Internally stored data will be deleted when the application is uninstalled, so it is not suitable for storing important data that needs to be saved for a long time. Internal storage is typically used to store an application's database files, cache files, and other private data.

External Storage is a storage space shared by the device and is used to store data and files shared by users and applications. External storage can be an on-device SD card, an external SD card, or a USB storage device. Externally stored data can be accessed by users and other applications, so it is suitable for storing data that needs to be shared with other applications or needs to be saved for a long time. External storage is usually used to store users' documents, pictures, music, downloaded files, etc.

Note that external storage availability and capacity may vary depending on the device and storage media. Furthermore, externally stored data may be deleted or modified due to user operations or device limitations. Therefore, when using external storage, you should consider data backup and recovery strategies to ensure data security and reliability.

In summary, internal storage is suitable for storing private data and temporary files of applications, while external storage is suitable for storing data shared by users and applications and important files that are saved for a long time. Based on specific needs and usage scenarios, developers can choose the appropriate storage method to manage and operate data.

Q: How to distinguish between Android’s internal storage and external storage?

ChatGPT Answer:

In Android, you can differentiate between internal and external storage by:

  1. Get the root directory path:

    • The root directory path of internal storage can be obtained using theContext.getFilesDir() method. This method returns a File object representing the application's private directory.
    • The root directory path of the external storage can be obtained using theEnvironment.getExternalStorageDirectory() method. This method returns a File object representing the device's external storage root directory.
  2. Determine whether the path is internal storage:

    • You can use theFile.getAbsolutePath() method to get the absolute path of a file or directory and compare it with the internally stored root directory path. If the path starts with the root directory path of the internal storage, it can be determined to be internal storage.
    • For example, you can usefile.getAbsolutePath().startsWith(context.getFilesDir().getAbsolutePath()) to determine whether the path is internal storage.
  3. Determine whether the path is external storage:

    • You can use theFile.getAbsolutePath() method to get the absolute path of a file or directory and compare it with the root path of the external storage. If the path starts with the root directory path of the external storage, it can be determined to be an external storage.
    • For example, you can usefile.getAbsolutePath().startsWith(Environment.getExternalStorageDirectory().getAbsolutePath()) to determine whether the path is external storage.

It should be noted that the specific internal storage and external storage paths may vary depending on the device and Android version. In order to obtain accurate internal storage and external storage paths, it is recommended to use the above method to dynamically obtain the paths instead of hardcoding the paths.

Guess you like

Origin blog.csdn.net/Yang_Mao_Shan/article/details/131695901