The app I'm writing needs to know if a 'boot session', for want of a better term, has changed but it doesn't need to actually start at boot and I would prefer if possible not to have to use the RECEIVE_BOOT_COMPLETED
permission.
So I was wondering if there is any device-wide boot session id or count I can query and store in my db to check against later. I know I can get the time in milliseconds since boot but I don't think that will be useful in this case.
Thanks in advance for any help.
Yes, on API >= 24. You can use the BOOT_COUNT
global settings variable. To read this, try a snippet like this:
int boot_count = Settings.Global.getInt(getContext().getContentResolver(),
Settings.Global.BOOT_COUNT);
Pre-API 24, you're stuck catching RECEIVE_BOOT_COMPLETED
.
I use this code to get a unique boot ID on all versions of Android. For Nougat and later, I use Settings.Global.BOOT_COUNT
. For versions older than Nougat, I read a unique boot ID from "/proc/sys/kernel/random/boot_id". I haven't had any issues with file access on Android 5 in my testing. Tested on Android 5, 8, 9, and 11 on real devices with a release build of our app.
This does not rely on the system clock, which can jump around or be changed by the user.
Thanks to this answer from @george-hilliard for the Settings.Global.BOOT_COUNT
solution.
String bootId = "";
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ) { // Starting in Android 7 / N(ougat) / API Level 24, we have access to `Settings.Global.BOOT_COUNT`, which increments with every boot.
bootId = Settings.Global.getString( getApplicationContext().getContentResolver(), Settings.Global.BOOT_COUNT );
}
else { // Before Android 7 / N(ougat) / API Level 24, we need to get the boot id from the /proc/sys/kernel/random/boot_id file. Example boot_id: "691aa77e-aff4-47c2-829e-a34df426c7e7".
File bootIdFile = new File( "/proc/sys/kernel/random/boot_id" );
if ( bootIdFile.exists() ) {
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream( bootIdFile );
BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) );
bootId = reader.readLine().trim(); // Read first line of file to get the boot id and remove any leading and trailing spaces.
}
catch ( FileNotFoundException error ) {
error.printStackTrace();
}
catch ( IOException error ) {
error.printStackTrace();
}
finally {
if ( inputStream != null ) try { inputStream.close(); } catch (IOException error ) { error.printStackTrace();; }
}
}
}
if ( bootId == "" ) {
Log.e( "UniqueTag", "Could not retrieve boot ID. Build.VERSION.SDK_INT: " + Build.VERSION.SDK_INT );
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With