mirror of
https://github.com/skyline-emu/skyline.git
synced 2025-01-11 03:59:08 +01:00
Add an in-app updater
This commit is contained in:
parent
cb62e15748
commit
b2de510b2b
@ -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"
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.vulkan.version"
|
||||
|
123
app/src/main/java/emu/skyline/AppUpdater.kt
Normal file
123
app/src/main/java/emu/skyline/AppUpdater.kt
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* Copyright © 2023 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
*/
|
||||
|
||||
package emu.skyline
|
||||
|
||||
import android.app.DownloadManager
|
||||
import android.content.BroadcastReceiver
|
||||
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.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat.startActivity
|
||||
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
|
||||
|
||||
override fun onReceive(context : Context, intent : Intent) {
|
||||
//Fetching the download id received with the broadcast
|
||||
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()
|
||||
|
||||
val intentInstall = Intent(Intent.ACTION_INSTALL_PACKAGE)
|
||||
intentInstall.data = (context.getSystemService(AppCompatActivity.DOWNLOAD_SERVICE) as DownloadManager).getUriForDownloadedFile(downloadID)
|
||||
intentInstall.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
startActivity(context, intentInstall, null)
|
||||
context.unregisterReceiver(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun downloadApk(applicationContext : Context, uri : Uri){
|
||||
val downloadPath = applicationContext.getPublicFilesDir().canonicalPath
|
||||
val file = File(downloadPath, "skyline.apk")
|
||||
|
||||
if (File(file.path).exists()) {
|
||||
File(file.path).delete()
|
||||
}
|
||||
|
||||
val request = DownloadManager.Request(uri).setTitle("skyline")
|
||||
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)
|
||||
.setDestinationUri(Uri.fromFile(file))
|
||||
|
||||
val downloadManager = applicationContext.getSystemService(AppCompatActivity.DOWNLOAD_SERVICE) as DownloadManager
|
||||
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"
|
||||
@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 {
|
||||
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 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("<b>Changelog</b><p>${jsonBuilds.getJSONObject(ftx1Index).getJSONObject("commit").getString("message")}</p>", 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("<b>Changelog</b><p>${jsonBuilds.getJSONObject(ftx1Index).getJSONObject("commit").getString("message")}</p>", 0))
|
||||
.setCancelable(true)
|
||||
.setPositiveButton("Close") { dialogInterface, it ->
|
||||
dialogInterface.dismiss()
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
} catch (e : IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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 ->
|
||||
|
8
app/src/main/res/drawable/ic_check_updates.xml
Normal file
8
app/src/main/res/drawable/ic_check_updates.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<!-- drawable/download.xml -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path android:fillColor="#000" android:pathData="M5,20H19V18H5M19,9H15V3H9V9H5L12,16L19,9Z" />
|
||||
</vector>
|
@ -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" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/check_updates_icon"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/check_updates"
|
||||
android:padding="5dp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/sub_text"
|
||||
app:layout_constraintEnd_toStartOf="@id/log_icon"
|
||||
app:layout_constraintTop_toTopOf="@id/title_text"
|
||||
app:srcCompat="@drawable/ic_check_updates"
|
||||
app:tint="?android:attr/textColorSecondary"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/log_icon"
|
||||
android:layout_width="30dp"
|
||||
|
@ -8,6 +8,7 @@
|
||||
<string name="settings">Settings</string>
|
||||
<string name="share_logs">Share Logs</string>
|
||||
<string name="refresh">Refresh</string>
|
||||
<string name="check_updates">Check for updates</string>
|
||||
<!-- Toolbar - Share Logs -->
|
||||
<string name="log_share_prompt">Share log file</string>
|
||||
<string name="logs_not_found">No logs were created during the last run</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user