Links to open external applications

This commit is contained in:
J-Jamet
2020-10-28 18:20:53 +01:00
parent e0ab6137e7
commit 7b242c9733
4 changed files with 60 additions and 12 deletions

View File

@@ -16,6 +16,8 @@
android:name="android.permission.VIBRATE"/>
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"/>
<application
android:label="@string/app_name"

View File

@@ -22,8 +22,10 @@ package com.kunzisoft.keepass.utils
import android.content.ContentResolver
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.util.Log
import android.widget.Toast
import androidx.documentfile.provider.DocumentFile
import com.kunzisoft.keepass.R
@@ -151,6 +153,24 @@ object UriUtil {
gotoUrl(context, context.getString(resId))
}
fun isExternalAppInstalled(context: Context, packageName: String): Boolean {
try {
context.applicationContext.packageManager.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES)
return true
} catch (e: Exception) {
Log.e(javaClass.simpleName, "App not accessible", e)
}
return false
}
fun openExternalApp(context: Context, packageName: String) {
try {
context.startActivity(context.applicationContext.packageManager.getLaunchIntentForPackage(packageName))
} catch (e: Exception) {
Log.e(javaClass.simpleName, "App cannot be open", e)
}
}
fun getBinaryDir(context: Context): File {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
context.applicationContext.noBackupFilesDir

View File

@@ -30,7 +30,8 @@ import android.widget.TextView
import androidx.annotation.StringRes
import androidx.core.text.util.LinkifyCompat
import com.kunzisoft.keepass.R
import java.util.regex.Pattern
import com.kunzisoft.keepass.model.EntryInfo.Companion.APPLICATION_ID_FIELD_NAME
import com.kunzisoft.keepass.utils.UriUtil
class EntryField @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null,
@@ -101,9 +102,7 @@ class EntryField @JvmOverloads constructor(context: Context,
setTextIsSelectable(true)
}
applyHiddenStyle(isProtected && !showButtonView.isSelected)
if (valueView.autoLinkMask == LINKIFY_MASKS) {
linkify()
}
if (!isProtected) linkify()
}
}
@@ -113,13 +112,23 @@ class EntryField @JvmOverloads constructor(context: Context,
}
private fun linkify() {
valueView.autoLinkMask = LINKIFY_MASKS
LinkifyCompat.addLinks(valueView, LINKIFY_MASKS)
when {
labelView.text.contains(APPLICATION_ID_FIELD_NAME) -> {
val packageName = valueView.text.toString()
if (UriUtil.isExternalAppInstalled(context, packageName)) {
valueView.customLink {
UriUtil.openExternalApp(context, packageName)
}
}
}
else -> {
LinkifyCompat.addLinks(valueView, Linkify.WEB_URLS or Linkify.EMAIL_ADDRESSES)
}
}
}
fun setLinkAll() {
valueView.autoLinkMask = LINKIFY_ALL
LinkifyCompat.addLinks(valueView, LINKIFY_ALL)
LinkifyCompat.addLinks(valueView, Linkify.ALL)
}
fun activateCopyButton(enable: Boolean) {
@@ -131,8 +140,4 @@ class EntryField @JvmOverloads constructor(context: Context,
copyButtonView.setOnClickListener(onClickActionListener)
copyButtonView.visibility = if (onClickActionListener == null) GONE else VISIBLE
}
companion object {
private const val LINKIFY_MASKS = Linkify.WEB_URLS or Linkify.EMAIL_ADDRESSES
private const val LINKIFY_ALL = Linkify.ALL
}
}

View File

@@ -25,7 +25,13 @@ import android.animation.ValueAnimator
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Typeface
import android.text.Selection
import android.text.Spannable
import android.text.SpannableString
import android.text.Spanned
import android.text.method.LinkMovementMethod
import android.text.method.PasswordTransformationMethod
import android.text.style.ClickableSpan
import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator
import android.widget.TextView
@@ -68,6 +74,21 @@ fun TextView.strikeOut(strikeOut: Boolean) {
paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
}
fun TextView.customLink(listener: (View) -> Unit) {
val spannableString = SpannableString(this.text)
val clickableSpan = object : ClickableSpan() {
override fun onClick(view: View) {
Selection.setSelection((view as TextView).text as Spannable, 0)
view.invalidate()
listener.invoke(view)
}
}
spannableString.setSpan(clickableSpan, 0, text.length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
this.movementMethod = LinkMovementMethod.getInstance() // without LinkMovementMethod, link can not click
this.setText(spannableString, TextView.BufferType.SPANNABLE)
}
fun Snackbar.asError(): Snackbar {
this.view.apply {
setBackgroundColor(Color.RED)