From 95ddccb514ae071f25ad46f2205613f77b61cbdf Mon Sep 17 00:00:00 2001 From: Mysochenko Yuriy Date: Thu, 12 Aug 2021 09:10:28 +0300 Subject: [PATCH] refactoring --- app/src/main/AndroidManifest.xml | 2 - .../com/sdex/activityrunner/MainActivity.kt | 71 ++--------- .../com/sdex/activityrunner/MainViewModel.kt | 28 ----- .../app/ActivitiesListActivity.kt | 37 ++---- .../app/ActivitiesListAdapter.kt | 58 ++++----- .../app/ActivitiesListViewModel.kt | 48 +++----- .../activityrunner/app/ActivityLauncher.kt | 10 +- .../sdex/activityrunner/app/ActivityModel.kt | 10 +- .../app/ApplicationsListAdapter.kt | 60 +++++----- .../app/ApplicationsListViewModel.kt | 20 ---- .../app/EnableNotExportedActivitiesDialog.kt | 4 +- .../sdex/activityrunner/app/MainViewModel.kt | 21 ++++ ...MenuDialog.kt => ActivityOptionsDialog.kt} | 23 +--- ...uDialog.kt => ApplicationOptionsDialog.kt} | 6 +- .../legacy/OreoPackageManagerBugActivity.kt | 35 ------ .../db/cache/query/GetApplicationsQuery.kt | 4 +- .../intent/dialog/ExportIntentAsUriDialog.kt | 4 +- .../intent/dialog/ExtraInputDialog.kt | 6 +- .../intent/dialog/MultiSelectionDialog.kt | 6 +- .../intent/dialog/SingleSelectionDialog.kt | 6 +- .../intent/dialog/ValueInputDialog.kt | 6 +- .../preferences/SettingsFragment.kt | 12 +- .../shortcut/AddShortcutDialogActivity.kt | 6 +- .../ui/SnackbarContainerActivity.kt | 11 -- .../res/drawable/img_oreo_instant_bug.png | Bin 33494 -> 0 bytes .../activity_oreo_package_manager_bug.xml | 111 ------------------ app/src/main/res/values/strings.xml | 2 +- 27 files changed, 162 insertions(+), 445 deletions(-) delete mode 100644 app/src/main/java/com/sdex/activityrunner/MainViewModel.kt delete mode 100644 app/src/main/java/com/sdex/activityrunner/app/ApplicationsListViewModel.kt create mode 100644 app/src/main/java/com/sdex/activityrunner/app/MainViewModel.kt rename app/src/main/java/com/sdex/activityrunner/app/dialog/{ActivityMenuDialog.kt => ActivityOptionsDialog.kt} (70%) rename app/src/main/java/com/sdex/activityrunner/app/dialog/{ApplicationMenuDialog.kt => ApplicationOptionsDialog.kt} (92%) delete mode 100644 app/src/main/java/com/sdex/activityrunner/app/legacy/OreoPackageManagerBugActivity.kt delete mode 100644 app/src/main/java/com/sdex/activityrunner/ui/SnackbarContainerActivity.kt delete mode 100644 app/src/main/res/drawable/img_oreo_instant_bug.png delete mode 100644 app/src/main/res/layout/activity_oreo_package_manager_bug.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1d62bc63..7fc12f8f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -59,8 +59,6 @@ - - diff --git a/app/src/main/java/com/sdex/activityrunner/MainActivity.kt b/app/src/main/java/com/sdex/activityrunner/MainActivity.kt index 45f83401..411703a2 100644 --- a/app/src/main/java/com/sdex/activityrunner/MainActivity.kt +++ b/app/src/main/java/com/sdex/activityrunner/MainActivity.kt @@ -1,20 +1,16 @@ package com.sdex.activityrunner +import android.annotation.SuppressLint import android.content.Intent -import android.os.Build.VERSION -import android.os.Build.VERSION_CODES import android.os.Bundle -import android.text.TextUtils import android.view.Menu import android.view.MenuItem import androidx.activity.viewModels import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView.OnQueryTextListener -import androidx.lifecycle.ViewModelProvider import com.sdex.activityrunner.app.ApplicationsListAdapter -import com.sdex.activityrunner.app.ApplicationsListViewModel -import com.sdex.activityrunner.app.legacy.OreoPackageManagerBugActivity +import com.sdex.activityrunner.app.MainViewModel import com.sdex.activityrunner.extensions.addDivider import com.sdex.activityrunner.intent.IntentBuilderActivity import com.sdex.activityrunner.preferences.AppPreferences @@ -26,17 +22,12 @@ import kotlinx.android.synthetic.main.activity_main.* class MainActivity : BaseActivity() { - private val viewModel by viewModels() + private val viewModel by viewModels() private val appPreferences by lazy { AppPreferences(this) } private val adapter by lazy { ApplicationsListAdapter(this) } - private var isShowSystemAppIndicator: Boolean = false - private var searchText: String? = null - - override fun getLayout(): Int { - return R.layout.activity_main - } + override fun getLayout() = R.layout.activity_main public override fun onCreate(savedInstanceState: Bundle?) { AppCompatDelegate.setDefaultNightMode(appPreferences.theme) @@ -44,11 +35,7 @@ class MainActivity : BaseActivity() { ApplicationsListJob.enqueueWork(this, Intent()) - isShowSystemAppIndicator = appPreferences.isShowSystemAppIndicator - - searchText = savedInstanceState?.getString(STATE_SEARCH_TEXT) - - viewModel.getItems(searchText).observe(this) { + viewModel.items.observe(this) { adapter.submitList(it) progress.hide() } @@ -57,44 +44,14 @@ class MainActivity : BaseActivity() { list.addDivider(this) list.adapter = adapter - - checkOreoBug() } + @SuppressLint("NotifyDataSetChanged") override fun onStart() { super.onStart() - if (appPreferences.isShowSystemAppIndicator != isShowSystemAppIndicator) { - isShowSystemAppIndicator = appPreferences.isShowSystemAppIndicator - viewModel.getItems(searchText).observe(this) { - adapter.submitList(it) - } - } - } - - public override fun onSaveInstanceState(outState: Bundle) { - super.onSaveInstanceState(outState) - outState.putString(STATE_SEARCH_TEXT, searchText) - } - - private fun filter(text: String) { - this.searchText = text - viewModel.getItems(text).observe(this) { - adapter.submitList(it) - } - } - - // https://issuetracker.google.com/issues/73289329 - private fun checkOreoBug() { - if (VERSION.SDK_INT == VERSION_CODES.O) { - if (!appPreferences.isOreoBugWarningShown) { - val viewModel = ViewModelProvider(this).get(MainViewModel::class.java) - viewModel.packages.observe(this) { - if (it!!.isEmpty()) { - overridePendingTransition(0, 0) - startActivity(Intent(this, OreoPackageManagerBugActivity::class.java)) - } - } - } + if (appPreferences.isShowSystemAppIndicator != adapter.isShowSystemAppIndicator) { + adapter.isShowSystemAppIndicator = appPreferences.isShowSystemAppIndicator + adapter.notifyDataSetChanged() } } @@ -105,8 +62,9 @@ class MainActivity : BaseActivity() { val hint = getString(R.string.action_search_hint) searchView.queryHint = hint - if (!TextUtils.isEmpty(searchText)) { - searchView.post { searchView.setQuery(searchText, false) } + val searchQuery = viewModel.searchQuery.value + if (!searchQuery.isNullOrEmpty()) { + searchView.post { searchView.setQuery(searchQuery, false) } searchItem.expandActionView() UIUtils.setMenuItemsVisibility(menu, searchItem, false) } @@ -117,7 +75,7 @@ class MainActivity : BaseActivity() { } override fun onQueryTextChange(newText: String): Boolean { - filter(newText) + viewModel.searchQuery.value = newText return false } }) @@ -128,7 +86,6 @@ class MainActivity : BaseActivity() { } override fun onMenuItemActionCollapse(item: MenuItem): Boolean { - searchText = null UIUtils.setMenuItemsVisibility(menu, true) invalidateOptionsMenu() return true @@ -157,8 +114,6 @@ class MainActivity : BaseActivity() { companion object { - private const val STATE_SEARCH_TEXT = "state_search_text" - init { AppCompatDelegate.setCompatVectorFromResourcesEnabled(true) } diff --git a/app/src/main/java/com/sdex/activityrunner/MainViewModel.kt b/app/src/main/java/com/sdex/activityrunner/MainViewModel.kt deleted file mode 100644 index 97115063..00000000 --- a/app/src/main/java/com/sdex/activityrunner/MainViewModel.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.sdex.activityrunner - -import android.app.Application -import android.content.pm.PackageInfo -import android.content.pm.PackageManager -import androidx.lifecycle.AndroidViewModel -import androidx.lifecycle.MutableLiveData -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch - -class MainViewModel(application: Application) : AndroidViewModel(application) { - - private val packageManager: PackageManager = application.packageManager - private var liveData: MutableLiveData> = MutableLiveData() - - val packages: MutableLiveData> - get() { - GlobalScope.launch { - val list = loadPackages() - liveData.postValue(list) - } - return liveData - } - - private fun loadPackages(): List { - return packageManager.getInstalledPackages(0) - } -} diff --git a/app/src/main/java/com/sdex/activityrunner/app/ActivitiesListActivity.kt b/app/src/main/java/com/sdex/activityrunner/app/ActivitiesListActivity.kt index a1e27ba2..5ac71b19 100644 --- a/app/src/main/java/com/sdex/activityrunner/app/ActivitiesListActivity.kt +++ b/app/src/main/java/com/sdex/activityrunner/app/ActivitiesListActivity.kt @@ -1,40 +1,35 @@ package com.sdex.activityrunner.app -import android.app.Activity import android.content.Context import android.content.Intent import android.os.Bundle import android.text.TextUtils import android.view.Menu import android.view.MenuItem -import android.view.View import android.view.View.GONE import android.view.View.VISIBLE import androidx.activity.viewModels import androidx.appcompat.widget.SearchView -import androidx.lifecycle.Observer import com.sdex.activityrunner.R import com.sdex.activityrunner.db.cache.ApplicationModel import com.sdex.activityrunner.extensions.addDivider import com.sdex.activityrunner.extensions.enableBackButton import com.sdex.activityrunner.preferences.AppPreferences -import com.sdex.activityrunner.ui.SnackbarContainerActivity import com.sdex.commons.BaseActivity import com.sdex.commons.util.UIUtils import kotlinx.android.synthetic.main.activity_activities_list.* -class ActivitiesListActivity : BaseActivity(), SnackbarContainerActivity { +class ActivitiesListActivity : BaseActivity() { - private val appPreferences: AppPreferences by lazy { AppPreferences(this) } - private val viewModel: ActivitiesListViewModel by viewModels() + private val viewModel by viewModels() + private val appPreferences by lazy { AppPreferences(this) } + + private lateinit var appPackageName: String private var isShowNotExported: Boolean = false - private var appPackageName: String? = null private var searchText: String? = null - override fun getLayout(): Int { - return R.layout.activity_activities_list - } + override fun getLayout() = R.layout.activity_activities_list override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -52,22 +47,22 @@ class ActivitiesListActivity : BaseActivity(), SnackbarContainerActivity { searchText = savedInstanceState?.getString(STATE_SEARCH_TEXT) - viewModel.getItems(appPackageName!!).observe(this, Observer { + viewModel.getItems(appPackageName).observe(this) { adapter.submitList(it) - val size = it!!.size + val size = it.size setSubtitle(resources.getQuantityString(R.plurals.activities_count, size, size)) if (size == 0 && searchText == null) { empty.visibility = VISIBLE } else { empty.visibility = GONE } - }) + } isShowNotExported = appPreferences.showNotExported turnOnAdvanced.setOnClickListener { appPreferences.showNotExported = true - viewModel.reloadItems(appPackageName!!) + viewModel.reloadItems(appPackageName) } if (!appPreferences.showNotExported && !appPreferences.isNotExportedDialogShown) { @@ -80,7 +75,7 @@ class ActivitiesListActivity : BaseActivity(), SnackbarContainerActivity { override fun onStart() { super.onStart() if (appPreferences.showNotExported != isShowNotExported) { - viewModel.reloadItems(appPackageName!!) + viewModel.reloadItems(appPackageName) } } @@ -128,17 +123,9 @@ class ActivitiesListActivity : BaseActivity(), SnackbarContainerActivity { return super.onCreateOptionsMenu(menu) } - override fun getView(): View { - return container - } - - override fun getActivity(): Activity { - return this - } - private fun filter(text: String) { this.searchText = text - viewModel.filterItems(appPackageName!!, searchText) + viewModel.filterItems(appPackageName, searchText) } companion object { diff --git a/app/src/main/java/com/sdex/activityrunner/app/ActivitiesListAdapter.kt b/app/src/main/java/com/sdex/activityrunner/app/ActivitiesListAdapter.kt index 2fd966d8..63e7c49d 100644 --- a/app/src/main/java/com/sdex/activityrunner/app/ActivitiesListAdapter.kt +++ b/app/src/main/java/com/sdex/activityrunner/app/ActivitiesListAdapter.kt @@ -13,22 +13,17 @@ import com.bumptech.glide.RequestManager import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions import com.bumptech.glide.request.RequestOptions import com.sdex.activityrunner.R -import com.sdex.activityrunner.app.dialog.ActivityMenuDialog +import com.sdex.activityrunner.app.dialog.ActivityOptionsDialog import com.sdex.activityrunner.glide.GlideApp -import com.sdex.activityrunner.ui.SnackbarContainerActivity +import com.sdex.commons.BaseActivity import kotlinx.android.synthetic.main.item_activity.view.* -class ActivitiesListAdapter(snackbarContainerActivity: SnackbarContainerActivity) : - ListAdapter(DIFF_CALLBACK) { +class ActivitiesListAdapter( + activity: BaseActivity +) : ListAdapter(DIFF_CALLBACK) { - private val glide: RequestManager - private val launcher: ActivityLauncher - - init { - val activity = snackbarContainerActivity.getActivity() - this.glide = GlideApp.with(activity) - this.launcher = ActivityLauncher(snackbarContainerActivity) - } + private val glide = GlideApp.with(activity) + private val launcher = ActivityLauncher(activity) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val inflater = LayoutInflater.from(parent.context) @@ -37,12 +32,12 @@ class ActivitiesListAdapter(snackbarContainerActivity: SnackbarContainerActivity } override fun onBindViewHolder(holder: ViewHolder, position: Int) { - holder.bindTo(getItem(position), glide, launcher) + holder.bind(getItem(position), glide, launcher) } class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - fun bindTo( + fun bind( item: ActivityModel, glide: RequestManager, launcher: ActivityLauncher @@ -79,29 +74,28 @@ class ActivitiesListAdapter(snackbarContainerActivity: SnackbarContainerActivity private fun showActivityMenu(context: Context, model: ActivityModel) { val activity = context as FragmentActivity - val dialog = ActivityMenuDialog.newInstance(model) - dialog.show(activity.supportFragmentManager, ActivityMenuDialog.TAG) + val dialog = ActivityOptionsDialog.newInstance(model) + dialog.show(activity.supportFragmentManager, ActivityOptionsDialog.TAG) } } companion object { - val DIFF_CALLBACK: DiffUtil.ItemCallback = - object : DiffUtil.ItemCallback() { - - override fun areItemsTheSame( - oldItem: ActivityModel, - newItem: ActivityModel - ): Boolean { - return oldItem == newItem - } - - override fun areContentsTheSame( - oldItem: ActivityModel, - newItem: ActivityModel - ): Boolean { - return oldItem == newItem - } + val DIFF_CALLBACK = object : DiffUtil.ItemCallback() { + + override fun areItemsTheSame( + oldItem: ActivityModel, + newItem: ActivityModel + ): Boolean { + return oldItem == newItem } + + override fun areContentsTheSame( + oldItem: ActivityModel, + newItem: ActivityModel + ): Boolean { + return oldItem == newItem + } + } } } diff --git a/app/src/main/java/com/sdex/activityrunner/app/ActivitiesListViewModel.kt b/app/src/main/java/com/sdex/activityrunner/app/ActivitiesListViewModel.kt index 8561551c..dfb26704 100644 --- a/app/src/main/java/com/sdex/activityrunner/app/ActivitiesListViewModel.kt +++ b/app/src/main/java/com/sdex/activityrunner/app/ActivitiesListViewModel.kt @@ -1,39 +1,35 @@ package com.sdex.activityrunner.app import android.app.Application -import android.content.ComponentName import android.content.pm.ActivityInfo -import android.content.pm.PackageManager import androidx.annotation.WorkerThread import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.viewModelScope import com.sdex.activityrunner.preferences.AppPreferences import com.sdex.commons.pm.getActivities import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext class ActivitiesListViewModel(application: Application) : AndroidViewModel(application) { - private val packageManager: PackageManager = application.packageManager - private val appPreferences: AppPreferences by lazy { AppPreferences(application) } - private val liveData: MutableLiveData> = MutableLiveData() + private val packageManager = application.packageManager + private val appPreferences by lazy { AppPreferences(application) } + + private val liveData = MutableLiveData>() private var list: List? = null fun getItems(packageName: String): LiveData> { - GlobalScope.launch { + viewModelScope.launch(Dispatchers.IO) { list = getActivitiesList(packageName) - withContext(Dispatchers.Main) { - liveData.value = list - } + liveData.postValue(list) } return liveData } fun reloadItems(packageName: String) { - GlobalScope.launch { + viewModelScope.launch(Dispatchers.IO) { list = getActivitiesList(packageName) liveData.postValue(list) } @@ -42,7 +38,7 @@ class ActivitiesListViewModel(application: Application) : AndroidViewModel(appli fun filterItems(packageName: String, searchText: String?) { if (list != null) { if (searchText != null) { - GlobalScope.launch { + viewModelScope.launch(Dispatchers.IO) { val filteredList = list!!.filter { it.name.contains(searchText, true) || it.className.contains( searchText, @@ -60,13 +56,13 @@ class ActivitiesListViewModel(application: Application) : AndroidViewModel(appli } @WorkerThread - private fun getActivitiesList(packageName: String): ArrayList { + private fun getActivitiesList(packageName: String): List { val list = ArrayList() val showNotExported = appPreferences.showNotExported try { val info = getActivities(packageManager, packageName) for (activityInfo in info.activities) { - val activityModel = getActivityModel(packageManager, activityInfo) + val activityModel = getActivityModel(activityInfo) if (activityModel.exported) { list.add(activityModel) } else if (showNotExported) { @@ -76,27 +72,13 @@ class ActivitiesListViewModel(application: Application) : AndroidViewModel(appli } catch (e: Exception) { e.printStackTrace() } - list.sortBy { it.name } - return list + return list.sortedBy { it.name } } - private fun getActivityModel(pm: PackageManager, activityInfo: ActivityInfo): ActivityModel { - var activityName = try { - activityInfo.loadLabel(pm).toString() - } catch (e: Exception) { - val componentName = ComponentName(activityInfo.packageName, activityInfo.name) - componentName.shortClassName - } - if (activityName.isNullOrBlank()) { - val applicationInfo = activityInfo.applicationInfo - activityName = if (applicationInfo != null) { - pm.getApplicationLabel(applicationInfo).toString() - } else { - activityInfo.packageName - } - } + private fun getActivityModel(activityInfo: ActivityInfo): ActivityModel { return ActivityModel( - activityName, activityInfo.packageName, activityInfo.name, + activityInfo.name.split(".").last(), + activityInfo.packageName, activityInfo.name, activityInfo.exported && activityInfo.isEnabled ) } diff --git a/app/src/main/java/com/sdex/activityrunner/app/ActivityLauncher.kt b/app/src/main/java/com/sdex/activityrunner/app/ActivityLauncher.kt index 27e4b58e..51eed910 100644 --- a/app/src/main/java/com/sdex/activityrunner/app/ActivityLauncher.kt +++ b/app/src/main/java/com/sdex/activityrunner/app/ActivityLauncher.kt @@ -6,16 +6,13 @@ import com.sdex.activityrunner.R import com.sdex.activityrunner.intent.IntentBuilderActivity import com.sdex.activityrunner.preferences.AppPreferences import com.sdex.activityrunner.preferences.SettingsActivity -import com.sdex.activityrunner.ui.SnackbarContainerActivity import com.sdex.activityrunner.util.IntentUtils import com.sdex.activityrunner.util.RunActivityTask class ActivityLauncher( - private val snackbarContainerActivity: SnackbarContainerActivity + private val activity: Activity ) { - private val activity: Activity = snackbarContainerActivity.getActivity() - fun launchActivity(model: ActivityModel) { if (model.exported) { IntentUtils.launchActivity(activity, model.componentName, model.name) @@ -39,8 +36,9 @@ class ActivityLauncher( runActivityTask.execute() } else { Snackbar.make( - snackbarContainerActivity.getView(), - R.string.settings_error_root_not_active, Snackbar.LENGTH_LONG + activity.findViewById(android.R.id.content), + R.string.settings_error_root_not_active, + Snackbar.LENGTH_LONG ).setAction( R.string.action_settings ) { diff --git a/app/src/main/java/com/sdex/activityrunner/app/ActivityModel.kt b/app/src/main/java/com/sdex/activityrunner/app/ActivityModel.kt index 78f9815a..507b48f2 100644 --- a/app/src/main/java/com/sdex/activityrunner/app/ActivityModel.kt +++ b/app/src/main/java/com/sdex/activityrunner/app/ActivityModel.kt @@ -3,11 +3,11 @@ package com.sdex.activityrunner.app import android.content.ComponentName import java.io.Serializable -class ActivityModel constructor( - var name: String, - var packageName: String, - var className: String, - var exported: Boolean +data class ActivityModel( + val name: String, + val packageName: String, + val className: String, + val exported: Boolean ) : Serializable { val componentName: ComponentName diff --git a/app/src/main/java/com/sdex/activityrunner/app/ApplicationsListAdapter.kt b/app/src/main/java/com/sdex/activityrunner/app/ApplicationsListAdapter.kt index 841a2704..3732ca7f 100644 --- a/app/src/main/java/com/sdex/activityrunner/app/ApplicationsListAdapter.kt +++ b/app/src/main/java/com/sdex/activityrunner/app/ApplicationsListAdapter.kt @@ -14,24 +14,22 @@ import com.bumptech.glide.RequestManager import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions import com.bumptech.glide.request.RequestOptions import com.sdex.activityrunner.R -import com.sdex.activityrunner.app.dialog.ApplicationMenuDialog +import com.sdex.activityrunner.app.dialog.ApplicationOptionsDialog import com.sdex.activityrunner.db.cache.ApplicationModel import com.sdex.activityrunner.glide.GlideApp import com.sdex.activityrunner.preferences.AppPreferences import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView import kotlinx.android.synthetic.main.item_application.view.* -class ApplicationsListAdapter(activity: FragmentActivity) : ListAdapter(DIFF_CALLBACK), +class ApplicationsListAdapter( + activity: FragmentActivity +) : ListAdapter(DIFF_CALLBACK), FastScrollRecyclerView.SectionedAdapter { - private val glide: RequestManager - private val appPreferences: AppPreferences + private val glide = GlideApp.with(activity) + private val appPreferences = AppPreferences(activity) - init { - this.glide = GlideApp.with(activity) - this.appPreferences = AppPreferences(activity) - } + var isShowSystemAppIndicator = appPreferences.isShowSystemAppIndicator override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AppViewHolder { val inflater = LayoutInflater.from(parent.context) @@ -40,19 +38,20 @@ class ApplicationsListAdapter(activity: FragmentActivity) : ListAdapter = - object : DiffUtil.ItemCallback() { + val DIFF_CALLBACK = object : DiffUtil.ItemCallback() { - override fun areItemsTheSame( - oldItem: ApplicationModel, - newItem: ApplicationModel - ): Boolean { - return oldItem.packageName == newItem.packageName - } + override fun areItemsTheSame( + oldItem: ApplicationModel, + newItem: ApplicationModel + ): Boolean { + return oldItem.packageName == newItem.packageName + } - override fun areContentsTheSame( - oldItem: ApplicationModel, - newItem: ApplicationModel - ): Boolean { - return oldItem == newItem - } + override fun areContentsTheSame( + oldItem: ApplicationModel, + newItem: ApplicationModel + ): Boolean { + return oldItem == newItem } + } } } diff --git a/app/src/main/java/com/sdex/activityrunner/app/ApplicationsListViewModel.kt b/app/src/main/java/com/sdex/activityrunner/app/ApplicationsListViewModel.kt deleted file mode 100644 index bbcd5845..00000000 --- a/app/src/main/java/com/sdex/activityrunner/app/ApplicationsListViewModel.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.sdex.activityrunner.app - -import android.app.Application -import androidx.lifecycle.AndroidViewModel -import androidx.lifecycle.LiveData -import androidx.sqlite.db.SimpleSQLiteQuery -import com.sdex.activityrunner.db.cache.ApplicationModel -import com.sdex.activityrunner.db.cache.CacheDatabase -import com.sdex.activityrunner.db.cache.query.GetApplicationsQuery - -class ApplicationsListViewModel(application: Application) : AndroidViewModel(application) { - - private val cacheDatabase: CacheDatabase = CacheDatabase.getDatabase(application) - - fun getItems(searchText: String?): LiveData> { - val query = GetApplicationsQuery(searchText) - return cacheDatabase.applicationsModelDao - .getApplicationModels(SimpleSQLiteQuery(query.toString())) - } -} diff --git a/app/src/main/java/com/sdex/activityrunner/app/EnableNotExportedActivitiesDialog.kt b/app/src/main/java/com/sdex/activityrunner/app/EnableNotExportedActivitiesDialog.kt index 54a11b91..edfbaf9e 100644 --- a/app/src/main/java/com/sdex/activityrunner/app/EnableNotExportedActivitiesDialog.kt +++ b/app/src/main/java/com/sdex/activityrunner/app/EnableNotExportedActivitiesDialog.kt @@ -10,11 +10,11 @@ import com.sdex.commons.BaseDialogFragment class EnableNotExportedActivitiesDialog : BaseDialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val alertDialog = AlertDialog.Builder(activity!!) + val alertDialog = AlertDialog.Builder(requireActivity()) .setTitle(R.string.dialog_enable_non_exported_title) .setMessage(R.string.dialog_enable_non_exported_message) .setPositiveButton(R.string.action_settings) { _, _ -> - SettingsActivity.start(activity!!) + SettingsActivity.start(requireActivity()) } .setNegativeButton(android.R.string.cancel, null) .create() diff --git a/app/src/main/java/com/sdex/activityrunner/app/MainViewModel.kt b/app/src/main/java/com/sdex/activityrunner/app/MainViewModel.kt new file mode 100644 index 00000000..dafdc1f7 --- /dev/null +++ b/app/src/main/java/com/sdex/activityrunner/app/MainViewModel.kt @@ -0,0 +1,21 @@ +package com.sdex.activityrunner.app + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.Transformations +import androidx.sqlite.db.SimpleSQLiteQuery +import com.sdex.activityrunner.db.cache.CacheDatabase +import com.sdex.activityrunner.db.cache.query.GetApplicationsQuery + +class MainViewModel(application: Application) : AndroidViewModel(application) { + + private val cacheDatabase = CacheDatabase.getDatabase(application) + + val searchQuery = MutableLiveData(null) + + val items = Transformations.switchMap(searchQuery) { text -> + val query = SimpleSQLiteQuery(GetApplicationsQuery(text).toString()) + cacheDatabase.applicationsModelDao.getApplicationModels(query) + } +} diff --git a/app/src/main/java/com/sdex/activityrunner/app/dialog/ActivityMenuDialog.kt b/app/src/main/java/com/sdex/activityrunner/app/dialog/ActivityOptionsDialog.kt similarity index 70% rename from app/src/main/java/com/sdex/activityrunner/app/dialog/ActivityMenuDialog.kt rename to app/src/main/java/com/sdex/activityrunner/app/dialog/ActivityOptionsDialog.kt index 06f35624..6bed3959 100644 --- a/app/src/main/java/com/sdex/activityrunner/app/dialog/ActivityMenuDialog.kt +++ b/app/src/main/java/com/sdex/activityrunner/app/dialog/ActivityOptionsDialog.kt @@ -1,6 +1,5 @@ package com.sdex.activityrunner.app.dialog -import android.content.Context import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -10,12 +9,9 @@ import com.sdex.activityrunner.R import com.sdex.activityrunner.app.ActivityLauncher import com.sdex.activityrunner.app.ActivityModel import com.sdex.activityrunner.shortcut.AddShortcutDialogActivity -import com.sdex.activityrunner.ui.SnackbarContainerActivity import kotlinx.android.synthetic.main.dialog_activity_menu.* -class ActivityMenuDialog : BottomSheetDialogFragment() { - - private lateinit var snackbarContainerActivity: SnackbarContainerActivity +class ActivityOptionsDialog : BottomSheetDialogFragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -24,22 +20,11 @@ class ActivityMenuDialog : BottomSheetDialogFragment() { return inflater.inflate(R.layout.dialog_activity_menu, container, false) } - override fun onAttach(context: Context) { - super.onAttach(context) - if (context is SnackbarContainerActivity) { - snackbarContainerActivity = context - } else { - throw IllegalArgumentException( - "${context::class.java.simpleName} doesn't implement SnackbarContainerActivity" - ) - } - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val model = requireArguments().getSerializable(ARG_MODEL) as ActivityModel - val launcher = ActivityLauncher(snackbarContainerActivity) + val launcher = ActivityLauncher(requireActivity()) activity_name.text = model.name action_activity_add_shortcut.setOnClickListener { @@ -64,8 +49,8 @@ class ActivityMenuDialog : BottomSheetDialogFragment() { private const val ARG_MODEL = "arg_model" - fun newInstance(model: ActivityModel): ActivityMenuDialog { - val dialog = ActivityMenuDialog() + fun newInstance(model: ActivityModel): ActivityOptionsDialog { + val dialog = ActivityOptionsDialog() dialog.arguments = Bundle(1).apply { putSerializable(ARG_MODEL, model) } diff --git a/app/src/main/java/com/sdex/activityrunner/app/dialog/ApplicationMenuDialog.kt b/app/src/main/java/com/sdex/activityrunner/app/dialog/ApplicationOptionsDialog.kt similarity index 92% rename from app/src/main/java/com/sdex/activityrunner/app/dialog/ApplicationMenuDialog.kt rename to app/src/main/java/com/sdex/activityrunner/app/dialog/ApplicationOptionsDialog.kt index 60f64afc..7e9b249b 100644 --- a/app/src/main/java/com/sdex/activityrunner/app/dialog/ApplicationMenuDialog.kt +++ b/app/src/main/java/com/sdex/activityrunner/app/dialog/ApplicationOptionsDialog.kt @@ -15,7 +15,7 @@ import com.sdex.activityrunner.util.IntentUtils import com.sdex.commons.util.AppUtils import kotlinx.android.synthetic.main.dialog_application_menu.* -class ApplicationMenuDialog : BottomSheetDialogFragment() { +class ApplicationOptionsDialog : BottomSheetDialogFragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -64,8 +64,8 @@ class ApplicationMenuDialog : BottomSheetDialogFragment() { private const val ARG_MODEL = "arg_model" - fun newInstance(model: ApplicationModel): ApplicationMenuDialog { - val dialog = ApplicationMenuDialog() + fun newInstance(model: ApplicationModel): ApplicationOptionsDialog { + val dialog = ApplicationOptionsDialog() dialog.arguments = Bundle(1).apply { putSerializable(ARG_MODEL, model) } diff --git a/app/src/main/java/com/sdex/activityrunner/app/legacy/OreoPackageManagerBugActivity.kt b/app/src/main/java/com/sdex/activityrunner/app/legacy/OreoPackageManagerBugActivity.kt deleted file mode 100644 index 2b840e2d..00000000 --- a/app/src/main/java/com/sdex/activityrunner/app/legacy/OreoPackageManagerBugActivity.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.sdex.activityrunner.app.legacy - -import android.content.Intent -import android.os.Bundle -import android.provider.Settings -import androidx.fragment.app.FragmentActivity -import com.sdex.activityrunner.R -import com.sdex.activityrunner.preferences.AppPreferences -import kotlinx.android.synthetic.main.activity_oreo_package_manager_bug.* - -class OreoPackageManagerBugActivity : FragmentActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_oreo_package_manager_bug) - - val appPreferences = AppPreferences(this) - - proceed.setOnClickListener { - appPreferences.isOreoBugWarningShown = true - finish() - } - - openApps.setOnClickListener { - finish() - try { - val intent = Intent(Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS) - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - startActivity(intent) - } catch (e: Exception) { - e.printStackTrace() - } - } - } -} diff --git a/app/src/main/java/com/sdex/activityrunner/db/cache/query/GetApplicationsQuery.kt b/app/src/main/java/com/sdex/activityrunner/db/cache/query/GetApplicationsQuery.kt index ed6a3f50..7797589f 100644 --- a/app/src/main/java/com/sdex/activityrunner/db/cache/query/GetApplicationsQuery.kt +++ b/app/src/main/java/com/sdex/activityrunner/db/cache/query/GetApplicationsQuery.kt @@ -2,7 +2,9 @@ package com.sdex.activityrunner.db.cache.query import com.sdex.activityrunner.db.cache.ApplicationModel -class GetApplicationsQuery(private val searchText: String?) { +class GetApplicationsQuery( + private val searchText: String? = null +) { private val sortBy: String = ApplicationModel.NAME private val sortOrder: String = "ASC" diff --git a/app/src/main/java/com/sdex/activityrunner/intent/dialog/ExportIntentAsUriDialog.kt b/app/src/main/java/com/sdex/activityrunner/intent/dialog/ExportIntentAsUriDialog.kt index 107f2015..a530c18d 100644 --- a/app/src/main/java/com/sdex/activityrunner/intent/dialog/ExportIntentAsUriDialog.kt +++ b/app/src/main/java/com/sdex/activityrunner/intent/dialog/ExportIntentAsUriDialog.kt @@ -18,7 +18,7 @@ class ExportIntentAsUriDialog : BaseDialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val launchParams = arguments?.getParcelable(ARG_LAUNCH_PARAMS) as LaunchParams? - val builder = AlertDialog.Builder(activity!!) + val builder = AlertDialog.Builder(requireActivity()) val view = View.inflate(activity, R.layout.dialog_export_intent_as_uri, null) val launchParamsToWebIntentConverter = LaunchParamsToWebIntentConverter(launchParams!!) @@ -29,7 +29,7 @@ class ExportIntentAsUriDialog : BaseDialogFragment() { .setView(view) .setPositiveButton(R.string.dialog_export_intent_copy) { _, _ -> val clipboard = - context!!.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager? + requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager? val clip = ClipData.newPlainText("Intent URI", value) clipboard!!.setPrimaryClip(clip) } diff --git a/app/src/main/java/com/sdex/activityrunner/intent/dialog/ExtraInputDialog.kt b/app/src/main/java/com/sdex/activityrunner/intent/dialog/ExtraInputDialog.kt index 9a8e6b63..9f17659b 100644 --- a/app/src/main/java/com/sdex/activityrunner/intent/dialog/ExtraInputDialog.kt +++ b/app/src/main/java/com/sdex/activityrunner/intent/dialog/ExtraInputDialog.kt @@ -18,10 +18,10 @@ class ExtraInputDialog : BaseDialogFragment() { private lateinit var callback: OnKeyValueInputDialogCallback override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val initialExtra = arguments!!.getParcelable(ARG_INITIAL_EXTRA) - val position = arguments!!.getInt(ARG_POSITION) + val initialExtra = requireArguments().getParcelable(ARG_INITIAL_EXTRA) + val position = requireArguments().getInt(ARG_POSITION) - val builder = AlertDialog.Builder(activity!!) + val builder = AlertDialog.Builder(requireActivity()) val view = View.inflate(activity, R.layout.dialog_input_extra, null) if (initialExtra != null) { diff --git a/app/src/main/java/com/sdex/activityrunner/intent/dialog/MultiSelectionDialog.kt b/app/src/main/java/com/sdex/activityrunner/intent/dialog/MultiSelectionDialog.kt index 5226af77..d4faa4b5 100644 --- a/app/src/main/java/com/sdex/activityrunner/intent/dialog/MultiSelectionDialog.kt +++ b/app/src/main/java/com/sdex/activityrunner/intent/dialog/MultiSelectionDialog.kt @@ -16,9 +16,9 @@ class MultiSelectionDialog : BaseDialogFragment() { private val selectedItems = SparseBooleanArray() override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val type: Int = arguments!!.getInt(ARG_TYPE) + val type: Int = requireArguments().getInt(ARG_TYPE) val initialPositions: ArrayList? = - arguments!!.getIntegerArrayList(ARG_INITIAL_POSITIONS) + requireArguments().getIntegerArrayList(ARG_INITIAL_POSITIONS) val source = when (type) { R.string.launch_param_categories -> CategoriesSource() @@ -35,7 +35,7 @@ class MultiSelectionDialog : BaseDialogFragment() { checkedItems[i] = checked selectedItems.put(i, checked) } - val builder = AlertDialog.Builder(activity!!) + val builder = AlertDialog.Builder(requireActivity()) builder.setMultiChoiceItems( list.toTypedArray(), checkedItems ) { _, which, isChecked -> selectedItems.put(which, isChecked) } diff --git a/app/src/main/java/com/sdex/activityrunner/intent/dialog/SingleSelectionDialog.kt b/app/src/main/java/com/sdex/activityrunner/intent/dialog/SingleSelectionDialog.kt index c4fcdb3a..5d7273a9 100644 --- a/app/src/main/java/com/sdex/activityrunner/intent/dialog/SingleSelectionDialog.kt +++ b/app/src/main/java/com/sdex/activityrunner/intent/dialog/SingleSelectionDialog.kt @@ -14,8 +14,8 @@ class SingleSelectionDialog : BaseDialogFragment() { private lateinit var callback: OnItemSelectedCallback override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val type: Int = arguments!!.getInt(ARG_TYPE) - val initialPosition: Int = arguments!!.getInt(ARG_INITIAL_POSITION) + val type: Int = requireArguments().getInt(ARG_TYPE) + val initialPosition: Int = requireArguments().getInt(ARG_INITIAL_POSITION) val source = when (type) { R.string.launch_param_action -> ActionSource() @@ -24,7 +24,7 @@ class SingleSelectionDialog : BaseDialogFragment() { } val list = source.list - val builder = AlertDialog.Builder(activity!!) + val builder = AlertDialog.Builder(requireActivity()) builder.setSingleChoiceItems( list.toTypedArray(), initialPosition diff --git a/app/src/main/java/com/sdex/activityrunner/intent/dialog/ValueInputDialog.kt b/app/src/main/java/com/sdex/activityrunner/intent/dialog/ValueInputDialog.kt index f5923f83..a08b156a 100644 --- a/app/src/main/java/com/sdex/activityrunner/intent/dialog/ValueInputDialog.kt +++ b/app/src/main/java/com/sdex/activityrunner/intent/dialog/ValueInputDialog.kt @@ -15,10 +15,10 @@ class ValueInputDialog : BaseDialogFragment() { private lateinit var callback: OnValueInputDialogCallback override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val type: Int = arguments!!.getInt(ARG_TYPE) - val initialValue: String = arguments!!.getString(ARG_INITIAL_VALUE, "") + val type: Int = requireArguments().getInt(ARG_TYPE) + val initialValue: String = requireArguments().getString(ARG_INITIAL_VALUE, "") - val builder = AlertDialog.Builder(activity!!) + val builder = AlertDialog.Builder(requireActivity()) val view = View.inflate(activity, R.layout.dialog_input_value, null) view.valueView.setText(initialValue) diff --git a/app/src/main/java/com/sdex/activityrunner/preferences/SettingsFragment.kt b/app/src/main/java/com/sdex/activityrunner/preferences/SettingsFragment.kt index 545e6a68..ddebc3b5 100644 --- a/app/src/main/java/com/sdex/activityrunner/preferences/SettingsFragment.kt +++ b/app/src/main/java/com/sdex/activityrunner/preferences/SettingsFragment.kt @@ -1,11 +1,11 @@ package com.sdex.activityrunner.preferences import android.os.Bundle -import android.widget.Toast import androidx.appcompat.app.AppCompatDelegate import androidx.preference.ListPreference import androidx.preference.PreferenceFragmentCompat import androidx.preference.SwitchPreferenceCompat +import com.google.android.material.snackbar.Snackbar import com.sdex.activityrunner.R import com.sdex.activityrunner.preferences.AppPreferences.Companion.KEY_ROOT_INTEGRATION import com.sdex.activityrunner.preferences.AppPreferences.Companion.KEY_THEME @@ -52,12 +52,14 @@ class SettingsFragment : PreferenceFragmentCompat() { private fun checkRoot(rootIntegration: SwitchPreferenceCompat) { val checkRootTask = CheckRootTask(object : CheckRootTask.Callback { override fun onStatusChanged(status: Int) { - if (activity != null && !activity!!.isFinishing && isAdded) { + val activity = activity + if (activity != null && !activity.isFinishing && isAdded) { if (status != CheckRootTask.RESULT_OK) { rootIntegration.isChecked = false - Toast.makeText( - activity, R.string.settings_error_root_not_granted, - Toast.LENGTH_SHORT + Snackbar.make( + activity.findViewById(android.R.id.content), + R.string.settings_error_root_not_granted, + Snackbar.LENGTH_LONG ).show() } } diff --git a/app/src/main/java/com/sdex/activityrunner/shortcut/AddShortcutDialogActivity.kt b/app/src/main/java/com/sdex/activityrunner/shortcut/AddShortcutDialogActivity.kt index 87fd741a..75e384f4 100644 --- a/app/src/main/java/com/sdex/activityrunner/shortcut/AddShortcutDialogActivity.kt +++ b/app/src/main/java/com/sdex/activityrunner/shortcut/AddShortcutDialogActivity.kt @@ -92,11 +92,11 @@ class AddShortcutDialogActivity : AppCompatActivity(), ContentManager.PickConten } activityModel?.let { - activityModel.name = shortcutName + val model = it.copy(name = shortcutName) if (bitmap != null) { - IntentUtils.createLauncherIcon(this, activityModel, bitmap!!) + IntentUtils.createLauncherIcon(this, model, bitmap!!) } else { - IntentUtils.createLauncherIcon(this, activityModel) + IntentUtils.createLauncherIcon(this, model) } } diff --git a/app/src/main/java/com/sdex/activityrunner/ui/SnackbarContainerActivity.kt b/app/src/main/java/com/sdex/activityrunner/ui/SnackbarContainerActivity.kt deleted file mode 100644 index 29d7dc80..00000000 --- a/app/src/main/java/com/sdex/activityrunner/ui/SnackbarContainerActivity.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.sdex.activityrunner.ui - -import android.app.Activity -import android.view.View - -interface SnackbarContainerActivity { - - fun getView(): View - - fun getActivity(): Activity -} diff --git a/app/src/main/res/drawable/img_oreo_instant_bug.png b/app/src/main/res/drawable/img_oreo_instant_bug.png deleted file mode 100644 index ed3c8c2fe674f5b1a6d5e51cc5feac2df9c394bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33494 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 - - - - - - - - - - - - - - - - -