安卓设备是否有唯一的启动会话ID或计数?

9
我正在编写的应用程序需要知道是否更改了“引导会话”(为了更好地描述),但它不需要在启动时实际运行,如果可能的话,我希望不必使用“RECEIVE_BOOT_COMPLETED”权限。因此,我想知道是否有任何设备范围内的引导会话ID或计数器可以查询并存储到我的数据库中以供以后检查。我知道可以获取自启动以来的毫秒数,但我认为这在这种情况下不会有用。谢谢您提前的帮助。

使用randomUUID()怎么样?获得两个相同的UUID的概率应该是微不足道的。 - Michael
由于根文件系统通常是一个ramdisk,因此它的创建日期往往实际上是启动时间戳。 - Chris Stratton
你找到启动会话 ID 或计数了吗? - Artem_Iens
抱歉没有回复……但是(也许)迟到总比不来得好。我已经很久没有使用这个网站或进行安卓应用程序开发了,所以我没有什么可以补充的,但是我不认为我曾经找到过一个解决方案。据我回忆,我只是在我的数据库中使用时间戳。 - mark_w
3个回答

5

是的,在API>=24中,您可以使用BOOT_COUNT全局设置变量。要读取这个变量,可以尝试以下代码片段:

int boot_count = Settings.Global.getInt(getContext().getContentResolver(),
                                        Settings.Global.BOOT_COUNT);

在API 24之前,你只能捕获RECEIVE_BOOT_COMPLETED


2
我使用这段代码在所有版本的Android上获取唯一的启动ID。 对于Nougat及更高版本,我使用Settings.Global.BOOT_COUNT。 对于早于Nougat的版本,我从“/proc/sys/kernel/random/boot_id”中读取唯一的启动ID。 在我的测试中,我没有在Android 5上遇到任何文件访问问题。 在真实设备上测试了我们应用程序的发布版本,包括Android 5、8、9和11。
这不依赖于系统时钟,因为系统时钟可能会跳动或被用户更改。
感谢@george-hilliard的this answer,提供了Settings.Global.BOOT_COUNT解决方案。
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 );
}

-3
为什么不在你的数据库中存储最后一次启动的(绝对)日期和时间?你可以使用自上次启动以来的时间轻松计算它,而且考虑到启动所需的时间比毫秒长得多,因此应该相当准确。

请注意,在我测试这个解决方案的许多Android设备上,系统报告的上次启动时间可能会跳跃,从而产生错误的启动计数。 - Kurovsky
这是一个不好的主意:用户可以随时更改日期。 - Patrick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接