Skip to content

Commit e4cddcc

Browse files
authored
Refactor Android code (#4)
1 parent 3a4336b commit e4cddcc

File tree

5 files changed

+69
-82
lines changed

5 files changed

+69
-82
lines changed

android/app/src/free/AndroidManifest.xml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66

77
<meta-data
88
android:name="com.google.android.gms.ads.APPLICATION_ID"
9-
tools:replace="android:value"
10-
android:value="ca-app-pub-5911839694379275~4255791238"/>
9+
android:value="ca-app-pub-5911839694379275~4255791238"
10+
tools:replace="android:value" />
1111

12-
</application>
12+
</application>
1313

14-
1514
</manifest>
Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,9 @@
11
package com.foxdebug.acode
22

3+
import com.foxdebug.acode.plugins.NativeLayer
34
import kotlinx.coroutines.CoroutineScope
4-
import kotlinx.coroutines.DelicateCoroutinesApi
5-
import kotlinx.coroutines.Dispatchers
6-
import kotlinx.coroutines.GlobalScope
75
import kotlinx.coroutines.launch
86

9-
object Utils {
10-
//guarantees the runnable to be run on the main thread
11-
@OptIn(DelicateCoroutinesApi::class)
12-
fun runOnUiThread(callback: CoroutineScope.() -> Unit) {
13-
GlobalScope.launch(Dispatchers.Main){
14-
callback.invoke(this)
15-
}
16-
}
17-
}
7+
fun NativeLayer.runOnUiThread(callback: CoroutineScope.() -> Unit) {
8+
scope.launch { callback() }
9+
}

android/app/src/main/java/com/foxdebug/acode/plugins/NativeLayer.kt

Lines changed: 47 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -5,46 +5,47 @@ import android.net.Uri
55
import android.os.Build
66
import androidx.appcompat.app.AlertDialog
77
import com.foxdebug.acode.Acode
8-
import com.foxdebug.acode.MainActivity
9-
import com.foxdebug.acode.Utils
8+
import com.foxdebug.acode.runOnUiThread
109
import com.getcapacitor.JSObject
1110
import com.getcapacitor.Plugin
1211
import com.getcapacitor.PluginCall
1312
import com.getcapacitor.PluginMethod
1413
import com.getcapacitor.annotation.CapacitorPlugin
14+
import kotlinx.coroutines.CoroutineName
15+
import kotlinx.coroutines.MainScope
16+
import kotlinx.coroutines.cancel
17+
import kotlinx.coroutines.plus
18+
import androidx.core.net.toUri
1519

1620
@CapacitorPlugin(name = "NativeLayer")
1721
class NativeLayer : Plugin() {
22+
val scope = MainScope() + CoroutineName("NativeLayer")
23+
24+
override fun handleOnDestroy() {
25+
super.handleOnDestroy()
26+
scope.cancel()
27+
}
1828

1929
/**
20-
* Displays a dialog with the provided title and message.
30+
* Displays a simple alert dialog with a title, message, and an "OK" button.
2131
*
22-
* @param call The PluginCall containing the dialog parameters. It should contain:
23-
* - `title`: The title of the dialog (String).
24-
* - `message`: The message displayed in the dialog (String).
32+
* @param call The PluginCall containing the dialog parameters. It expects the following keys:
33+
* - `title`: (String) The title of the dialog.
34+
* - `message`: (String) The message content of the dialog.
2535
*
26-
* If either `title` or `message` is missing, the call will be rejected with an appropriate error message.
27-
* Upon clicking "OK", the dialog will resolve the call.
36+
* The dialog will display the provided title and message. If either `title` or `message` is not provided, the call will be rejected with an error.
37+
* When the user clicks the "OK" button, the dialog will be dismissed, and the plugin call will be resolved.
2838
*/
2939
@PluginMethod
3040
fun showDialog(call: PluginCall) = with(call) {
3141
autoRejectOnError(onFailure = {}) {
32-
existsNot("title") {
33-
return@with
34-
}
35-
existsNot("message") {
36-
return@with
37-
}
42+
existsNot("title") { return@with }
43+
existsNot("message") { return@with }
3844

3945
val title = call.getString("title")
4046
val message = call.getString("message")
4147

42-
Utils.runOnUiThread {
43-
val context = MainActivity.getActivityContext()
44-
if (context == null) {
45-
call.reject("Context is null")
46-
return@runOnUiThread
47-
}
48+
runOnUiThread {
4849
AlertDialog.Builder(context).apply {
4950
setTitle(title)
5051
setMessage(message)
@@ -60,27 +61,31 @@ class NativeLayer : Plugin() {
6061
/**
6162
* Launches an intent based on the provided parameters.
6263
*
63-
* @param call The PluginCall containing the intent parameters. It should contain:
64-
* - `constructor_number`: The type of intent constructor to use (Int).
65-
* - `launch_type`: The type of intent launch ("activity" or "service").
66-
* - `activity_context`: Whether to use the activity context (Boolean).
67-
* - `action`: The action for the intent (String) (for constructor 0).
68-
* - `className`: The class name to launch (String) (for constructor 1).
69-
* - `new_task`: Whether to launch the intent in a new task (Boolean).
70-
* - `extras`: A JSObject containing key-value pairs to add as extras to the intent.
71-
* - `data`: Optional URI to set as the intent data.
72-
* - `type`: Optional MIME type for the intent.
73-
* - `package` and `class`: Optional package and class for explicit intents.
74-
*
75-
* This method supports multiple constructors based on the `constructor_number`:
76-
* - `0`: Uses an action string to create an intent.
77-
* - `1`: Uses a class name to create an explicit intent.
78-
* - `2`: Creates a generic intent.
64+
* @param call The PluginCall containing the intent parameters.
65+
* The following parameters are expected:
66+
* - `constructor_number`: (Int) The type of intent constructor to use.
67+
* - `0`: Creates an intent using an action string. Requires `action`.
68+
* - `1`: Creates an explicit intent using a class name. Requires `className`.
69+
* - `2`: Creates a generic intent.
70+
* - `launch_type`: (String) The type of intent launch.
71+
* - `"activity"`: Starts an activity.
72+
* - `"service"`: Starts a service.
73+
* - `activity_context`: (Boolean) Whether to use the activity context. If `false`, uses the application context.
74+
* - `action`: (String) The action for the intent (required for `constructor_number` 0).
75+
* - `className`: (String) The fully qualified class name to launch (required for `constructor_number` 1).
76+
* - `new_task`: (Boolean) Whether to launch the intent in a new task.
77+
* - `extras`: (JSObject) Key-value pairs to add as extras to the intent. Supported types are String, Int, Boolean, Double, and Float.
78+
* - `data`: (String, optional) URI to set as the intent data.
79+
* - `type`: (String, optional) MIME type for the intent.
80+
* - `package`: (String, optional) Package name for an explicit intent.
81+
* - `class`: (String, optional) Class name for an explicit intent. Should be used alongside `package`.
82+
* - `foreground_service`: (Boolean, optional) Indicates if the service is a foreground service. (required for service launch)
83+
* Only applies when `launch_type` is "service". Requires API 26+.
7984
*
80-
* If the `launch_type` is "activity", it starts an activity.
81-
* If the `launch_type` is "service", it starts a service, and you can specify if it's a foreground service.
85+
* If `launch_type` is "service" and `foreground_service` is `true`, it starts a foreground service.
86+
* Otherwise, it starts a regular background service.
8287
*
83-
* If any required parameters are missing, the call will be rejected with an appropriate error message.
88+
* If any required parameters are missing or invalid, the call will be rejected with an appropriate error message.
8489
*/
8590
@PluginMethod
8691
fun launchIntent(call: PluginCall) {
@@ -100,11 +105,7 @@ class NativeLayer : Plugin() {
100105
return
101106
}
102107

103-
val context = if (useActivityContext) MainActivity.getActivityContext() else Acode.instance
104-
if (context == null) {
105-
call.reject("Requested context is not available")
106-
return
107-
}
108+
val context = if (useActivityContext) context else Acode.instance.applicationContext
108109

109110
val intent = when (constructorNumber) {
110111
0 -> {
@@ -153,13 +154,8 @@ class NativeLayer : Plugin() {
153154
}
154155
}
155156

156-
call.getString("data")?.let {
157-
intent.data = Uri.parse(it)
158-
}
159-
160-
call.getString("type")?.let {
161-
intent.type = it
162-
}
157+
call.getString("data")?.let { intent.data = it.toUri() }
158+
call.getString("type")?.let(intent::setType)
163159

164160
if (call.data.has("package") && call.data.has("class")) {
165161
val pkg = call.getString("package")
@@ -199,6 +195,5 @@ class NativeLayer : Plugin() {
199195
}
200196
}
201197
}
202-
203198
}
204199
}

android/app/src/main/java/com/foxdebug/acode/plugins/PluginUtils.kt

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@ package com.foxdebug.acode.plugins
22

33
import com.foxdebug.acode.MainActivity
44
import com.getcapacitor.PluginCall
5-
import kotlinx.coroutines.CoroutineDispatcher
65
import kotlinx.coroutines.CoroutineScope
76
import kotlinx.coroutines.CoroutineStart
87
import kotlinx.coroutines.Dispatchers
98
import kotlinx.coroutines.launch
109
import kotlin.coroutines.CoroutineContext
11-
import kotlin.coroutines.EmptyCoroutineContext
1210

13-
inline fun PluginCall.autoRejectOnError(onFailure:(Throwable?)-> Unit, invoke:()-> Unit){
11+
inline fun PluginCall.autoRejectOnError(onFailure: (Throwable?) -> Unit, invoke: () -> Unit) {
1412
runCatching {
1513
invoke()
1614
}.onFailure {
@@ -20,24 +18,26 @@ inline fun PluginCall.autoRejectOnError(onFailure:(Throwable?)-> Unit, invoke:()
2018
}
2119
}
2220

23-
inline fun PluginCall.exists(key: String,onFailure:(()-> Unit) = {},onSuccess:(()-> Unit) = {}){
24-
if (data.has(key).not()){
21+
inline fun PluginCall.exists(key: String, onFailure: (() -> Unit) = {}, onSuccess: (() -> Unit) = {}) {
22+
if (data.has(key).not()) {
2523
reject("$key is not set")
2624
onFailure.invoke()
27-
}else{
25+
} else {
2826
onSuccess.invoke()
2927
}
3028
}
3129

32-
inline fun PluginCall.existsNot(key: String,onFailure:(()-> Unit) = {}){
33-
if (data.has(key).not()){
30+
inline fun PluginCall.existsNot(key: String, onFailure: (() -> Unit) = {}) {
31+
if (data.has(key).not()) {
3432
reject("$key is not set")
3533
onFailure.invoke()
3634
}
3735
}
3836

39-
fun async(context: CoroutineContext = Dispatchers.IO,
40-
start: CoroutineStart = CoroutineStart.DEFAULT,
41-
block: suspend CoroutineScope.() -> Unit){
42-
MainActivity.lifeCycleScope.launch(context,start,block)
43-
}
37+
fun async(
38+
context: CoroutineContext = Dispatchers.IO,
39+
start: CoroutineStart = CoroutineStart.DEFAULT,
40+
block: suspend CoroutineScope.() -> Unit
41+
) {
42+
MainActivity.lifeCycleScope.launch(context, start, block)
43+
}

www/index.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@
164164
<script src="./js/build/main.build.js"></script>
165165

166166
<title>Acode</title>
167-
<!--styles-->
167+
168+
<!--styles-->
168169
<link rel="stylesheet" href="./css/build/about.css">
169170
<link rel="stylesheet" href="./css/build/customTheme.css">
170171
<link rel="stylesheet" href="./css/build/donate.css">

0 commit comments

Comments
 (0)