小编Cod*_*Lee的帖子

java.lang.SecurityException:在uid -1下指定了包“包名称”,但它不在Android 13中

我使用它是Settings.ACTION_APPLICATION_DETAILS_SETTINGS为了在用户未故意授予权限时发出请求。

Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getActivity().getPackageName(), null);
intent.setData(uri);
getActivity().startActivity(intent);
Run Code Online (Sandbox Code Playgroud)

该代码仅在 Android 13 下运行良好。如果我在 Android 13 中运行此代码,则会发生异常。

 "Bad call made by uid 1000. Package "package name" does not belong to uid -1.
noteOperation
java.lang.SecurityException: Specified package "package name" under uid -1 but it is not
at com.android.server.appop.AppOpsService.verifyAndGetBypass(AppOpsService.java:4858)
at com.android.server.appop.AppOpsService.noteOperationUnchecked(AppOpsService.java:3586)
at com.android.server.appop.AppOpsService.noteOperationImpl(AppOpsService.java:3574)
at com.android.server.appop.AppOpsService.-$$Nest$mnoteOperationImpl(Unknown Source:0)
at com.android.server.appop.AppOpsService$CheckOpsDelegateDispatcher.lambda$noteOperation$4(AppOpsService.java:7928)
at com.android.server.appop.AppOpsService$CheckOpsDelegateDispatcher.$r8$lambda$oOwUoG55BBmJ6yiwhp3OAq3tQ30(Unknown Source:0)
at com.android.server.appop.AppOpsService$CheckOpsDelegateDispatcher$$ExternalSyntheticLambda4.apply(Unknown Source:32)
at com.android.server.policy.AppOpsPolicy.noteOperation(AppOpsPolicy.java:225)
at com.android.server.appop.AppOpsService$CheckOpsDelegateDispatcher.noteOperation(AppOpsService.java:7926)
at com.android.server.appop.AppOpsService.noteOperation(AppOpsService.java:3558)
at com.android.internal.app.IAppOpsService$Stub.onTransact(IAppOpsService.java:486)
at android.os.Binder.execTransactInternal(Binder.java:1316)
at …
Run Code Online (Sandbox Code Playgroud)

android android-permissions android-settings

14
推荐指数
0
解决办法
2279
查看次数

为什么生成 LiveData 或 Flow 的函数不必从 CoroutineScope 调用?

当我们平时使用 Room 时,我们使用 Kotlin Coroutine 并创建一个 DAO 来访问 Room 并获取结果。大多数函数通常suspend在函数开头有修饰符 butLiveDataFlow。例如,让我们看一下下面的这两段代码。

@Query("SELECT * FROM MockTable")
suspend fun allMockDataWithSuspend(): List<MockData>

@Query("SELECT * FROM MockTable")
fun allMockData(): Flow<List<MockData>> // or LiveData<List<MockData>>
Run Code Online (Sandbox Code Playgroud)

当我们使用suspend修饰符时,我们需要在协程范围内调用该函数,因为该函数具有 suspend 修饰符。LiveData但是当函数的结果是或者Flow即使是 I/O 访问时,我们不需要在协程中调用该函数。

这怎么可能?

android android-room android-livedata kotlin-coroutines kotlin-flow

8
推荐指数
1
解决办法
2028
查看次数

为每个 Android 版本安装 APK 的正确方法是什么?

我正在制作一个 APK 安装应用程序,并且经历了很多。特别是版本控制。为此,我查阅了一些帖子和 StackOverFlow。但现在所有的帖子让我更加困惑。那么,什么是正确的方法呢?

首先,请检查我下面关于每个版本安装的代码。让我们谈谈什么是正确的方法。

KitKat(API 19)、棒棒糖(API 21)、MashMellow(API 23)

fun installApkBelowNougat(apkFile: File) {
  val apkUri = Uri.fromFile(apkFile)
  val intent = Intent(Intent.ACTION_VIEW).apply {
    setDataAndType(apkUri, "application/vnd.android.package-archive")
    flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
  }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,所有解决方案都是相同的,我们必须使用Uri.fromFile(file)来获得Uri.

牛轧糖(API 24)

fun installApkInNougat(apkFile: File) {
  val apkUri = FileProvider.getUriForFile(applicationContext, applicationContext.packageName + ".fileProvider", apkFile)
  val intent = Intent(Intent.ACTION_VIEW).apply {
    setDataAndType(apkUri, "application/vnd.android.package-archive")
    flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
    addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
  }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们就不能再使用了Uri.fromFile(file)。因此,我们必须使用FileProvider“Nougat”来代替它。并且我们还必须<proivder/>在AndroidManifest.xml中这样写。

...
<provider
  android:name="androidx.core.content.FileProvider"
  android:authorities="${applicationId}.fileProvider"
  android:exported="false"
  android:grantUriPermissions="true">
     <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS" …
Run Code Online (Sandbox Code Playgroud)

android apk android-package-managers android-fileprovider

6
推荐指数
0
解决办法
1277
查看次数

PendingIntent.FLAG_IMMUTABLE 可以替换 PendingIntent.FLAG_UPDATE_CURRENT 吗?

我正在PendingIntent处理notification. 在我的项目中,我一直PendingIntent.FLAG_UPDATE_CURRENT在一些代码中使用。它的定义如下。

标志指示如果所描述的 PendingIntent 已经存在,则保留它,但用这个新 Intent 中的内容替换其额外数据。用于 getActivity(Context, int, Intent, int)、getBroadcast(Context, int, Intent, int) 和 getService(Context, int, Intent, int)。

如果您正在创建仅额外内容发生变化的意图,并且不关心接收到您之前的 PendingIntent 的任何实体将能够使用新的额外内容启动它,即使它们没有明确提供给它,则可以使用此方法。

即使设置了 FLAG_IMMUTABLE,FLAG_UPDATE_CURRENT 仍然有效 - PendingIntent 的创建者始终可以更新 PendingIntent 本身。IMMUTABLE 标志仅限制 send() 调用者更改 send() 发送的意图语义的能力。


但我必须选择FLAG_IMMUTABLE还是FLAG_MUTABLE因为Android12。就我而言,我不需要使用PendingIntent.FLAG_MUTABLE. 它的定义如下。

指示创建的 PendingIntent 应该是不可变的标志。这意味着传递给发送方法以填充此意图的未填充属性的附加意图参数将被忽略。

FLAG_IMMUTABLE 仅限制 send() 调用者更改 send() 发送的意图语义的能力。PendingIntent 的创建者始终可以通过 FLAG_UPDATE_CURRENT 更新 PendingIntent 本身。

正如你所看到的,他们说“即使设置了 FLAG_IMMUTABLE,FLAG_UPDATE_CURRENT 仍然有效...”和“PendingIntent 的创建者始终可以通过 FLAG_UPDATE_CURRENT 更新 PendingIntent 本身。”

那么,我想知道的是,它可以在任何Android版本中FLAG_IMMUTABLE完美替代吗?FLAG_UPDATE_CURRENT

例如

PendingIntent.getActivity(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); …
Run Code Online (Sandbox Code Playgroud)

android android-notifications android-pendingintent

6
推荐指数
1
解决办法
3787
查看次数

Android12中的数据提取规则

当我们不想维护SharedPreferences或任何备份文件时,我们可以直接设置android:allowBackup="false"AndroidManifest.xml.
android:allowBackup="false"在 Android12 中已弃用。尽管它已被弃用,我们仍然可以继续使用它cloud-based backup。例如,如果我们正在使用SharedPreferences,则删除我们的应用程序并重新安装后,它们SharedPreferences就会消失。您可以从这里找到信息。

所以,我想了解的是D2D。在Android12中,Android系统自动将文件从旧设备发送到新设备(D2D)。我想阻止系统SharedPreferences默认自动发送文件(如)。所以,我必须确定dataExtractionRules 哪些文件包含或不包含。

我想要做的是排除所有文件。这意味着我可以将应用程序传输到新设备,但没有数据或缓存,就像我刚刚下载了新应用程序一样。那么,我该如何写作dataExtractionRules来实现它呢?

请检查以下代码我做了什么。

数据提取规则.xml

<?xml version="1.0" encoding="utf-8"?>
<data-extraction-rules>

<!-- <cloud-backup> I don't write cloud-backups in here
 because i can still use android:allowBackup="false" </cloud-backup> -->
    
    <device-transfer>
        <exclude domain="root" path="where?" />
        <exclude domain="file" path="where?" />
        <exclude domain="database" path="where?" />
        <exclude domain="sharedpref" path="com.google.android.gms.appid.xml" />
        <exclude domain="sharedpref" path="user_pref.xml" />
        <!-- <exclude domain="external" path="where?" /> --> …
Run Code Online (Sandbox Code Playgroud)

android android-manifest android-backup-service android-12

5
推荐指数
1
解决办法
2852
查看次数

如何在 Android 中继续显示底部导航菜单标题?

我在底部导航视图中有 5 个图标,当我单击菜单时,我可以看到菜单的标题,如果我单击另一个图标,前一个的标题就会消失。我想继续以 XML 形式显示所有菜单的标题。我该怎么做?

这是我在活动 XML 中的代码。

 <androidx.coordinatorlayout.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true">

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNV"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:backgroundTint="@color/light_gray"
        app:itemIconTint="@color/black"
        app:itemTextColor="@color/black"
        app:menu="@menu/bottom_navigation_menu"/>


</androidx.coordinatorlayout.widget.CoordinatorLayout>
Run Code Online (Sandbox Code Playgroud)

这是一个菜单资源文件。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
    android:id="@+id/bottom_menu_home"
    android:enabled="true"
    android:icon="@drawable/bottom_home_inactive"
    android:title="@string/bottom_menu_home" />

<item
    android:id="@+id/bottom_menu_search"
    android:enabled="true"
    android:icon="@drawable/bottom_search_inactive"
    android:title="@string/bottom_menu_search" />

<item
    android:id="@+id/bottom_menu_message"
    android:enabled="true"
    android:icon="@drawable/bottom_message_inactive"
    android:title="@string/bottom_menu_message" />

<item
    android:id="@+id/bottom_menu_reservation"
    android:enabled="true"
    android:icon="@drawable/bottom_reservation_inactive"
    android:title="@string/bottom_menu_reservation" />

<item
    android:id="@+id/bottom_menu_myInfo"
    android:enabled="true"
    android:icon="@drawable/bottom_myinfo_inactive"
    android:title="@string/bottom_menu_myInfo" />
Run Code Online (Sandbox Code Playgroud)

android android-xml bottomnavigationview material-components-android android-bottomnavigationview

3
推荐指数
1
解决办法
2788
查看次数

Android 中 Flow 的一次性操作

我正在尝试在 中显示用户信息DetailActivity。因此,我请求数据并从服务器获取用户的数据。但在本例中,返回类型是Flow<User>. 让我向您展示以下代码。

ServiceApi.kt

@GET("endpoint")
suspend fun getUser(@Query("id") id: Int): Response<User>
Run Code Online (Sandbox Code Playgroud)

存储库.kt

fun getUser(id: Int): Flow<User> = flow<User> {
    val userResponse = api.getUser(id = id)
    if (userResponse.isSuccessful) {
        val user = userResponse.body()
        emit(user)
    }
}
.flowOn(Dispatchers.IO)
.catch { // send error }
Run Code Online (Sandbox Code Playgroud)

详细视图模型.kt

class DetailViewModel(
    private val repository : Repository
) {
    val uiState: StateFlow<User> = repository.getUser(id = 369).stateIn(
        scope = viewModelScope,
        started = SharingStarted.WhileSubscribed(5000),
        initialValue = User() // empty user
    )
}
Run Code Online (Sandbox Code Playgroud)

详细活动.kt

class DetailActivity: …
Run Code Online (Sandbox Code Playgroud)

android android-lifecycle kotlin-flow

3
推荐指数
1
解决办法
1654
查看次数

Kotlin runBlocking 总是阻塞主线程?

关于runBlokcing的官方文档

\n
\n

运行新的协程并阻塞当前线程,直到\n完成。不应在协程中使用此函数。它旨在将常规阻塞代码桥接到以挂起方式编写的库,以在主函数和测试中使用。

\n
\n

我认为这意味着runBlocking仅阻止当前线程。

\n

Kotlin Coroutines Deep Dive所写的Marcin Moska\xc5\x82a
\n书上说

\n
\n

“使用调度程序,我们可以使 runBlocking 在不同的线程上运行。但是,启动此构建器的线程仍然会被阻塞,直到协程完成为止。”

\n
\n

我理解,即使我将当前线程更改为工作线程(或其他)线程withContext,并在工作线程中运行“runBlocking”,runBlocking仍然会阻止包括主线程在内的所有线程。

\n

因此,我想知道的是runBlocking无论我使用什么方式总是阻塞主线程?

\n

android kotlin retrofit2 kotlin-coroutines

1
推荐指数
2
解决办法
917
查看次数

如何在活动之间共享 viewModel?

我现在正在学习 Android ViewModel。我有 MainActivity 和 RegisterActivity ,它们可以在其中输入姓名、年龄和电话号码。在 RegisterActivity 中输入该信息后,我将该信息放入 ViewModel 并单击一个按钮并完成 RegisterActivity。问题是,我想在 MainActivity 中显示信息。那么如何在两个活动之间共享 viewModel 呢?我必须使用什么概念?

android android-databinding android-viewmodel

0
推荐指数
1
解决办法
437
查看次数