「アプリ設定/挙動/Webブラウザ」を追加
This commit is contained in:
parent
70dd21bf41
commit
35deaf985f
|
@ -20,6 +20,18 @@
|
|||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
</intent>
|
||||
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="https" />
|
||||
</intent>
|
||||
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="http" />
|
||||
</intent>
|
||||
|
||||
<!-- Chrome Custom Tabs の存在確認 -->
|
||||
<intent>
|
||||
<action android:name="android.support.customtabs.action.CustomTabsService" />
|
||||
|
|
|
@ -2,6 +2,7 @@ package jp.juggler.subwaytooter
|
|||
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.content.pm.ResolveInfo
|
||||
import android.graphics.Color
|
||||
import android.graphics.Typeface
|
||||
import android.net.Uri
|
||||
|
@ -21,13 +22,14 @@ import androidx.core.content.ContextCompat
|
|||
import androidx.core.content.FileProvider
|
||||
import com.jrummyapps.android.colorpicker.ColorPickerDialog
|
||||
import com.jrummyapps.android.colorpicker.ColorPickerDialogListener
|
||||
import jp.juggler.subwaytooter.util.CustomShare
|
||||
import jp.juggler.subwaytooter.util.CustomShareTarget
|
||||
import jp.juggler.subwaytooter.dialog.DlgAppPicker
|
||||
import jp.juggler.subwaytooter.notification.PollingWorker
|
||||
import jp.juggler.subwaytooter.table.AcctColor
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.subwaytooter.util.AsyncActivity
|
||||
import jp.juggler.subwaytooter.util.CustomShare
|
||||
import jp.juggler.subwaytooter.util.CustomShareTarget
|
||||
import jp.juggler.subwaytooter.util.cn
|
||||
import jp.juggler.util.*
|
||||
import org.apache.commons.io.IOUtils
|
||||
import java.io.File
|
||||
|
@ -1127,7 +1129,7 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
|
|||
return list.size
|
||||
}
|
||||
|
||||
override fun getItem(position : Int) : Any? {
|
||||
override fun getItem(position : Int) : Any {
|
||||
return list[position]
|
||||
}
|
||||
|
||||
|
@ -1164,16 +1166,17 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
|
|||
}
|
||||
}
|
||||
|
||||
fun openCustomShareChooser(target : CustomShareTarget) {
|
||||
fun openCustomShareChooser(appSettingItem: AppSettingItem,target : CustomShareTarget) {
|
||||
try {
|
||||
val rv = DlgAppPicker(
|
||||
this,
|
||||
Intent().apply {
|
||||
intent = Intent().apply {
|
||||
action = Intent.ACTION_SEND
|
||||
type = "text/plain"
|
||||
putExtra(Intent.EXTRA_TEXT, getString(R.string.content_sample))
|
||||
}
|
||||
) { setCustomShare(target, it) }
|
||||
},
|
||||
addCopyAction = true
|
||||
) { setCustomShare(appSettingItem,target, it) }
|
||||
.show()
|
||||
if(! rv) showToast(true, "share target app is not installed.")
|
||||
} catch(ex : Throwable) {
|
||||
|
@ -1182,22 +1185,11 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
|
|||
}
|
||||
}
|
||||
|
||||
fun setCustomShare(target : CustomShareTarget?, value : String) {
|
||||
|
||||
target ?: return
|
||||
|
||||
val item = when(target) {
|
||||
CustomShareTarget.Translate -> AppSettingItem.CUSTOM_TRANSLATE
|
||||
CustomShareTarget.CustomShare1 -> AppSettingItem.CUSTOM_SHARE_1
|
||||
CustomShareTarget.CustomShare2 -> AppSettingItem.CUSTOM_SHARE_2
|
||||
CustomShareTarget.CustomShare3 -> AppSettingItem.CUSTOM_SHARE_3
|
||||
}
|
||||
?: error("setCustomShare $target has no setting item.")
|
||||
|
||||
val sp : StringPref = item.pref.cast() ?: error("$target: not StringPref")
|
||||
fun setCustomShare(appSettingItem: AppSettingItem,target : CustomShareTarget, value : String) {
|
||||
val sp : StringPref = appSettingItem.pref.cast() ?: error("$target: not StringPref")
|
||||
pref.edit().put(sp, value).apply()
|
||||
|
||||
showCustomShareIcon(findItemViewHolder(item)?.textView1, target)
|
||||
showCustomShareIcon(findItemViewHolder(appSettingItem)?.textView1, target)
|
||||
}
|
||||
|
||||
fun showCustomShareIcon(tv : TextView?, target : CustomShareTarget) {
|
||||
|
@ -1208,5 +1200,36 @@ class ActAppSetting : AsyncActivity(), ColorPickerDialogListener, View.OnClickLi
|
|||
tv.setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null)
|
||||
tv.compoundDrawablePadding = (resources.displayMetrics.density * 4f + 0.5f).toInt()
|
||||
}
|
||||
|
||||
|
||||
fun openWebBrowserChooser(appSettingItem: AppSettingItem, intent:Intent, filter: (ResolveInfo) -> Boolean ) {
|
||||
try {
|
||||
val rv = DlgAppPicker(
|
||||
this,
|
||||
intent=intent,
|
||||
filter = filter,
|
||||
addCopyAction = false
|
||||
) { setWebBrowser( appSettingItem,it) }
|
||||
.show()
|
||||
if(! rv) showToast(true, "share target app is not installed.")
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
showToast(ex, "openCustomShareChooser failed.")
|
||||
}
|
||||
}
|
||||
|
||||
fun setWebBrowser(appSettingItem: AppSettingItem, value : String) {
|
||||
val sp : StringPref = appSettingItem.pref.cast() ?: error("${getString(appSettingItem.caption)}: not StringPref")
|
||||
pref.edit().put(sp, value).apply()
|
||||
|
||||
showWebBrowser(findItemViewHolder(appSettingItem)?.textView1, value )
|
||||
}
|
||||
|
||||
fun showWebBrowser(tv : TextView?,prefValue:String) {
|
||||
tv ?: return
|
||||
val cn =prefValue.cn()
|
||||
val (label, icon) = CustomShare.getInfo(this, cn)
|
||||
tv.text = label ?: getString(R.string.not_selected)
|
||||
tv.setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null)
|
||||
tv.compoundDrawablePadding = (resources.displayMetrics.density * 4f + 0.5f).toInt()
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -591,7 +591,8 @@ object Pref {
|
|||
val spCustomShare1 = StringPref("CustomShare1", "")
|
||||
val spCustomShare2 = StringPref("CustomShare2", "")
|
||||
val spCustomShare3 = StringPref("CustomShare3", "")
|
||||
|
||||
val spWebBrowser = StringPref("WebBrowser", "")
|
||||
|
||||
val spTimelineSpacing = StringPref("TimelineSpacing", "")
|
||||
|
||||
// long
|
||||
|
|
|
@ -21,8 +21,9 @@ class DlgAppPicker(
|
|||
val activity: Activity,
|
||||
val intent: Intent,
|
||||
val autoSelect: Boolean = false,
|
||||
val addCopyAction:Boolean= false,
|
||||
val filter: (ResolveInfo) -> Boolean = { true },
|
||||
val callback: (String) -> Unit
|
||||
val callback: (String) -> Unit,
|
||||
) {
|
||||
|
||||
companion object {
|
||||
|
@ -55,7 +56,7 @@ class DlgAppPicker(
|
|||
}
|
||||
|
||||
// 自動選択オフの場合、末尾にクリップボード項目を追加する
|
||||
if (!autoSelect) {
|
||||
if (addCopyAction && !autoSelect) {
|
||||
val (label, icon) = CustomShare.getInfo(activity, CustomShare.CN_CLIPBOARD.cn())
|
||||
add(ListItem(icon, label.toString(), CustomShare.CN_CLIPBOARD))
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import android.net.Uri
|
|||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.app.Activity
|
||||
import android.content.SharedPreferences
|
||||
import androidx.browser.customtabs.CustomTabColorSchemeParams
|
||||
import androidx.browser.customtabs.CustomTabsIntent
|
||||
import jp.juggler.subwaytooter.ActMain
|
||||
|
@ -40,15 +41,23 @@ private val log = LogCategory("AppOpener")
|
|||
// returns true if activity is opened.
|
||||
// returns false if fallback required
|
||||
private fun Activity.startActivityExcludeMyApp(
|
||||
pref:SharedPreferences,
|
||||
intent: Intent,
|
||||
startAnimationBundle: Bundle? = null
|
||||
): Boolean {
|
||||
try {
|
||||
if( intent.component == null){
|
||||
val cn = Pref.spWebBrowser(pref).cn()
|
||||
if( cn?.exists(this) == true){
|
||||
intent.component = cn
|
||||
}
|
||||
}
|
||||
|
||||
// このアプリのパッケージ名
|
||||
val myName = packageName
|
||||
|
||||
val filter: (ResolveInfo) -> Boolean = {
|
||||
when{
|
||||
when {
|
||||
it.activityInfo.packageName == myName -> false
|
||||
!it.activityInfo.exported -> false
|
||||
|
||||
|
@ -57,7 +66,7 @@ private fun Activity.startActivityExcludeMyApp(
|
|||
|
||||
// 標準アプリが設定されていない場合、アプリを選択するためのActivityが出てくる場合がある
|
||||
it.activityInfo.packageName == "android" -> false
|
||||
it.activityInfo.javaClass.name.startsWith( "com.android.internal") -> false
|
||||
it.activityInfo.javaClass.name.startsWith("com.android.internal") -> false
|
||||
it.activityInfo.javaClass.name.startsWith("com.android.systemui") -> false
|
||||
|
||||
// たぶんChromeとかfirefoxとか
|
||||
|
@ -89,7 +98,8 @@ private fun Activity.startActivityExcludeMyApp(
|
|||
this,
|
||||
intent,
|
||||
autoSelect = true,
|
||||
filter = filter
|
||||
filter = filter,
|
||||
addCopyAction = false
|
||||
) {
|
||||
try {
|
||||
intent.component = it.cn()
|
||||
|
@ -108,16 +118,20 @@ private fun Activity.startActivityExcludeMyApp(
|
|||
}
|
||||
}
|
||||
|
||||
fun Activity.openBrowser(uri: Uri?) {
|
||||
fun Activity.openBrowser(uri: Uri? , pref:SharedPreferences = pref()) {
|
||||
uri ?: return
|
||||
val rv = startActivityExcludeMyApp(Intent(Intent.ACTION_VIEW, uri))
|
||||
val rv = startActivityExcludeMyApp(
|
||||
pref,
|
||||
Intent(Intent.ACTION_VIEW, uri)
|
||||
.apply { addCategory(Intent.CATEGORY_BROWSABLE) }
|
||||
)
|
||||
if (!rv) showToast(true, "there is no app that can open $uri")
|
||||
}
|
||||
|
||||
fun Activity.openBrowser(url: String?) = openBrowser(url.mayUri())
|
||||
fun Activity.openBrowser(url: String?, pref:SharedPreferences = pref()) = openBrowser(url.mayUri(),pref)
|
||||
|
||||
// Chrome Custom Tab を開く
|
||||
fun Activity.openCustomTab(url: String?) {
|
||||
fun Activity.openCustomTab(url: String?, pref:SharedPreferences = pref()) {
|
||||
url ?: return
|
||||
|
||||
if (url.isEmpty()) {
|
||||
|
@ -125,9 +139,8 @@ fun Activity.openCustomTab(url: String?) {
|
|||
return
|
||||
}
|
||||
|
||||
val pref = pref()
|
||||
if (Pref.bpDontUseCustomTabs(pref)) {
|
||||
openBrowser(url)
|
||||
openBrowser(url,pref)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -144,6 +157,7 @@ fun Activity.openCustomTab(url: String?) {
|
|||
.let {
|
||||
log.w("startCustomTabIntent ComponentName=$cn")
|
||||
startActivityExcludeMyApp(
|
||||
pref,
|
||||
it.intent.also { intent ->
|
||||
if (cn != null) intent.component = cn
|
||||
intent.data = url.toUri()
|
||||
|
|
|
@ -15,170 +15,179 @@ import jp.juggler.util.showToast
|
|||
import jp.juggler.util.systemService
|
||||
|
||||
enum class CustomShareTarget {
|
||||
Translate,
|
||||
CustomShare1,
|
||||
CustomShare2,
|
||||
CustomShare3,
|
||||
Translate,
|
||||
CustomShare1,
|
||||
CustomShare2,
|
||||
CustomShare3,
|
||||
}
|
||||
|
||||
object CustomShare {
|
||||
|
||||
val log = LogCategory("CustomShare")
|
||||
|
||||
const val CN_CLIPBOARD = "<InApp>/CopyToClipboard"
|
||||
|
||||
private const val translate_app_component_default =
|
||||
"com.google.android.apps.translate/com.google.android.apps.translate.TranslateActivity"
|
||||
|
||||
fun getCustomShareComponentName(
|
||||
pref : SharedPreferences,
|
||||
target : CustomShareTarget
|
||||
) : ComponentName? {
|
||||
val src : String
|
||||
val defaultComponentName : String?
|
||||
when(target) {
|
||||
|
||||
val log = LogCategory("CustomShare")
|
||||
|
||||
const val CN_CLIPBOARD = "<InApp>/CopyToClipboard"
|
||||
|
||||
private const val translate_app_component_default =
|
||||
"com.google.android.apps.translate/com.google.android.apps.translate.TranslateActivity"
|
||||
|
||||
fun getCustomShareComponentName(
|
||||
pref: SharedPreferences,
|
||||
target: CustomShareTarget
|
||||
): ComponentName? {
|
||||
val src: String
|
||||
val defaultComponentName: String?
|
||||
when (target) {
|
||||
CustomShareTarget.Translate -> {
|
||||
src = Pref.spTranslateAppComponent(pref)
|
||||
defaultComponentName = translate_app_component_default
|
||||
}
|
||||
|
||||
|
||||
CustomShareTarget.CustomShare1 -> {
|
||||
src = Pref.spCustomShare1(pref)
|
||||
defaultComponentName = null
|
||||
}
|
||||
|
||||
|
||||
CustomShareTarget.CustomShare2 -> {
|
||||
src = Pref.spCustomShare2(pref)
|
||||
defaultComponentName = null
|
||||
}
|
||||
|
||||
|
||||
CustomShareTarget.CustomShare3 -> {
|
||||
src = Pref.spCustomShare3(pref)
|
||||
defaultComponentName = null
|
||||
}
|
||||
}
|
||||
return src.cn() ?: defaultComponentName?.cn()
|
||||
}
|
||||
|
||||
fun getInfo(context : Context, cn : ComponentName?) : Pair<CharSequence?, Drawable?> {
|
||||
var label : CharSequence? = null
|
||||
var icon : Drawable? = null
|
||||
try {
|
||||
if(cn != null) {
|
||||
val cnStr = "${cn.packageName}/${cn.className}"
|
||||
label = cnStr
|
||||
if(cnStr == CN_CLIPBOARD) {
|
||||
label =
|
||||
"${context.getString(R.string.copy_to_clipboard)}(${context.getString(R.string.app_name)})"
|
||||
icon = ContextCompat.getDrawable(context, R.drawable.ic_copy)?.mutate()?.apply {
|
||||
setTint(context.getAttributeColor(R.attr.colorVectorDrawable))
|
||||
setTintMode(PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
} else {
|
||||
val pm = context.packageManager
|
||||
val ri = pm.resolveActivity(Intent().apply { component = cn }, 0)
|
||||
if(ri != null) {
|
||||
try {
|
||||
label = ri.loadLabel(pm)
|
||||
} catch(ex : Throwable) {
|
||||
log.e(ex, "loadLabel failed.")
|
||||
}
|
||||
try {
|
||||
icon = ri.loadIcon(pm)
|
||||
} catch(ex : Throwable) {
|
||||
log.e(ex, "loadIcon failed.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(ex : Throwable) {
|
||||
log.e(ex, "getInfo failed.")
|
||||
}
|
||||
return Pair(label, icon)
|
||||
}
|
||||
|
||||
fun invoke(
|
||||
context : Context,
|
||||
text : String,
|
||||
target : CustomShareTarget
|
||||
}
|
||||
return src.cn() ?: defaultComponentName?.cn()
|
||||
}
|
||||
|
||||
fun getInfo(context: Context, cn: ComponentName?): Pair<CharSequence?, Drawable?> {
|
||||
var label: CharSequence? = null
|
||||
var icon: Drawable? = null
|
||||
try {
|
||||
if (cn != null) {
|
||||
val cnStr = "${cn.packageName}/${cn.className}"
|
||||
label = cnStr
|
||||
if (cnStr == CN_CLIPBOARD) {
|
||||
label =
|
||||
"${context.getString(R.string.copy_to_clipboard)}(${context.getString(R.string.app_name)})"
|
||||
icon = ContextCompat.getDrawable(context, R.drawable.ic_copy)?.mutate()?.apply {
|
||||
setTint(context.getAttributeColor(R.attr.colorVectorDrawable))
|
||||
setTintMode(PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
} else {
|
||||
val pm = context.packageManager
|
||||
val ri = pm.resolveActivity(Intent().apply { component = cn }, 0)
|
||||
if (ri != null) {
|
||||
try {
|
||||
label = ri.loadLabel(pm)
|
||||
} catch (ex: Throwable) {
|
||||
log.e(ex, "loadLabel failed.")
|
||||
}
|
||||
try {
|
||||
icon = ri.loadIcon(pm)
|
||||
} catch (ex: Throwable) {
|
||||
log.e(ex, "loadIcon failed.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ex: Throwable) {
|
||||
log.e(ex, "getInfo failed.")
|
||||
}
|
||||
return Pair(label, icon)
|
||||
}
|
||||
|
||||
fun invoke(
|
||||
context: Context,
|
||||
text: String,
|
||||
target: CustomShareTarget
|
||||
) {
|
||||
// convert "pkgName/className" string to ComponentName object.
|
||||
val cn = getCustomShareComponentName(App1.pref, target)
|
||||
if(cn == null) {
|
||||
context.showToast(true, R.string.custom_share_app_not_found)
|
||||
return
|
||||
}
|
||||
val cnStr = "${cn.packageName}/${cn.className}"
|
||||
if(cnStr == CN_CLIPBOARD) {
|
||||
try {
|
||||
val cm : ClipboardManager = systemService(context) !!
|
||||
cm.setPrimaryClip(ClipData.newPlainText("", text))
|
||||
context.showToast(false, R.string.copied_to_clipboard)
|
||||
} catch(ex : Throwable) {
|
||||
context.showToast(ex, "copy to clipboard failed.")
|
||||
}
|
||||
return
|
||||
}
|
||||
try {
|
||||
val intent = Intent()
|
||||
intent.action = Intent.ACTION_SEND
|
||||
intent.type = "text/plain"
|
||||
intent.putExtra(Intent.EXTRA_TEXT, text)
|
||||
intent.component = cn
|
||||
context.startActivity(intent)
|
||||
} catch(ex : ActivityNotFoundException) {
|
||||
log.trace(ex)
|
||||
context.showToast(true, R.string.custom_share_app_not_found)
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
context.showToast(ex, "invoke() failed.")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun invoke(
|
||||
context : Context,
|
||||
access_info : SavedAccount,
|
||||
status : TootStatus?,
|
||||
target : CustomShareTarget
|
||||
// convert "pkgName/className" string to ComponentName object.
|
||||
val cn = getCustomShareComponentName(App1.pref, target)
|
||||
if (cn == null) {
|
||||
context.showToast(true, R.string.custom_share_app_not_found)
|
||||
return
|
||||
}
|
||||
val cnStr = "${cn.packageName}/${cn.className}"
|
||||
if (cnStr == CN_CLIPBOARD) {
|
||||
try {
|
||||
val cm: ClipboardManager = systemService(context)!!
|
||||
cm.setPrimaryClip(ClipData.newPlainText("", text))
|
||||
context.showToast(false, R.string.copied_to_clipboard)
|
||||
} catch (ex: Throwable) {
|
||||
context.showToast(ex, "copy to clipboard failed.")
|
||||
}
|
||||
return
|
||||
}
|
||||
try {
|
||||
val intent = Intent()
|
||||
intent.action = Intent.ACTION_SEND
|
||||
intent.type = "text/plain"
|
||||
intent.putExtra(Intent.EXTRA_TEXT, text)
|
||||
intent.component = cn
|
||||
context.startActivity(intent)
|
||||
} catch (ex: ActivityNotFoundException) {
|
||||
log.trace(ex)
|
||||
context.showToast(true, R.string.custom_share_app_not_found)
|
||||
} catch (ex: Throwable) {
|
||||
log.trace(ex)
|
||||
context.showToast(ex, "invoke() failed.")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun invoke(
|
||||
context: Context,
|
||||
access_info: SavedAccount,
|
||||
status: TootStatus?,
|
||||
target: CustomShareTarget
|
||||
) {
|
||||
status ?: return
|
||||
try {
|
||||
// convert "pkgName/className" string to ComponentName object.
|
||||
val cn = getCustomShareComponentName(App1.pref, target)
|
||||
if(cn == null) {
|
||||
context.showToast(true, R.string.custom_share_app_not_found)
|
||||
return
|
||||
}
|
||||
|
||||
val sv = TootTextEncoder.encodeStatusForTranslate(context, access_info, status)
|
||||
invoke(context, sv, target)
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
context.showToast(ex, "invoke() failed.")
|
||||
}
|
||||
}
|
||||
|
||||
private val cache = HashMap<CustomShareTarget, Pair<CharSequence?, Drawable?>>()
|
||||
|
||||
fun getCache(target : CustomShareTarget) = cache[target]
|
||||
|
||||
fun reloadCache(context : Context, pref : SharedPreferences) {
|
||||
CustomShareTarget.values().forEach { target ->
|
||||
val cn = getCustomShareComponentName(pref, target)
|
||||
val pair = getInfo(context, cn)
|
||||
cache[target] = pair
|
||||
}
|
||||
}
|
||||
status ?: return
|
||||
try {
|
||||
// convert "pkgName/className" string to ComponentName object.
|
||||
val cn = getCustomShareComponentName(App1.pref, target)
|
||||
if (cn == null) {
|
||||
context.showToast(true, R.string.custom_share_app_not_found)
|
||||
return
|
||||
}
|
||||
|
||||
val sv = TootTextEncoder.encodeStatusForTranslate(context, access_info, status)
|
||||
invoke(context, sv, target)
|
||||
} catch (ex: Throwable) {
|
||||
log.trace(ex)
|
||||
context.showToast(ex, "invoke() failed.")
|
||||
}
|
||||
}
|
||||
|
||||
private val cache = HashMap<CustomShareTarget, Pair<CharSequence?, Drawable?>>()
|
||||
|
||||
fun getCache(target: CustomShareTarget) = cache[target]
|
||||
|
||||
fun reloadCache(context: Context, pref: SharedPreferences) {
|
||||
CustomShareTarget.values().forEach { target ->
|
||||
val cn = getCustomShareComponentName(pref, target)
|
||||
val pair = getInfo(context, cn)
|
||||
cache[target] = pair
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convert "pkgName/className" string to ComponentName object.
|
||||
fun String.cn() : ComponentName? {
|
||||
try {
|
||||
val idx = indexOf('/')
|
||||
if(idx >= 1) return ComponentName(substring(0 until idx), substring(idx + 1))
|
||||
} catch(ex : Throwable) {
|
||||
CustomShare.log.e(ex, "incorrect component name $this")
|
||||
}
|
||||
return null
|
||||
fun String.cn(): ComponentName? {
|
||||
try {
|
||||
val idx = indexOf('/')
|
||||
if (idx >= 1) return ComponentName(substring(0 until idx), substring(idx + 1))
|
||||
} catch (ex: Throwable) {
|
||||
CustomShare.log.e(ex, "incorrect component name $this")
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun ComponentName.exists(context: Context): Boolean {
|
||||
return try {
|
||||
context.packageManager.resolveActivity(Intent().apply { component = this@exists }, 0)
|
||||
?.activityInfo?.exported ?: false
|
||||
} catch (_: Throwable) {
|
||||
false
|
||||
}
|
||||
}
|
|
@ -1065,5 +1065,6 @@
|
|||
<string name="username_not_need_atmark">ユーザ名に@や/ を含めることはできません</string>
|
||||
<string name="speech">読み上げ</string>
|
||||
<string name="reset_notification_tracking_status">既読状態をリセット</string>
|
||||
<string name="web_browser">Webブラウザー</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -1076,4 +1076,5 @@
|
|||
<string name="toot_search_notestock_of">notestock search \"%1$s\"</string>
|
||||
<string name="update_push_subscription_not_force" translatable="false">Update push subscription(not force)</string>
|
||||
<string name="reset_notification_tracking_status">Reset notification tracking status</string>
|
||||
<string name="web_browser">Web browser</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue