Skip to content

Commit 3533877

Browse files
committed
Fix crash issues
1 parent 23bbea1 commit 3533877

28 files changed

+140
-97
lines changed

app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ android {
4141
else -> 0
4242
}
4343

44-
val vCode = 409
44+
val vCode = 412
4545
versionCode = vCode - singleAbiNum
46-
versionName = "2.1.9"
46+
versionName = "2.1.10"
4747

4848
ndk {
4949
//noinspection ChromeOsAbiSupport

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@
164164
</service>
165165

166166
<service
167-
android:name=".services.AudioPlayerService"
167+
android:name="com.ismartcoding.plain.services.AudioPlayerService"
168168
android:enabled="true"
169169
android:exported="true"
170170
android:foregroundServiceType="mediaPlayback">

app/src/main/java/com/ismartcoding/plain/MainApp.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package com.ismartcoding.plain
22

33
import android.app.Application
44
import android.os.Build
5+
import android.view.textclassifier.TextClassificationManager
6+
import android.view.textclassifier.TextClassifier
57
import com.ismartcoding.lib.channel.sendEvent
68
import com.ismartcoding.lib.helpers.CoroutinesHelper.coIO
79
import com.ismartcoding.lib.isUPlus
@@ -51,6 +53,13 @@ class MainApp : Application() {
5153
ZipPathValidator.clearCallback()
5254
}
5355

56+
// Disable Smart Text Selection to avoid framework crash in SmartSelectSprite
57+
try {
58+
val manager = getSystemService(TextClassificationManager::class.java)
59+
manager?.setTextClassifier(TextClassifier.NO_OP)
60+
} catch (_: Throwable) {
61+
}
62+
5463
coIO {
5564
val preferences = dataStore.getPreferencesAsync()
5665
TempData.webEnabled = WebPreference.get(preferences)

app/src/main/java/com/ismartcoding/plain/features/Permissions.kt

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,14 @@ enum class Permission {
175175
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
176176
intentLauncher?.launch(intent)
177177
} catch (e: Exception) {
178-
val intent = Intent()
179-
intent.action = Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION
180-
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
181-
if (intent.resolveActivity(packageManager) != null) {
182-
intentLauncher?.launch(intent)
178+
val appDetailsIntent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
179+
data = Uri.parse("package:${context.packageName}")
180+
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
181+
}
182+
if (appDetailsIntent.resolveActivity(packageManager) != null) {
183+
intentLauncher?.launch(appDetailsIntent)
183184
} else {
184-
DialogHelper.showMessage(
185-
"ActivityNotFoundException: No Activity found to handle Intent act=android.settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION",
186-
)
185+
DialogHelper.showMessage("Cannot open app settings to grant storage access.")
187186
}
188187
}
189188
} else if (this == WRITE_SETTINGS) {

app/src/main/java/com/ismartcoding/plain/helpers/AppHelper.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE
66
import android.content.Context
77
import android.content.Intent
88
import com.ismartcoding.lib.helpers.JsonHelper.jsonDecode
9+
import android.os.Handler
10+
import android.os.Looper
11+
import android.os.Process
912
import com.ismartcoding.plain.BuildConfig
1013
import com.ismartcoding.plain.Constants
1114
import com.ismartcoding.plain.MainApp

app/src/main/java/com/ismartcoding/plain/helpers/NotificationHelper.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ object NotificationHelper {
7575
)
7676

7777
return NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_ID).apply {
78-
setSmallIcon(R.drawable.notification)
78+
setSmallIcon(R.drawable.ic_stat_notification)
7979
setContentTitle(title)
8080
setContentText(description)
8181
setVisibility(NotificationCompat.VISIBILITY_PUBLIC)

app/src/main/java/com/ismartcoding/plain/ui/MainActivity.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import androidx.compose.runtime.mutableStateOf
2323
import androidx.compose.runtime.getValue
2424
import androidx.compose.runtime.setValue
2525
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
26+
import androidx.core.content.ContextCompat
2627
import androidx.core.view.WindowCompat
2728
import androidx.core.view.WindowInsetsControllerCompat
2829
import androidx.lifecycle.lifecycleScope
@@ -130,7 +131,7 @@ class MainActivity : AppCompatActivity() {
130131
val service = Intent(this, ScreenMirrorService::class.java)
131132
service.putExtra("code", result.resultCode)
132133
service.putExtra("data", result.data)
133-
startService(service)
134+
ContextCompat.startForegroundService(this, service)
134135
} else {
135136
sendEvent(WebSocketEvent(EventType.SCREEN_MIRRORING, image))
136137
}

app/src/main/java/com/ismartcoding/plain/ui/base/PTopAppBar.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ fun PTopAppBar(
2222
modifier: Modifier = Modifier,
2323
navController: NavHostController,
2424
navigationIcon: (@Composable () -> Unit)? = {
25-
NavigationBackIcon { navController.popBackStack() }
25+
NavigationBackIcon { navController.navigateUp() }
2626
},
2727
title: String,
2828
subtitle: String = "",

app/src/main/java/com/ismartcoding/plain/ui/components/mediaviewer/previewer/MediaPreviewer.kt

Lines changed: 52 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class PreviewerPlaceholder(
9191
fun MediaPreviewer(
9292
state: MediaPreviewerState,
9393
getItem: (Int) -> PreviewItem = { index ->
94-
MediaPreviewData.items[index]
94+
MediaPreviewData.items.getOrNull(index) ?: PreviewItem(index.toString())
9595
},
9696
castVM: CastViewModel = viewModel(),
9797
tagsVM: TagsViewModel? = null,
@@ -156,59 +156,68 @@ fun MediaPreviewer(
156156

157157
) {
158158
key(page) {
159-
val item = remember(page) {
160-
getItem(page)
159+
val item = remember(page, MediaPreviewData.items.size) {
160+
MediaPreviewData.items.getOrNull(page)
161+
}
162+
if (item != null) {
163+
MediaViewer(
164+
modifier = Modifier.fillMaxSize(),
165+
pagerState = state.pagerState,
166+
videoState = state.videoState,
167+
page = page,
168+
model = getModel(item),
169+
state = viewerState,
170+
boundClip = false,
171+
gesture = GestureScope(
172+
onTap = {
173+
state.showActions = !state.showActions
174+
},
175+
onDoubleTap = {
176+
scope.launch {
177+
viewerState.toggleScale(it)
178+
}
179+
false
180+
},
181+
onLongPress = {}
182+
),
183+
)
161184
}
162-
MediaViewer(
163-
modifier = Modifier.fillMaxSize(),
164-
pagerState = state.pagerState,
165-
videoState = state.videoState,
166-
page = page,
167-
model = getModel(item),
168-
state = viewerState,
169-
boundClip = false,
170-
gesture = GestureScope(
171-
onTap = {
172-
state.showActions = !state.showActions
173-
},
174-
onDoubleTap = {
175-
scope.launch {
176-
viewerState.toggleScale(it)
177-
}
178-
false
179-
},
180-
onLongPress = {}
181-
),
182-
)
183185
}
184186
}
185187
},
186188
)
187189
}
188-
val m = remember(state.pagerState.currentPage) {
189-
getItem(state.pagerState.currentPage)
190+
val m = remember(state.pagerState.currentPage, MediaPreviewData.items.size) {
191+
MediaPreviewData.items.getOrNull(state.pagerState.currentPage)
190192
}
191-
if (m.path.isVideoFast()) {
192-
VideoPreviewActions(context = context, castViewModel = castVM, m = m, state)
193-
} else {
194-
ImagePreviewActions(context = context, castViewModel = castVM, m = m, state)
193+
if (m != null) {
194+
if (m.path.isVideoFast()) {
195+
VideoPreviewActions(context = context, castViewModel = castVM, m = m, state)
196+
} else {
197+
ImagePreviewActions(context = context, castViewModel = castVM, m = m, state)
198+
}
195199
}
196200
}
197201
}
198202
if (state.showMediaInfo) {
199-
val m = getItem(state.pagerState.currentPage)
200-
ViewMediaBottomSheet(
201-
m,
202-
tagsVM, tagsMap, tagsState,
203-
onDismiss = {
204-
state.showMediaInfo = false
205-
},
206-
onRenamedAsync = onRenamed,
207-
deleteAction = {
208-
deleteAction(m)
209-
},
210-
onTagsChangedAsync = onTagsChanged
211-
)
203+
val m = MediaPreviewData.items.getOrNull(state.pagerState.currentPage)
204+
if (m != null) {
205+
ViewMediaBottomSheet(
206+
m,
207+
tagsVM, tagsMap, tagsState,
208+
onDismiss = {
209+
state.showMediaInfo = false
210+
},
211+
onRenamedAsync = onRenamed,
212+
deleteAction = {
213+
deleteAction(m)
214+
},
215+
onTagsChangedAsync = onTagsChanged
216+
)
217+
} else {
218+
// No valid item; ensure the info panel is closed
219+
state.showMediaInfo = false
220+
}
212221
}
213222

214223
state.ticket.Next()

app/src/main/java/com/ismartcoding/plain/ui/components/mediaviewer/previewer/MediaPreviewerState.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ fun rememberPreviewerState(
5454
verticalDragType: VerticalDragType = VerticalDragType.UpAndDown,
5555
@IntRange(from = 0) initialPage: Int = 0,
5656
pageCount: () -> Int = { MediaPreviewData.items.size },
57-
getKey: (Int) -> Any = { MediaPreviewData.items[it].id },
57+
getKey: (Int) -> Any = { index ->
58+
MediaPreviewData.items.getOrNull(index)?.id ?: index
59+
},
5860
): MediaPreviewerState {
5961
val pagerState = rememberPagerState(initialPage, pageCount = pageCount)
6062
val mediaPreviewerState = rememberSaveable(saver = MediaPreviewerState.getSaver(pagerState)) {

0 commit comments

Comments
 (0)