${message.substringAfter("\n")}
" + + withContext(Dispatchers.Main) { + builder.setTitle("${applicationContext.getString(R.string.new_version)} ${newestBuild.get("runNumber")}") + .setMessage(Html.fromHtml(changelog, 0)) + .setCancelable(true) + .setPositiveButton(applicationContext.getString(R.string.update)) { dialogInterface, _ -> + val receiver = AppUpdater() + applicationContext.registerReceiver(receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) + receiver.downloadApk(applicationContext, uri) + dialogInterface.dismiss() + }.setNegativeButton(applicationContext.getString(R.string.cancel)){ dialogInterface, _ -> + dialogInterface.cancel() + }.show() + } + } else { + withContext(Dispatchers.Main) { + builder.setTitle(applicationContext.getString(R.string.no_updates_available)) + .setMessage(Html.fromHtml("${applicationContext.getString(R.string.changelog)}${commit.getString("message")}
", 0)) + .setCancelable(true) + .setPositiveButton(applicationContext.getString(R.string.close)) { dialogInterface, _ -> + dialogInterface.dismiss() + }.show() + } + } + } + } + } + + @com.google.android.material.badge.ExperimentalBadgeUtils + fun notifyUpdateBadge(context : Context, icon : ImageView) { + CoroutineScope(Dispatchers.IO).launch { + val newestBuild = checkRemoteForUpdates() + if (newestBuild != null) { + val remoteBuildGitHash = newestBuild.getJSONObject("commit").getString("id") + if (BuildConfig.GIT_HASH != remoteBuildGitHash) { + val badge = BadgeDrawable.create(context) + badge.badgeGravity = BOTTOM_END + badge.verticalOffset = 25 + badge.horizontalOffset = 25 + badge.backgroundColor = ContextCompat.getColor(context, R.color.colorPrimary) + BadgeUtils.attachBadgeDrawable(badge, icon) + } + } + } + } + + private fun checkRemoteForUpdates() : JSONObject? { + val url = URL("$baseUrl/builds") + try { + val response = url.readText() + val jsonBuilds = JSONTokener(response).nextValue() as JSONArray + + var ftx1Index = 0 + while (ftx1Index < jsonBuilds.length() && jsonBuilds.getJSONObject(ftx1Index).get("branch") != branch) { + ftx1Index++ + } + if (ftx1Index >= jsonBuilds.length()) + ftx1Index = 0 + + return jsonBuilds.getJSONObject(ftx1Index) + } catch (e : IOException) { + e.printStackTrace() + return null + } + } + + fun removeApk(){ + if (File(SkylineApplication.instance.getPublicFilesDir().canonicalPath + "/skyline.apk").exists()) { + File(SkylineApplication.instance.getPublicFilesDir().canonicalPath + "/skyline.apk").delete() + } + } + } +} diff --git a/app/src/main/java/emu/skyline/MainActivity.kt b/app/src/main/java/emu/skyline/MainActivity.kt index 955cac75..ff057aad 100644 --- a/app/src/main/java/emu/skyline/MainActivity.kt +++ b/app/src/main/java/emu/skyline/MainActivity.kt @@ -291,6 +291,18 @@ class MainActivity : AppCompatActivity() { } } }) + + binding.checkUpdatesIcon.apply { + if (BuildConfig.FLAVOR == "edge") { + visibility = View.GONE + } else { + AppUpdater.removeApk() + AppUpdater.notifyUpdateBadge(context, this) + this.setOnClickListener { + AppUpdater.checkForUpdates(context) + } + } + } } override fun onResume() { diff --git a/app/src/main/res/drawable/ic_check_updates.xml b/app/src/main/res/drawable/ic_check_updates.xml new file mode 100644 index 00000000..6346d876 --- /dev/null +++ b/app/src/main/res/drawable/ic_check_updates.xml @@ -0,0 +1,8 @@ + +