This commit is contained in:
Mariotaku Lee 2017-02-14 15:52:29 +08:00
parent 5a44823705
commit d4bbd0a22a
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
5 changed files with 53 additions and 70 deletions

View File

@ -51,6 +51,8 @@ open class BaseArrayAdapter<T>(
lateinit var multiSelectManager: MultiSelectManager
@Inject
lateinit var preferences: SharedPreferencesWrapper
@Inject
lateinit var permissionsManager: PermissionsManager
final override val profileImageStyle: Int
final override val textSize: Float

View File

@ -28,13 +28,7 @@ import org.mariotaku.twidere.loader.ExtensionsListLoader.ExtensionInfo
import org.mariotaku.twidere.util.PermissionsManager
import org.mariotaku.twidere.view.holder.TwoLineWithIconViewHolder
class ExtensionsAdapter(context: Context) : ArrayAdapter<ExtensionInfo>(context, R.layout.list_item_two_line) {
private val mPermissionsManager: PermissionsManager
init {
mPermissionsManager = PermissionsManager(context)
}
class ExtensionsAdapter(context: Context) : BaseArrayAdapter<ExtensionInfo>(context, R.layout.list_item_two_line) {
override fun getItemId(position: Int): Long {
return getItem(position).hashCode().toLong()
@ -57,7 +51,7 @@ class ExtensionsAdapter(context: Context) : ArrayAdapter<ExtensionInfo>(context,
val permissionValid = PermissionsManager.isPermissionValid(*permissions)
holder.checkbox.visibility = if (permissionValid) View.VISIBLE else View.GONE
if (permissionValid) {
holder.checkbox.isChecked = mPermissionsManager.checkPermission(info.pname, *permissions)
holder.checkbox.isChecked = permissionsManager.checkPermission(info.packageName, *permissions)
}
holder.text1.text = info.label
holder.text2.visibility = if (TextUtils.isEmpty(info.description)) View.GONE else View.VISIBLE

View File

@ -59,6 +59,8 @@ open class BaseFragment : Fragment(), IBaseFragment<BaseFragment> {
lateinit var validator: TwidereValidator
@Inject
lateinit var extraFeaturesService: ExtraFeaturesService
@Inject
lateinit var permissionsManager: PermissionsManager
private val actionHelper = IBaseFragment.ActionHelper(this)

View File

@ -21,7 +21,6 @@ package org.mariotaku.twidere.fragment
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.support.v4.app.LoaderManager.LoaderCallbacks
@ -43,18 +42,12 @@ import org.mariotaku.twidere.adapter.ExtensionsAdapter
import org.mariotaku.twidere.constant.IntentConstants
import org.mariotaku.twidere.loader.ExtensionsListLoader
import org.mariotaku.twidere.loader.ExtensionsListLoader.ExtensionInfo
import org.mariotaku.twidere.util.PermissionsManager
class ExtensionsListFragment : AbsContentListViewFragment<ExtensionsAdapter>(),
LoaderCallbacks<List<ExtensionInfo>>, AdapterView.OnItemClickListener {
private var packageManager: PackageManager? = null
private var permissionsManager: PermissionsManager? = null
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
packageManager = activity.packageManager
permissionsManager = PermissionsManager(activity)
listView.onItemClickListener = this
@ -97,10 +90,10 @@ class ExtensionsListFragment : AbsContentListViewFragment<ExtensionsAdapter>(),
inflater.inflate(R.menu.action_extension, menu)
val adapterMenuInfo = menuInfo as AdapterContextMenuInfo
val extensionInfo = adapter.getItem(adapterMenuInfo.position)
if (extensionInfo.pname != null && extensionInfo.settings != null) {
if (extensionInfo.settings != null) {
val intent = Intent(IntentConstants.INTENT_ACTION_EXTENSION_SETTINGS)
intent.setClassName(extensionInfo.pname, extensionInfo.settings)
menu.setItemAvailability(R.id.settings, packageManager!!.queryIntentActivities(intent, 0).size == 1)
intent.setClassName(extensionInfo.packageName, extensionInfo.settings)
menu.setItemAvailability(R.id.settings, context.packageManager.queryIntentActivities(intent, 0).size == 1)
} else {
menu.setItemAvailability(R.id.settings, false)
}
@ -118,7 +111,7 @@ class ExtensionsListFragment : AbsContentListViewFragment<ExtensionsAdapter>(),
uninstallExtension(extensionInfo)
}
R.id.revoke -> {
permissionsManager!!.revoke(extensionInfo.pname)
permissionsManager.revoke(extensionInfo.packageName)
adapter.notifyDataSetChanged()
}
else -> {
@ -130,9 +123,9 @@ class ExtensionsListFragment : AbsContentListViewFragment<ExtensionsAdapter>(),
private fun openSettings(info: ExtensionInfo): Boolean {
val intent = Intent(IntentConstants.INTENT_ACTION_EXTENSION_SETTINGS)
intent.`package` = info.pname
intent.`package` = info.packageName
if (info.settings != null) {
intent.setClassName(info.pname, info.settings)
intent.setClassName(info.packageName, info.settings)
} else {
val pm = activity.packageManager
val activities = pm.queryIntentActivities(intent, 0)
@ -140,7 +133,7 @@ class ExtensionsListFragment : AbsContentListViewFragment<ExtensionsAdapter>(),
return false
}
val resolveInfo = activities[0]
intent.setClassName(info.pname, resolveInfo.activityInfo.name)
intent.setClassName(info.packageName, resolveInfo.activityInfo.name)
}
try {
startActivity(intent)
@ -154,7 +147,7 @@ class ExtensionsListFragment : AbsContentListViewFragment<ExtensionsAdapter>(),
private fun uninstallExtension(info: ExtensionInfo?): Boolean {
if (info == null) return false
val packageUri = Uri.parse("package:${info.pname}")
val packageUri = Uri.parse("package:${info.packageName}")
val uninstallIntent = Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri)
try {
startActivity(uninstallIntent)

View File

@ -29,10 +29,9 @@ import android.content.pm.PackageManager
import android.content.res.Configuration
import android.content.res.Resources
import android.graphics.drawable.Drawable
import android.os.Build
import android.support.v4.content.FixedAsyncTaskLoader
import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.util.ParseUtils
import java.text.Collator
import java.util.*
class ExtensionsListLoader(
@ -52,6 +51,7 @@ class ExtensionsListLoader(
extensions.add(ExtensionInfo(info, packageManager))
}
}
extensions.sort(ExtensionInfoComparator(Collator.getInstance()))
return extensions
}
@ -100,39 +100,24 @@ class ExtensionsListLoader(
cancelLoad()
}
class ExtensionInfo(info: ApplicationInfo, pm: PackageManager) : Comparable<ExtensionInfo> {
val permissions: Array<String>?
val label: String
val description: String
val pname: String
val settings: String
val icon: Drawable
data class ExtensionInfo(
val packageName: String,
val label: CharSequence,
val description: CharSequence?,
val icon: Drawable,
val permissions: Array<String>?,
val settings: String?
) {
init {
val meta = info.metaData
val permissionString = meta.getString(METADATA_KEY_EXTENSION_PERMISSIONS)
permissions = permissionString?.split('|')?.filterNot(String::isEmpty)?.toTypedArray()
settings = meta.getString(METADATA_KEY_EXTENSION_SETTINGS)
icon = info.loadIcon(pm)
pname = info.packageName
label = ParseUtils.parseString(info.loadLabel(pm), pname)
description = ParseUtils.parseString(info.loadDescription(pm))
}
constructor(info: ApplicationInfo, pm: PackageManager) : this(
info.packageName,
info.loadLabel(pm) ?: info.packageName,
info.loadDescription(pm),
info.loadIcon(pm),
info.metaData?.getString(METADATA_KEY_EXTENSION_PERMISSIONS)?.split('|')?.filterNot(String::isEmpty)?.toTypedArray(),
info.metaData?.getString(METADATA_KEY_EXTENSION_SETTINGS)
)
override fun compareTo(another: ExtensionInfo): Int {
return label.compareTo(another.label, ignoreCase = true)
}
override fun toString(): String {
return "ExtensionInfo{" +
"permissions=" + Arrays.toString(permissions) +
", label='" + label + '\'' +
", description='" + description + '\'' +
", pname='" + pname + '\'' +
", settings='" + settings + '\'' +
", icon=" + icon +
'}'
}
}
/**
@ -141,14 +126,14 @@ class ExtensionsListLoader(
*/
class InterestingConfigChanges {
internal val mLastConfiguration = Configuration()
internal var mLastDensity: Int = 0
internal val lastConfiguration = Configuration()
internal var lastDensity: Int = 0
internal fun applyNewConfig(res: Resources): Boolean {
val configChanges = mLastConfiguration.updateFrom(res.configuration)
val densityChanged = mLastDensity != res.displayMetrics.densityDpi
val configChanges = lastConfiguration.updateFrom(res.configuration)
val densityChanged = lastDensity != res.displayMetrics.densityDpi
if (densityChanged || configChanges and (ActivityInfo.CONFIG_LOCALE or ActivityInfo.CONFIG_UI_MODE or ActivityInfo.CONFIG_SCREEN_LAYOUT) != 0) {
mLastDensity = res.displayMetrics.densityDpi
lastDensity = res.displayMetrics.densityDpi
return true
}
return false
@ -159,27 +144,34 @@ class ExtensionsListLoader(
* Helper class to look for interesting changes to the installed apps so
* that the loader can be updated.
*/
class PackageIntentReceiver(internal val mLoader: ExtensionsListLoader) : BroadcastReceiver() {
class PackageIntentReceiver(internal val loader: ExtensionsListLoader) : BroadcastReceiver() {
init {
val filter = IntentFilter(Intent.ACTION_PACKAGE_ADDED)
filter.addAction(Intent.ACTION_PACKAGE_REMOVED)
filter.addAction(Intent.ACTION_PACKAGE_CHANGED)
filter.addDataScheme("package")
mLoader.context.registerReceiver(this, filter)
loader.context.registerReceiver(this, filter)
// Register for events related to sdcard installation.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
val sdFilter = IntentFilter()
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE)
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)
mLoader.context.registerReceiver(this, sdFilter)
}
val sdFilter = IntentFilter()
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE)
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)
loader.context.registerReceiver(this, sdFilter)
}
override fun onReceive(context: Context, intent: Intent) {
// Tell the loader about the change.
mLoader.onContentChanged()
loader.onContentChanged()
}
}
class ExtensionInfoComparator(val collator: Collator) : Comparator<ExtensionInfo> {
override fun compare(o1: ExtensionInfo, o2: ExtensionInfo): Int {
val label1 = o1.label.toString()
val label2 = o2.label.toString()
return collator.compare(label1, label2)
}
}
}