From b2de510b2b4aeb9157987468be2776f9b0185fb5 Mon Sep 17 00:00:00 2001 From: PabloG02 Date: Tue, 10 Jan 2023 17:01:47 +0100 Subject: [PATCH 01/11] Add an in-app updater --- app/build.gradle | 3 + app/src/main/AndroidManifest.xml | 1 + app/src/main/java/emu/skyline/AppUpdater.kt | 123 ++++++++++++++++++ app/src/main/java/emu/skyline/MainActivity.kt | 3 + .../main/res/drawable/ic_check_updates.xml | 8 ++ app/src/main/res/layout/main_activity.xml | 18 ++- app/src/main/res/values/strings.xml | 1 + 7 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/emu/skyline/AppUpdater.kt create mode 100644 app/src/main/res/drawable/ic_check_updates.xml diff --git a/app/build.gradle b/app/build.gradle index c8a67aac..2a041494 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,6 +18,7 @@ android { compileSdk 33 var isBuildSigned = (System.getenv("CI") == "true") && (System.getenv("IS_SKYLINE_SIGNED") == "true") + var gitCommitHash = 'git rev-parse --verify HEAD'.execute().text.trim() defaultConfig { applicationId "skyline.emu" @@ -28,6 +29,8 @@ android { versionCode 3 versionName "0.0.3" + buildConfigField("String", "GIT_HASH", "\"${gitCommitHash}\"") + ndk { //noinspection ChromeOsAbiSupport abiFilters "arm64-v8a" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a0ba2cca..c083f13e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,6 +4,7 @@ + = jsonBuilds.length()) + ftx1Index = 0 + + val remoteBuildGitHash = jsonBuilds.getJSONObject(ftx1Index).getJSONObject("commit").getString("id") + if (!BuildConfig.GIT_HASH.equals(remoteBuildGitHash)) { + val id = jsonBuilds.getJSONObject(ftx1Index).get("id") + val apkName = jsonBuilds.getJSONObject(ftx1Index).get("apkName") + val uri = Uri.parse("$baseUrl/cache/${id}/${apkName}") + + myHandler.post { + builder.setTitle("New version ${jsonBuilds.getJSONObject(ftx1Index).get("runNumber")}") + .setMessage(Html.fromHtml("Changelog

${jsonBuilds.getJSONObject(ftx1Index).getJSONObject("commit").getString("message")}

", 0)) + .setCancelable(true) + .setPositiveButton("Update") { dialogInterface, it -> + val receiver = AppUpdater() + applicationContext.registerReceiver(receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) + receiver.downloadApk(applicationContext, uri) + dialogInterface.dismiss() + }.show() + } + } else { + myHandler.post { + builder.setTitle("No updates available") + .setMessage(Html.fromHtml("Changelog

${jsonBuilds.getJSONObject(ftx1Index).getJSONObject("commit").getString("message")}

", 0)) + .setCancelable(true) + .setPositiveButton("Close") { dialogInterface, it -> + dialogInterface.dismiss() + }.show() + } + } + } catch (e : IOException) { + e.printStackTrace() + } + } + } + } +} diff --git a/app/src/main/java/emu/skyline/MainActivity.kt b/app/src/main/java/emu/skyline/MainActivity.kt index 19ef8284..9ce767ce 100644 --- a/app/src/main/java/emu/skyline/MainActivity.kt +++ b/app/src/main/java/emu/skyline/MainActivity.kt @@ -151,6 +151,9 @@ class MainActivity : AppCompatActivity() { Snackbar.make(this@MainActivity.findViewById(android.R.id.content), getString(R.string.logs_not_found), Snackbar.LENGTH_SHORT).show() } } + binding.checkUpdatesIcon.setOnClickListener { + AppUpdater.checkForUpdates(context) + } binding.settingsIcon.setOnClickListener { settingsCallback.launch(Intent(context, SettingsActivity::class.java)) } binding.refreshIcon.setOnClickListener { loadRoms(false) } addTextChangedListener(afterTextChanged = { editable -> 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..74fd5fd2 --- /dev/null +++ b/app/src/main/res/drawable/ic_check_updates.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/main_activity.xml b/app/src/main/res/layout/main_activity.xml index 4896778a..c74d9650 100644 --- a/app/src/main/res/layout/main_activity.xml +++ b/app/src/main/res/layout/main_activity.xml @@ -40,12 +40,28 @@ android:padding="5dp" android:visibility="invisible" app:layout_constraintBottom_toBottomOf="@id/sub_text" - app:layout_constraintEnd_toStartOf="@id/log_icon" + app:layout_constraintEnd_toStartOf="@id/check_updates_icon" app:layout_constraintTop_toTopOf="@id/title_text" app:srcCompat="@drawable/ic_refresh" app:tint="?android:attr/textColorSecondary" tools:visibility="visible" /> + + Settings Share Logs Refresh + Check for updates Share log file No logs were created during the last run From d6eab932a75ddd2019e709245137c4086cc48f43 Mon Sep 17 00:00:00 2001 From: PabloG02 Date: Thu, 12 Jan 2023 01:04:38 +0100 Subject: [PATCH 02/11] Use coroutine --- app/src/main/java/emu/skyline/AppUpdater.kt | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/emu/skyline/AppUpdater.kt b/app/src/main/java/emu/skyline/AppUpdater.kt index a1706310..7c13494a 100644 --- a/app/src/main/java/emu/skyline/AppUpdater.kt +++ b/app/src/main/java/emu/skyline/AppUpdater.kt @@ -18,12 +18,14 @@ import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat.startActivity +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.json.JSONArray import org.json.JSONTokener import java.io.File import java.io.IOException import java.net.URL -import java.util.concurrent.Executors class AppUpdater : BroadcastReceiver() { private var downloadID = 0L @@ -43,7 +45,7 @@ class AppUpdater : BroadcastReceiver() { } } - fun downloadApk(applicationContext : Context, uri : Uri){ + fun downloadApk(applicationContext : Context, uri : Uri) { val downloadPath = applicationContext.getPublicFilesDir().canonicalPath val file = File(downloadPath, "skyline.apk") @@ -60,31 +62,31 @@ class AppUpdater : BroadcastReceiver() { } init { - if (File(SkylineApplication.instance.getPublicFilesDir().canonicalPath+"/skyline.apk").exists()) { - File(SkylineApplication.instance.getPublicFilesDir().canonicalPath+"/skyline.apk").delete() + if (File(SkylineApplication.instance.getPublicFilesDir().canonicalPath + "/skyline.apk").exists()) { + File(SkylineApplication.instance.getPublicFilesDir().canonicalPath + "/skyline.apk").delete() } } companion object { private const val baseUrl = "https://skyline-builds.alula.gay" private const val branch = "ftx1" + @JvmStatic fun checkForUpdates(applicationContext : Context) { - val myExecutor = Executors.newSingleThreadExecutor() val myHandler = Handler(Looper.getMainLooper()) val builder = AlertDialog.Builder(applicationContext) val url = URL("$baseUrl/builds") - myExecutor.execute { + CoroutineScope(Dispatchers.IO).launch { try { val response = url.readText() val jsonBuilds = JSONTokener(response).nextValue() as JSONArray var ftx1Index = 0 - while(ftx1Index < jsonBuilds.length() && !jsonBuilds.getJSONObject(ftx1Index).get("branch").equals(branch)){ + while (ftx1Index < jsonBuilds.length() && !jsonBuilds.getJSONObject(ftx1Index).get("branch").equals(branch)) { ftx1Index++ } - if(ftx1Index >= jsonBuilds.length()) + if (ftx1Index >= jsonBuilds.length()) ftx1Index = 0 val remoteBuildGitHash = jsonBuilds.getJSONObject(ftx1Index).getJSONObject("commit").getString("id") From 411b79ed9ea9bd273e35c0b75987686e4f93d3e8 Mon Sep 17 00:00:00 2001 From: PabloG02 Date: Thu, 12 Jan 2023 12:24:41 +0100 Subject: [PATCH 03/11] Hide button on edge flavor --- app/src/main/java/emu/skyline/MainActivity.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/emu/skyline/MainActivity.kt b/app/src/main/java/emu/skyline/MainActivity.kt index 9ce767ce..afcc33f8 100644 --- a/app/src/main/java/emu/skyline/MainActivity.kt +++ b/app/src/main/java/emu/skyline/MainActivity.kt @@ -151,8 +151,12 @@ class MainActivity : AppCompatActivity() { Snackbar.make(this@MainActivity.findViewById(android.R.id.content), getString(R.string.logs_not_found), Snackbar.LENGTH_SHORT).show() } } - binding.checkUpdatesIcon.setOnClickListener { - AppUpdater.checkForUpdates(context) + if (BuildConfig.FLAVOR.equals("edge")) { + binding.checkUpdatesIcon.visibility = View.GONE + } else { + binding.checkUpdatesIcon.setOnClickListener { + AppUpdater.checkForUpdates(context) + } } binding.settingsIcon.setOnClickListener { settingsCallback.launch(Intent(context, SettingsActivity::class.java)) } binding.refreshIcon.setOnClickListener { loadRoms(false) } From 68b0abfa917a639e2a310494701d5c7b0f2f86dd Mon Sep 17 00:00:00 2001 From: PabloG02 Date: Thu, 12 Jan 2023 13:42:53 +0100 Subject: [PATCH 04/11] Add badge to notify when update is available --- app/src/main/java/emu/skyline/AppUpdater.kt | 35 +++++++++++++++++++ app/src/main/java/emu/skyline/MainActivity.kt | 1 + .../main/res/drawable/ic_check_updates.xml | 2 +- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/emu/skyline/AppUpdater.kt b/app/src/main/java/emu/skyline/AppUpdater.kt index 7c13494a..022ac862 100644 --- a/app/src/main/java/emu/skyline/AppUpdater.kt +++ b/app/src/main/java/emu/skyline/AppUpdater.kt @@ -14,10 +14,14 @@ import android.net.Uri import android.os.Handler import android.os.Looper import android.text.Html +import android.widget.ImageView import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat.startActivity +import com.google.android.material.badge.BadgeDrawable +import com.google.android.material.badge.BadgeDrawable.BOTTOM_END +import com.google.android.material.badge.BadgeUtils import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -121,5 +125,36 @@ class AppUpdater : BroadcastReceiver() { } } } + + @JvmStatic + @com.google.android.material.badge.ExperimentalBadgeUtils + fun checkForUpdates2(context : Context, icon: ImageView) { + CoroutineScope(Dispatchers.IO).launch { + 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").equals(branch)) { + ftx1Index++ + } + if (ftx1Index >= jsonBuilds.length()) + ftx1Index = 0 + + val remoteBuildGitHash = jsonBuilds.getJSONObject(ftx1Index).getJSONObject("commit").getString("id") + if(!BuildConfig.GIT_HASH.equals(remoteBuildGitHash)){ + val badge = BadgeDrawable.create(context) + badge.badgeGravity = BOTTOM_END + badge.verticalOffset = 25 + badge.horizontalOffset = 25 + badge.backgroundColor = context.getResources().getColor(R.color.colorPrimary) + BadgeUtils.attachBadgeDrawable(badge, icon) + } + } catch (e : IOException) { + e.printStackTrace() + } + } + } } } diff --git a/app/src/main/java/emu/skyline/MainActivity.kt b/app/src/main/java/emu/skyline/MainActivity.kt index afcc33f8..e904f2a5 100644 --- a/app/src/main/java/emu/skyline/MainActivity.kt +++ b/app/src/main/java/emu/skyline/MainActivity.kt @@ -154,6 +154,7 @@ class MainActivity : AppCompatActivity() { if (BuildConfig.FLAVOR.equals("edge")) { binding.checkUpdatesIcon.visibility = View.GONE } else { + AppUpdater.checkForUpdates2(context, binding.checkUpdatesIcon) binding.checkUpdatesIcon.setOnClickListener { AppUpdater.checkForUpdates(context) } diff --git a/app/src/main/res/drawable/ic_check_updates.xml b/app/src/main/res/drawable/ic_check_updates.xml index 74fd5fd2..6346d876 100644 --- a/app/src/main/res/drawable/ic_check_updates.xml +++ b/app/src/main/res/drawable/ic_check_updates.xml @@ -4,5 +4,5 @@ android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"> - + \ No newline at end of file From b6c164747600c54bf5fd767c7a3ab988ed473649 Mon Sep 17 00:00:00 2001 From: PabloG02 Date: Sat, 21 Jan 2023 17:12:15 +0100 Subject: [PATCH 05/11] Change equal to == --- app/src/main/java/emu/skyline/AppUpdater.kt | 17 +++++++++-------- app/src/main/java/emu/skyline/MainActivity.kt | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/emu/skyline/AppUpdater.kt b/app/src/main/java/emu/skyline/AppUpdater.kt index 022ac862..51cbb640 100644 --- a/app/src/main/java/emu/skyline/AppUpdater.kt +++ b/app/src/main/java/emu/skyline/AppUpdater.kt @@ -18,6 +18,7 @@ import android.widget.ImageView import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat.startActivity import com.google.android.material.badge.BadgeDrawable import com.google.android.material.badge.BadgeDrawable.BOTTOM_END @@ -87,14 +88,14 @@ class AppUpdater : BroadcastReceiver() { val jsonBuilds = JSONTokener(response).nextValue() as JSONArray var ftx1Index = 0 - while (ftx1Index < jsonBuilds.length() && !jsonBuilds.getJSONObject(ftx1Index).get("branch").equals(branch)) { + while (ftx1Index < jsonBuilds.length() && jsonBuilds.getJSONObject(ftx1Index).get("branch") != branch) { ftx1Index++ } if (ftx1Index >= jsonBuilds.length()) ftx1Index = 0 val remoteBuildGitHash = jsonBuilds.getJSONObject(ftx1Index).getJSONObject("commit").getString("id") - if (!BuildConfig.GIT_HASH.equals(remoteBuildGitHash)) { + if (BuildConfig.GIT_HASH != remoteBuildGitHash) { val id = jsonBuilds.getJSONObject(ftx1Index).get("id") val apkName = jsonBuilds.getJSONObject(ftx1Index).get("apkName") val uri = Uri.parse("$baseUrl/cache/${id}/${apkName}") @@ -103,7 +104,7 @@ class AppUpdater : BroadcastReceiver() { builder.setTitle("New version ${jsonBuilds.getJSONObject(ftx1Index).get("runNumber")}") .setMessage(Html.fromHtml("Changelog

${jsonBuilds.getJSONObject(ftx1Index).getJSONObject("commit").getString("message")}

", 0)) .setCancelable(true) - .setPositiveButton("Update") { dialogInterface, it -> + .setPositiveButton("Update") { dialogInterface, _ -> val receiver = AppUpdater() applicationContext.registerReceiver(receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) receiver.downloadApk(applicationContext, uri) @@ -115,7 +116,7 @@ class AppUpdater : BroadcastReceiver() { builder.setTitle("No updates available") .setMessage(Html.fromHtml("Changelog

${jsonBuilds.getJSONObject(ftx1Index).getJSONObject("commit").getString("message")}

", 0)) .setCancelable(true) - .setPositiveButton("Close") { dialogInterface, it -> + .setPositiveButton("Close") { dialogInterface, _ -> dialogInterface.dismiss() }.show() } @@ -130,25 +131,25 @@ class AppUpdater : BroadcastReceiver() { @com.google.android.material.badge.ExperimentalBadgeUtils fun checkForUpdates2(context : Context, icon: ImageView) { CoroutineScope(Dispatchers.IO).launch { - val url = URL("$baseUrl/builds") + 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").equals(branch)) { + while (ftx1Index < jsonBuilds.length() && jsonBuilds.getJSONObject(ftx1Index).get("branch") != branch) { ftx1Index++ } if (ftx1Index >= jsonBuilds.length()) ftx1Index = 0 val remoteBuildGitHash = jsonBuilds.getJSONObject(ftx1Index).getJSONObject("commit").getString("id") - if(!BuildConfig.GIT_HASH.equals(remoteBuildGitHash)){ + if(BuildConfig.GIT_HASH != remoteBuildGitHash){ val badge = BadgeDrawable.create(context) badge.badgeGravity = BOTTOM_END badge.verticalOffset = 25 badge.horizontalOffset = 25 - badge.backgroundColor = context.getResources().getColor(R.color.colorPrimary) + badge.backgroundColor = ContextCompat.getColor(context, R.color.colorPrimary) BadgeUtils.attachBadgeDrawable(badge, icon) } } catch (e : IOException) { diff --git a/app/src/main/java/emu/skyline/MainActivity.kt b/app/src/main/java/emu/skyline/MainActivity.kt index e904f2a5..f8213b09 100644 --- a/app/src/main/java/emu/skyline/MainActivity.kt +++ b/app/src/main/java/emu/skyline/MainActivity.kt @@ -151,7 +151,7 @@ class MainActivity : AppCompatActivity() { Snackbar.make(this@MainActivity.findViewById(android.R.id.content), getString(R.string.logs_not_found), Snackbar.LENGTH_SHORT).show() } } - if (BuildConfig.FLAVOR.equals("edge")) { + if (BuildConfig.FLAVOR == "edge") { binding.checkUpdatesIcon.visibility = View.GONE } else { AppUpdater.checkForUpdates2(context, binding.checkUpdatesIcon) From 19c4bf0aebb7a3d212518a7f90404f63731c670a Mon Sep 17 00:00:00 2001 From: PabloG02 Date: Sat, 21 Jan 2023 20:03:16 +0100 Subject: [PATCH 06/11] Make checking latest build its own function --- app/src/main/java/emu/skyline/AppUpdater.kt | 72 +++++++++---------- app/src/main/java/emu/skyline/MainActivity.kt | 2 +- 2 files changed, 36 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/emu/skyline/AppUpdater.kt b/app/src/main/java/emu/skyline/AppUpdater.kt index 51cbb640..37bf12c3 100644 --- a/app/src/main/java/emu/skyline/AppUpdater.kt +++ b/app/src/main/java/emu/skyline/AppUpdater.kt @@ -27,6 +27,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.json.JSONArray +import org.json.JSONObject import org.json.JSONTokener import java.io.File import java.io.IOException @@ -81,28 +82,18 @@ class AppUpdater : BroadcastReceiver() { val myHandler = Handler(Looper.getMainLooper()) val builder = AlertDialog.Builder(applicationContext) - val url = URL("$baseUrl/builds") CoroutineScope(Dispatchers.IO).launch { - 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 - - val remoteBuildGitHash = jsonBuilds.getJSONObject(ftx1Index).getJSONObject("commit").getString("id") + val newestBuild = checkRemoteForUpdates() + if (newestBuild != null) { + val remoteBuildGitHash = newestBuild.getJSONObject("commit").getString("id") if (BuildConfig.GIT_HASH != remoteBuildGitHash) { - val id = jsonBuilds.getJSONObject(ftx1Index).get("id") - val apkName = jsonBuilds.getJSONObject(ftx1Index).get("apkName") + val id = newestBuild.get("id") + val apkName = newestBuild.get("apkName") val uri = Uri.parse("$baseUrl/cache/${id}/${apkName}") myHandler.post { - builder.setTitle("New version ${jsonBuilds.getJSONObject(ftx1Index).get("runNumber")}") - .setMessage(Html.fromHtml("Changelog

${jsonBuilds.getJSONObject(ftx1Index).getJSONObject("commit").getString("message")}

", 0)) + builder.setTitle("New version ${newestBuild.get("runNumber")}") + .setMessage(Html.fromHtml("Changelog

${newestBuild.getJSONObject("commit").getString("message")}

", 0)) .setCancelable(true) .setPositiveButton("Update") { dialogInterface, _ -> val receiver = AppUpdater() @@ -114,37 +105,25 @@ class AppUpdater : BroadcastReceiver() { } else { myHandler.post { builder.setTitle("No updates available") - .setMessage(Html.fromHtml("Changelog

${jsonBuilds.getJSONObject(ftx1Index).getJSONObject("commit").getString("message")}

", 0)) + .setMessage(Html.fromHtml("Changelog

${newestBuild.getJSONObject("commit").getString("message")}

", 0)) .setCancelable(true) .setPositiveButton("Close") { dialogInterface, _ -> dialogInterface.dismiss() }.show() } } - } catch (e : IOException) { - e.printStackTrace() } } } @JvmStatic @com.google.android.material.badge.ExperimentalBadgeUtils - fun checkForUpdates2(context : Context, icon: ImageView) { + fun notifyUpdateBadge(context : Context, icon : ImageView) { CoroutineScope(Dispatchers.IO).launch { - 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 - - val remoteBuildGitHash = jsonBuilds.getJSONObject(ftx1Index).getJSONObject("commit").getString("id") - if(BuildConfig.GIT_HASH != remoteBuildGitHash){ + 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 @@ -152,10 +131,29 @@ class AppUpdater : BroadcastReceiver() { badge.backgroundColor = ContextCompat.getColor(context, R.color.colorPrimary) BadgeUtils.attachBadgeDrawable(badge, icon) } - } catch (e : IOException) { - e.printStackTrace() } } } + + @JvmStatic + 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 + } + } } } diff --git a/app/src/main/java/emu/skyline/MainActivity.kt b/app/src/main/java/emu/skyline/MainActivity.kt index f8213b09..881de5f4 100644 --- a/app/src/main/java/emu/skyline/MainActivity.kt +++ b/app/src/main/java/emu/skyline/MainActivity.kt @@ -154,7 +154,7 @@ class MainActivity : AppCompatActivity() { if (BuildConfig.FLAVOR == "edge") { binding.checkUpdatesIcon.visibility = View.GONE } else { - AppUpdater.checkForUpdates2(context, binding.checkUpdatesIcon) + AppUpdater.notifyUpdateBadge(context, binding.checkUpdatesIcon) binding.checkUpdatesIcon.setOnClickListener { AppUpdater.checkForUpdates(context) } From c623278d093f4a98ad398a1d6c4b7bb89f5d12c6 Mon Sep 17 00:00:00 2001 From: PabloG02 Date: Wed, 25 Jan 2023 14:26:44 +0100 Subject: [PATCH 07/11] Remove @JvmStatic and fix formatting of the changelog --- app/src/main/java/emu/skyline/AppUpdater.kt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/emu/skyline/AppUpdater.kt b/app/src/main/java/emu/skyline/AppUpdater.kt index 37bf12c3..04a125dd 100644 --- a/app/src/main/java/emu/skyline/AppUpdater.kt +++ b/app/src/main/java/emu/skyline/AppUpdater.kt @@ -77,7 +77,7 @@ class AppUpdater : BroadcastReceiver() { private const val baseUrl = "https://skyline-builds.alula.gay" private const val branch = "ftx1" - @JvmStatic + fun checkForUpdates(applicationContext : Context) { val myHandler = Handler(Looper.getMainLooper()) val builder = AlertDialog.Builder(applicationContext) @@ -91,9 +91,13 @@ class AppUpdater : BroadcastReceiver() { val apkName = newestBuild.get("apkName") val uri = Uri.parse("$baseUrl/cache/${id}/${apkName}") + var changelog = "Changelog

${newestBuild.getJSONObject("commit").getString("message").substringBefore("\n")}

" + if (newestBuild.getJSONObject("commit").getString("message").contains("\n")) + changelog += "

${newestBuild.getJSONObject("commit").getString("message").substringAfter("\n")}

" + myHandler.post { builder.setTitle("New version ${newestBuild.get("runNumber")}") - .setMessage(Html.fromHtml("Changelog

${newestBuild.getJSONObject("commit").getString("message")}

", 0)) + .setMessage(Html.fromHtml(changelog, 0)) .setCancelable(true) .setPositiveButton("Update") { dialogInterface, _ -> val receiver = AppUpdater() @@ -116,7 +120,7 @@ class AppUpdater : BroadcastReceiver() { } } - @JvmStatic + @com.google.android.material.badge.ExperimentalBadgeUtils fun notifyUpdateBadge(context : Context, icon : ImageView) { CoroutineScope(Dispatchers.IO).launch { @@ -135,7 +139,7 @@ class AppUpdater : BroadcastReceiver() { } } - @JvmStatic + fun checkRemoteForUpdates() : JSONObject? { val url = URL("$baseUrl/builds") try { From 1cc0b427201b3916a174b26f82e5efc156f9ea66 Mon Sep 17 00:00:00 2001 From: PabloG02 Date: Thu, 26 Jan 2023 14:35:07 +0100 Subject: [PATCH 08/11] Make dialog translatable and replace handlers with coroutines --- app/src/main/java/emu/skyline/AppUpdater.kt | 35 ++++++++++----------- app/src/main/res/values/strings.xml | 6 ++++ 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/emu/skyline/AppUpdater.kt b/app/src/main/java/emu/skyline/AppUpdater.kt index 04a125dd..0caf8332 100644 --- a/app/src/main/java/emu/skyline/AppUpdater.kt +++ b/app/src/main/java/emu/skyline/AppUpdater.kt @@ -11,8 +11,6 @@ import android.content.Context import android.content.Intent import android.content.IntentFilter import android.net.Uri -import android.os.Handler -import android.os.Looper import android.text.Html import android.widget.ImageView import android.widget.Toast @@ -26,6 +24,7 @@ import com.google.android.material.badge.BadgeUtils import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.json.JSONArray import org.json.JSONObject import org.json.JSONTokener @@ -77,41 +76,43 @@ class AppUpdater : BroadcastReceiver() { private const val baseUrl = "https://skyline-builds.alula.gay" private const val branch = "ftx1" - fun checkForUpdates(applicationContext : Context) { - val myHandler = Handler(Looper.getMainLooper()) val builder = AlertDialog.Builder(applicationContext) CoroutineScope(Dispatchers.IO).launch { val newestBuild = checkRemoteForUpdates() if (newestBuild != null) { - val remoteBuildGitHash = newestBuild.getJSONObject("commit").getString("id") + val commit = newestBuild.getJSONObject("commit") + val remoteBuildGitHash = commit.getString("id") if (BuildConfig.GIT_HASH != remoteBuildGitHash) { val id = newestBuild.get("id") val apkName = newestBuild.get("apkName") val uri = Uri.parse("$baseUrl/cache/${id}/${apkName}") - var changelog = "Changelog

${newestBuild.getJSONObject("commit").getString("message").substringBefore("\n")}

" - if (newestBuild.getJSONObject("commit").getString("message").contains("\n")) - changelog += "

${newestBuild.getJSONObject("commit").getString("message").substringAfter("\n")}

" + val message = commit.getString("message") + var changelog = "${applicationContext.getString(R.string.changelog)}

${message.substringBefore("\n")}

" + if (message.contains("\n")) + changelog += "

${message.substringAfter("\n")}

" - myHandler.post { - builder.setTitle("New version ${newestBuild.get("runNumber")}") + withContext(Dispatchers.Main) { + builder.setTitle("${applicationContext.getString(R.string.new_version)} ${newestBuild.get("runNumber")}") .setMessage(Html.fromHtml(changelog, 0)) .setCancelable(true) - .setPositiveButton("Update") { dialogInterface, _ -> + .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 { - myHandler.post { - builder.setTitle("No updates available") - .setMessage(Html.fromHtml("Changelog

${newestBuild.getJSONObject("commit").getString("message")}

", 0)) + 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("Close") { dialogInterface, _ -> + .setPositiveButton(applicationContext.getString(R.string.close)) { dialogInterface, _ -> dialogInterface.dismiss() }.show() } @@ -120,7 +121,6 @@ class AppUpdater : BroadcastReceiver() { } } - @com.google.android.material.badge.ExperimentalBadgeUtils fun notifyUpdateBadge(context : Context, icon : ImageView) { CoroutineScope(Dispatchers.IO).launch { @@ -139,8 +139,7 @@ class AppUpdater : BroadcastReceiver() { } } - - fun checkRemoteForUpdates() : JSONObject? { + private fun checkRemoteForUpdates() : JSONObject? { val url = URL("$baseUrl/builds") try { val response = url.readText() diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 216bd85a..efc23d66 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -12,6 +12,12 @@ Share log file No logs were created during the last run + + New version + Changelog + Update + No updates available + Close All Metadata Missing From d442be37b66eee6389e6ff7ec25b8ed1ede9d6c6 Mon Sep 17 00:00:00 2001 From: PabloG02 Date: Thu, 26 Jan 2023 14:42:53 +0100 Subject: [PATCH 09/11] Remove APK when app is opened --- app/src/main/java/emu/skyline/AppUpdater.kt | 12 ++++++------ app/src/main/java/emu/skyline/MainActivity.kt | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/emu/skyline/AppUpdater.kt b/app/src/main/java/emu/skyline/AppUpdater.kt index 0caf8332..e9a97221 100644 --- a/app/src/main/java/emu/skyline/AppUpdater.kt +++ b/app/src/main/java/emu/skyline/AppUpdater.kt @@ -66,12 +66,6 @@ class AppUpdater : BroadcastReceiver() { downloadID = downloadManager.enqueue(request) } - init { - if (File(SkylineApplication.instance.getPublicFilesDir().canonicalPath + "/skyline.apk").exists()) { - File(SkylineApplication.instance.getPublicFilesDir().canonicalPath + "/skyline.apk").delete() - } - } - companion object { private const val baseUrl = "https://skyline-builds.alula.gay" private const val branch = "ftx1" @@ -158,5 +152,11 @@ class AppUpdater : BroadcastReceiver() { 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 881de5f4..10197c89 100644 --- a/app/src/main/java/emu/skyline/MainActivity.kt +++ b/app/src/main/java/emu/skyline/MainActivity.kt @@ -154,6 +154,7 @@ class MainActivity : AppCompatActivity() { if (BuildConfig.FLAVOR == "edge") { binding.checkUpdatesIcon.visibility = View.GONE } else { + AppUpdater.removeApk() AppUpdater.notifyUpdateBadge(context, binding.checkUpdatesIcon) binding.checkUpdatesIcon.setOnClickListener { AppUpdater.checkForUpdates(context) From ad5222eed3956f3909cac951a883063f7304b63d Mon Sep 17 00:00:00 2001 From: PabloG02 Date: Thu, 26 Jan 2023 14:47:26 +0100 Subject: [PATCH 10/11] Forgot 1 string --- app/src/main/java/emu/skyline/AppUpdater.kt | 2 +- app/src/main/res/values/strings.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/emu/skyline/AppUpdater.kt b/app/src/main/java/emu/skyline/AppUpdater.kt index e9a97221..c82ceb8a 100644 --- a/app/src/main/java/emu/skyline/AppUpdater.kt +++ b/app/src/main/java/emu/skyline/AppUpdater.kt @@ -40,7 +40,7 @@ class AppUpdater : BroadcastReceiver() { val id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1) //Checking if the received broadcast is for our enqueued download by matching download id if (downloadID == id) { - Toast.makeText(context, "Download Completed", Toast.LENGTH_SHORT).show() + Toast.makeText(context, context.getString(R.string.download_completed), Toast.LENGTH_SHORT).show() val intentInstall = Intent(Intent.ACTION_INSTALL_PACKAGE) intentInstall.data = (context.getSystemService(AppCompatActivity.DOWNLOAD_SERVICE) as DownloadManager).getUriForDownloadedFile(downloadID) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index efc23d66..9657d8d7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -16,6 +16,7 @@ New version Changelog Update + Download completed No updates available Close From 5a8db157259a1df61b9292e62b82cd43c4d29ec8 Mon Sep 17 00:00:00 2001 From: PabloG02 Date: Sun, 19 Feb 2023 19:39:24 +0100 Subject: [PATCH 11/11] Move update check to `onStart` --- app/src/main/java/emu/skyline/MainActivity.kt | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/emu/skyline/MainActivity.kt b/app/src/main/java/emu/skyline/MainActivity.kt index 10197c89..77ce4f9e 100644 --- a/app/src/main/java/emu/skyline/MainActivity.kt +++ b/app/src/main/java/emu/skyline/MainActivity.kt @@ -151,15 +151,6 @@ class MainActivity : AppCompatActivity() { Snackbar.make(this@MainActivity.findViewById(android.R.id.content), getString(R.string.logs_not_found), Snackbar.LENGTH_SHORT).show() } } - if (BuildConfig.FLAVOR == "edge") { - binding.checkUpdatesIcon.visibility = View.GONE - } else { - AppUpdater.removeApk() - AppUpdater.notifyUpdateBadge(context, binding.checkUpdatesIcon) - binding.checkUpdatesIcon.setOnClickListener { - AppUpdater.checkForUpdates(context) - } - } binding.settingsIcon.setOnClickListener { settingsCallback.launch(Intent(context, SettingsActivity::class.java)) } binding.refreshIcon.setOnClickListener { loadRoms(false) } addTextChangedListener(afterTextChanged = { editable -> @@ -333,6 +324,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() {