Android当前存储政策下无网络依赖的应用历史安装检测方案咨询
Great question—this is such a common headache for developers trying to enforce trial periods without relying on cloud services, especially with Android's evolving storage rules. Let's walk through the offline options that still work today:
1. Retain an Identifier File via MediaStore in Public Storage
While Scoped Storage locks down app-private directories (which get deleted on uninstall), files in public storage directories (like Downloads or Documents) stick around even after your app is removed. Here's how to implement this:
- Generate a unique filename: Combine your app's package name with the device's
Android ID(retrieved viaSettings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID)) and hash the result to create a unique, unguessable filename. Add a.hiddensuffix to make it less noticeable to users. - Create the marker file: Use
MediaStoreto write a small file (either empty or containing the first install timestamp) to a public directory. Example code:
ContentValues values = new ContentValues(); values.put(MediaStore.Downloads.DISPLAY_NAME, "your_unique_hash_filename.hidden"); values.put(MediaStore.Downloads.MIME_TYPE, "application/octet-stream"); values.put(MediaStore.Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS); Uri fileUri = getContentResolver().insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values); if (fileUri != null) { // Write the first install time to the file try (OutputStream outputStream = getContentResolver().openOutputStream(fileUri)) { String installTimestamp = String.valueOf(System.currentTimeMillis()); outputStream.write(installTimestamp.getBytes()); } catch (IOException e) { e.printStackTrace(); } }
- Check for the file on reinstall: After reinstalling, request the necessary read permissions (use
READ_MEDIA_DOWNLOADSfor Android 13+,READ_EXTERNAL_STORAGEfor older versions). Then query theMediaStore.Downloads.EXTERNAL_CONTENT_URIto find your marker file, read its content, and verify if the app was installed before.
Key notes:
- Users could manually delete this file, so you can improve robustness by creating multiple marker files in different public directories.
- Don't forget to handle the full permission request flow—users need to grant access for this to work.
2. Use External SD Card Storage (If Available)
If the user's device has a removable SD card, you can write your marker file to the SD card's root or a non-app-specific directory. Files on the SD card won't be deleted when your app is uninstalled. The implementation is similar to the MediaStore method, but you'll need to handle SD card mount states and ensure you have the right permissions to write to it.
3. Enterprise-Only: Device/Profile Owner Permissions
If your app is targeted at enterprise users, you can leverage Device Owner or Profile Owner privileges. These allow you to store system-level data that persists across app uninstalls. However, this requires special setup by the user or IT admin, so it's not feasible for consumer-facing apps.
PackageInfo Method Fails Now As you noted, the PackageInfo.firstInstallTime approach no longer works. Starting with Android 11, the system clears all installation records for an app when it's uninstalled. Reinstalling resets this timestamp to the new install time, so it can't be used to detect prior installations.
内容的提问来源于stack exchange,提问作者HenryC

