Skip to content

Commit c40418a

Browse files
committed
v1.1
Major refactoring! Updated dependencies. App now uses TJW's libsu. New app icon, launch screen and UI. Added Dark theme(follows system). Use XmlPullParser for reading the OTA URL.
1 parent 054245d commit c40418a

34 files changed

+385
-362
lines changed

app/build.gradle

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,31 @@ apply plugin: 'kotlin-android'
55
apply plugin: 'kotlin-android-extensions'
66

77
android {
8-
compileSdkVersion 28
8+
compileSdkVersion 29
99
defaultConfig {
1010
applicationId "app.akilesh.ota"
1111
minSdkVersion 27
12-
targetSdkVersion 28
13-
versionCode 1
14-
versionName "1.0"
15-
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
12+
targetSdkVersion 29
13+
versionCode 2
14+
versionName "1.1"
1615
vectorDrawables.useSupportLibrary = true
1716

1817
}
18+
buildFeatures {
19+
viewBinding = true
20+
}
21+
compileOptions {
22+
sourceCompatibility = JavaVersion.VERSION_1_8
23+
targetCompatibility = JavaVersion.VERSION_1_8
24+
}
25+
kotlinOptions {
26+
jvmTarget = JavaVersion.VERSION_1_8.toString()
27+
}
1928
buildTypes {
20-
release {
21-
minifyEnabled true
22-
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
23-
}
2429
debug {
30+
debuggable true
2531
minifyEnabled true
32+
shrinkResources true
2633
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
2734
}
2835
}
@@ -31,11 +38,10 @@ android {
3138
dependencies {
3239
implementation fileTree(dir: 'libs', include: ['*.jar'])
3340
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
34-
implementation 'androidx.appcompat:appcompat:1.0.2'
35-
implementation 'androidx.core:core-ktx:1.0.2'
36-
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
37-
testImplementation 'junit:junit:4.12'
38-
androidTestImplementation 'androidx.test:runner:1.2.0'
39-
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
40-
implementation 'com.google.android.material:material:1.1.0-alpha07'
41+
implementation 'androidx.appcompat:appcompat:1.1.0'
42+
implementation 'androidx.core:core-ktx:1.2.0'
43+
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta4'
44+
implementation 'com.google.android.material:material:1.2.0-alpha04'
45+
implementation "com.github.topjohnwu.libsu:core:2.5.1"
46+
4147
}

app/src/androidTest/java/app/akilesh/ota/ExampleInstrumentedTest.kt

Lines changed: 0 additions & 24 deletions
This file was deleted.

app/src/main/AndroidManifest.xml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,18 @@
1313
tools:ignore="GoogleAppIndexingWarning"
1414
>
1515

16-
<activity android:name=".MainActivity">
16+
<activity
17+
android:name=".ui.LaunchActivity"
18+
android:theme="@style/SplashTheme">
1719
<intent-filter>
1820
<action android:name="android.intent.action.MAIN"/>
1921

2022
<category android:name="android.intent.category.LAUNCHER"/>
2123
</intent-filter>
2224
</activity>
2325

26+
<activity android:name=".ui.MainActivity" />
27+
2428
</application>
2529

2630
</manifest>
24 KB
Loading

app/src/main/java/app/akilesh/ota/MainActivity.kt

Lines changed: 0 additions & 114 deletions
This file was deleted.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package app.akilesh.ota.ui
2+
3+
import android.content.Intent
4+
import android.os.Bundle
5+
import android.util.Log
6+
import androidx.appcompat.app.AppCompatActivity
7+
import app.akilesh.ota.R
8+
import com.google.android.material.dialog.MaterialAlertDialogBuilder
9+
import com.topjohnwu.superuser.Shell
10+
11+
class LaunchActivity : AppCompatActivity() {
12+
13+
override fun onCreate(savedInstanceState: Bundle?) {
14+
super.onCreate(savedInstanceState)
15+
16+
Shell.su().exec()
17+
18+
if (!Shell.rootAccess()) {
19+
Log.e("su", "Unable to get root access")
20+
21+
MaterialAlertDialogBuilder(this)
22+
.setTitle(getString(R.string.no_root_access_title))
23+
.setMessage(getString(R.string.no_root_access_message))
24+
.setCancelable(false)
25+
.setNegativeButton(getString(R.string.exit)) { _, _ ->
26+
finish()
27+
}
28+
.create()
29+
.show()
30+
}
31+
else {
32+
val intent = Intent(this, MainActivity::class.java)
33+
startActivity(intent)
34+
finish()
35+
}
36+
}
37+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package app.akilesh.ota.ui
2+
3+
import android.content.Intent
4+
import android.content.pm.PackageManager
5+
import android.content.res.Configuration
6+
import android.os.Bundle
7+
import android.util.Log
8+
import android.view.View
9+
import android.view.View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
10+
import android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
11+
import androidx.appcompat.app.AppCompatActivity
12+
import app.akilesh.ota.R
13+
import app.akilesh.ota.databinding.ActivityMainBinding
14+
import com.topjohnwu.superuser.Shell
15+
import org.xmlpull.v1.XmlPullParser
16+
import org.xmlpull.v1.XmlPullParserFactory
17+
import java.io.File
18+
import java.io.InputStreamReader
19+
20+
class MainActivity : AppCompatActivity() {
21+
private lateinit var binding: ActivityMainBinding
22+
private var filePath = "/data" + "/data/com.google.android.gms/shared_prefs/com.google.android.gms.update.storage.xml"
23+
24+
override fun onCreate(savedInstanceState: Bundle?) {
25+
super.onCreate(savedInstanceState)
26+
binding = ActivityMainBinding.inflate(layoutInflater)
27+
setContentView(binding.root)
28+
val linkTextView = binding.include.link
29+
30+
val decorView = window.decorView
31+
decorView.systemUiVisibility = FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
32+
33+
when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
34+
Configuration.UI_MODE_NIGHT_NO -> {
35+
decorView.systemUiVisibility =
36+
SYSTEM_UI_FLAG_LIGHT_STATUS_BAR or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
37+
}
38+
}
39+
40+
41+
if(Shell.su("[ -f $filePath ]").exec().isSuccess) {
42+
43+
val file = File(filesDir, "update.xml")
44+
Shell.su(
45+
"cp -af $filePath ${file.absolutePath}",
46+
"chmod 664 ${file.absolutePath}"
47+
).exec()
48+
val result = parseXML(file.reader())
49+
if (result != null) {
50+
Log.d("update-url", result)
51+
binding.include.check.visibility = View.GONE
52+
linkTextView.setTextIsSelectable(true)
53+
linkTextView.text = String.format("%s", result)
54+
//hintText.text = String.format("%s", resources.getString(R.string.hint))
55+
} else {
56+
val intent = Intent(Intent.ACTION_MAIN)
57+
intent.setClassName("com.google.android.gms","com.google.android.gms.update.SystemUpdateActivity")
58+
if (isCallable(intent)) {
59+
binding.include.check.apply {
60+
visibility = View.VISIBLE
61+
setOnClickListener {
62+
startActivity(intent)
63+
}
64+
}
65+
}
66+
else binding.include.check.visibility = View.GONE
67+
68+
linkTextView.text = String.format("%s", getString(R.string.no_update_available))
69+
}
70+
}
71+
}
72+
73+
private fun isCallable(intent: Intent): Boolean {
74+
val activities = packageManager.queryIntentActivities(intent,
75+
PackageManager.MATCH_DEFAULT_ONLY)
76+
return activities.isNotEmpty()
77+
}
78+
79+
private fun parseXML(reader: InputStreamReader): String? {
80+
val xmlPullParserFactory = XmlPullParserFactory.newInstance()
81+
xmlPullParserFactory.isNamespaceAware = true
82+
val xmlPullParser = xmlPullParserFactory.newPullParser()
83+
xmlPullParser.setInput(reader)
84+
var eventType = xmlPullParser.eventType
85+
var tag: String? = null
86+
var attr: String? = null
87+
var updateURL: String? = null
88+
89+
while (eventType != XmlPullParser.END_DOCUMENT) {
90+
if (eventType == XmlPullParser.START_TAG) {
91+
if ("map" != xmlPullParser.name) {
92+
tag = xmlPullParser.name
93+
attr = xmlPullParser.getAttributeValue(null, "name")
94+
}
95+
}
96+
else if (eventType == XmlPullParser.END_TAG) tag = null
97+
else if (eventType == XmlPullParser.TEXT) {
98+
if (tag != null && attr == "control.installation.current_update_url") {
99+
updateURL = xmlPullParser.text
100+
}
101+
}
102+
eventType = xmlPullParser.next()
103+
}
104+
return updateURL
105+
}
106+
107+
}

0 commit comments

Comments
 (0)