diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt index f5c66ee6..55b351b5 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt @@ -219,6 +219,8 @@ object AppConfig { const val REALITY = "reality" const val HEADER_TYPE_HTTP = "http" + const val UNIDENTIFIED_PACKAGE = "__unknown_app__" + val DNS_ALIDNS_ADDRESSES = arrayListOf("223.5.5.5", "223.6.6.6", "2400:3200::1", "2400:3200:baba::1") val DNS_CLOUDFLARE_ONE_ADDRESSES = arrayListOf("1.1.1.1", "1.0.0.1", "2606:4700:4700::1111", "2606:4700:4700::1001") val DNS_CLOUDFLARE_DNS_COM_ADDRESSES = arrayListOf("104.16.132.229", "104.16.133.229", "2606:4700::6810:84e5", "2606:4700::6810:85e5") diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/AppPickerActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/AppPickerActivity.kt index c3234b31..6c148176 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/AppPickerActivity.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/AppPickerActivity.kt @@ -1,5 +1,6 @@ package com.v2ray.ang.ui +import android.annotation.SuppressLint import android.content.Context import android.content.Intent import android.os.Bundle @@ -7,11 +8,13 @@ import android.view.Menu import android.view.MenuItem import androidx.appcompat.widget.SearchView import androidx.lifecycle.lifecycleScope +import com.v2ray.ang.AppConfig import com.v2ray.ang.R import com.v2ray.ang.databinding.ActivityAppPickerBinding import com.v2ray.ang.dto.AppInfo import com.v2ray.ang.util.AppManagerUtil import com.v2ray.ang.util.LogUtil +import com.v2ray.ang.util.PackageUidResolver import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -101,6 +104,21 @@ class AppPickerActivity : BaseActivity() { addCustomDividerToRecyclerView(binding.recyclerView, this, R.drawable.custom_divider) } + @SuppressLint("UseCompatLoadingForDrawables") + private fun createSpecialItemUnidentified(): AppInfo { + val icon = requireNotNull( + getDrawable(android.R.drawable.ic_menu_help) + ?: getDrawable(android.R.drawable.sym_def_app_icon) + ) { "No fallback drawable available" } + return AppInfo( + appName = getString(R.string.app_picker_unknown_app), + packageName = AppConfig.UNIDENTIFIED_PACKAGE, + appIcon = icon, + isSystemApp = false, + isSelected = 0 + ) + } + private fun loadApps() { showLoading() @@ -108,7 +126,8 @@ class AppPickerActivity : BaseActivity() { try { val apps = withContext(Dispatchers.IO) { val appsList = AppManagerUtil.loadNetworkAppList(this@AppPickerActivity) - sortApps(appsList) + val sortedApps = sortApps(appsList) + listOf(createSpecialItemUnidentified()) + sortedApps } appsAll = apps diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/util/PackageUidResolver.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/util/PackageUidResolver.kt index 42627c05..d609c13c 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/util/PackageUidResolver.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/util/PackageUidResolver.kt @@ -2,12 +2,11 @@ package com.v2ray.ang.util import android.content.Context import android.content.pm.PackageManager +import com.v2ray.ang.AppConfig import java.util.concurrent.ConcurrentHashMap object PackageUidResolver { - private const val TAG = "PackageUidResolver" - // In-process cache to avoid resolving the same package UID repeatedly. private val packageUidCache = ConcurrentHashMap() @@ -32,13 +31,20 @@ object PackageUidResolver { } private fun resolveUid(context: Context, packageName: String): String? { + // Special token for connections whose UID cannot be resolved (mapped to -1) + if (packageName == AppConfig.UNIDENTIFIED_PACKAGE) { + val uid = "-1" + LogUtil.d(AppConfig.TAG, "Special package: $packageName -> UID: $uid") + return uid + } + return try { val uid = context.packageManager.getPackageUid(packageName, 0).toString() - LogUtil.d(TAG, "Package: $packageName -> UID: $uid") + LogUtil.d(AppConfig.TAG, "Package: $packageName -> UID: $uid") uid } catch (_: PackageManager.NameNotFoundException) { - LogUtil.w(TAG, "Package not found: $packageName") + LogUtil.w(AppConfig.TAG, "Package not found: $packageName") null } } -} \ No newline at end of file +} diff --git a/V2rayNG/app/src/main/res/values/strings.xml b/V2rayNG/app/src/main/res/values/strings.xml index 1eb2d747..88a1a3c1 100644 --- a/V2rayNG/app/src/main/res/values/strings.xml +++ b/V2rayNG/app/src/main/res/values/strings.xml @@ -144,6 +144,7 @@ Import from Clipboard Per-app settings Enable per-app + Unknown app (unidentified UID) Settings