Parcourir la source

version sufix

sduduzog il y a 7 ans
Parent
commit
c9aaf32985

+ 5 - 6
app/build.gradle

@@ -13,6 +13,7 @@ android {
         versionCode 2
         versionName "0.1.2"
         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        versionNameSuffix 'preview'
     }
     buildTypes {
         release {
@@ -28,7 +29,7 @@ android {
 }
 
 dependencies {
-    implementation fileTree(dir: 'libs', include: ['*.jar'])
+    implementation fileTree(include: ['*.jar'], dir: 'libs')
     implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
     implementation 'com.android.support:appcompat-v7:28.0.0'
     implementation 'com.android.support.constraint:constraint-layout:1.1.3'
@@ -38,12 +39,10 @@ dependencies {
     androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
     implementation 'com.android.support:recyclerview-v7:28.0.0'
     implementation 'android.arch.navigation:navigation-fragment:1.0.0-alpha06'
-
-    implementation "android.arch.persistence.room:runtime:1.1.1"
+    implementation 'android.arch.persistence.room:runtime:1.1.1'
     annotationProcessor "android.arch.persistence.room:compiler:1.1.1"
-    androidTestImplementation "android.arch.persistence.room:testing:1.1.1"
-
-    implementation "android.arch.lifecycle:extensions:1.1.1"
+    androidTestImplementation 'android.arch.persistence.room:testing:1.1.1'
+    implementation 'android.arch.lifecycle:extensions:1.1.1'
     annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
     implementation 'com.android.support:cardview-v7:28.0.0'
 }

+ 6 - 44
app/src/main/java/com/sduduzog/slimlauncher/MainActivity.kt

@@ -1,17 +1,14 @@
 package com.sduduzog.slimlauncher
 
 import android.arch.lifecycle.ViewModelProviders
-import android.content.*
-import android.content.pm.ResolveInfo
+import android.content.SharedPreferences
 import android.content.res.Resources
 import android.os.Bundle
 import android.support.v7.app.AppCompatActivity
 import androidx.navigation.NavController
 import androidx.navigation.NavDestination
 import androidx.navigation.Navigation.findNavController
-import com.sduduzog.slimlauncher.data.App
 import com.sduduzog.slimlauncher.ui.main.MainViewModel
-import java.util.*
 
 
 class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceChangeListener, NavController.OnNavigatedListener {
@@ -21,7 +18,6 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
     private lateinit var currentLabel: String
 
     private lateinit var viewModel: MainViewModel
-    private lateinit var receiver: PackageInfoReceiver
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -31,7 +27,11 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
         val navigator = findNavController(this, R.id.nav_host_fragment)
         navigator.addOnNavigatedListener(this)
         viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
-        updateApps()
+    }
+
+    override fun onStart() {
+        super.onStart()
+        viewModel.updateApps()
     }
 
     override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, s: String?) {
@@ -59,42 +59,4 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
     override fun onNavigated(controller: NavController, destination: NavDestination) {
         currentLabel = destination.label.toString()
     }
-
-    private fun updateApps(){
-        val apps: MutableList<App> = mutableListOf()
-        val pm = packageManager
-        val main = Intent(Intent.ACTION_MAIN, null)
-
-        main.addCategory(Intent.CATEGORY_LAUNCHER)
-
-        val launchables = pm.queryIntentActivities(main, 0)
-        Collections.sort(launchables,
-                ResolveInfo.DisplayNameComparator(pm))
-        for (i in launchables.indices) {
-            val item = launchables[i]
-            val activity = item.activityInfo
-            val app = App(activity.loadLabel(pm).toString(), activity.name, activity.applicationInfo.packageName)
-            apps.add(app)
-        }
-        viewModel.bulkInsert(apps)
-    }
-
-    override fun onStart() {
-        super.onStart()
-        receiver = PackageInfoReceiver()
-        registerReceiver(receiver, IntentFilter(Intent.ACTION_PACKAGE_ADDED))
-        registerReceiver(receiver, IntentFilter(Intent.ACTION_PACKAGE_REMOVED))
-    }
-
-    override fun onStop() {
-        super.onStop()
-        unregisterReceiver(receiver)
-    }
-
-    inner class PackageInfoReceiver: BroadcastReceiver() {
-        override fun onReceive(ctx: Context?, intent: Intent?) {
-            updateApps()
-        }
-
-    }
 }

+ 9 - 4
app/src/main/java/com/sduduzog/slimlauncher/data/App.kt

@@ -5,7 +5,12 @@ import android.arch.persistence.room.Entity
 import android.arch.persistence.room.PrimaryKey
 
 @Entity(tableName = "apps")
-data class App(@field:ColumnInfo(name = "label")
-          var label: String, @field:ColumnInfo(name = "activity_name")
-          var activityName: String, @field:PrimaryKey @field:ColumnInfo(name = "package_name")
-          var packageName: String, @field:ColumnInfo(name = "home") var home: Boolean = false)
+class App(
+        @field:ColumnInfo(name = "app_name")
+        var appName: String,
+        @PrimaryKey
+        @field:ColumnInfo(name = "package_name")
+        var packageName: String,
+        @field:ColumnInfo(name = "activity_name")
+        var activityName: String
+)

+ 12 - 13
app/src/main/java/com/sduduzog/slimlauncher/data/AppDao.kt

@@ -1,32 +1,31 @@
 package com.sduduzog.slimlauncher.data
 
 import android.arch.lifecycle.LiveData
-import android.arch.persistence.room.Dao
-import android.arch.persistence.room.Insert
-import android.arch.persistence.room.Query
-import android.arch.persistence.room.Update
+import android.arch.persistence.room.*
 
 @Dao
 interface AppDao {
 
-    @get:Query("SELECT * from apps")
-    val allApps: LiveData<List<App>>
 
-    @get:Query("SELECT * from apps WHERE home=1")
-    val homeApps: LiveData<List<App>>
+    @get:Query("SELECT * FROM apps WHERE package_name NOT IN (SELECT apps.package_name from apps JOIN home_apps ON home_apps.package_name=apps.package_name)")
+    val apps: LiveData<List<App>>
 
-    @get:Query("SELECT * from apps WHERE home=0")
-    val availableApps: LiveData<List<App>>
+    @get:Query("SELECT * FROM home_apps")
+    val homeApps: LiveData<List<HomeApp>>
 
-    @Insert
+    @Insert(onConflict = OnConflictStrategy.IGNORE)
     fun insert(app: App)
 
     @Update
     fun update(app: App)
 
+    @Insert(onConflict = OnConflictStrategy.IGNORE)
+    fun addHomeApp(app: HomeApp)
+
     @Query("DELETE FROM apps")
     fun deleteAll()
 
-    @Query("DELETE FROM apps WHERE package_name=:packageName")
-    fun delete(packageName: String)
+    @Delete
+    fun delete(app: HomeApp)
+
 }

+ 52 - 30
app/src/main/java/com/sduduzog/slimlauncher/data/AppRepository.kt

@@ -2,40 +2,45 @@ package com.sduduzog.slimlauncher.data
 
 import android.app.Application
 import android.arch.lifecycle.LiveData
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.content.pm.ResolveInfo
 import android.os.AsyncTask
+import java.util.*
 
-class AppRepository(application: Application){
+class AppRepository(application: Application) {
 
-    val db = AppRoomDatabase.getDatabase(application)
-    private var appDao: AppDao = db!!.appDao()
-    private var _apps: LiveData<List<App>> = appDao.allApps
-    private var _homeApps: LiveData<List<App>> = appDao.homeApps
-    private var _availableApps: LiveData<List<App>> = appDao.availableApps
+    private val db: AppRoomDatabase = AppRoomDatabase.getDatabase(application)
+    private var appDao: AppDao = db.appDao()
+    private var _apps: LiveData<List<App>> = appDao.apps
+    private var _homeApps: LiveData<List<HomeApp>> = appDao.homeApps
 
+    private var pm: PackageManager = application.packageManager
 
-    val allApps: LiveData<List<App>>
-        get() = _apps
+    val homeApps: LiveData<List<HomeApp>>
+        get() = _homeApps
 
-    val homeApps: LiveData<List<App>>
-    get() = _homeApps
-
-    val availableApps: LiveData<List<App>>
-        get() = _availableApps
+    val apps: LiveData<List<App>>
+    get() = _apps
 
     fun insert(app: App) {
         InsertAsyncTask(appDao).execute(app)
     }
 
+    fun delete(app: HomeApp) {
+        DeleteAsyncTask(appDao).execute(app)
+    }
+
     fun update(app: App) {
         UpdateAsyncTask(appDao).execute(app)
     }
 
-    fun bulkInsert(apps: List<App>) {
-        BulkInsertAsyncTask(appDao).execute(apps)
+    fun updateApps() {
+        UpdateAppsAsyncTask(appDao).execute(pm)
     }
 
-    fun delete(packageName: String) {
-        DeleteAsyncTask(appDao).execute(packageName)
+    fun insertHomeApp(home: HomeApp) {
+    InsertHomeAsyncTask(appDao).execute(home)
     }
 
     private class InsertAsyncTask internal constructor(private val mAsyncTaskDao: AppDao) : AsyncTask<App, Void, Void>() {
@@ -46,31 +51,48 @@ class AppRepository(application: Application){
         }
     }
 
-    private class UpdateAsyncTask internal constructor(private val mAsyncTaskDao: AppDao) : AsyncTask<App, Void, Void>() {
+    private class InsertHomeAsyncTask internal constructor(private val mAsyncTaskDao: AppDao) : AsyncTask<HomeApp, Void, Void>() {
 
-        override fun doInBackground(vararg params: App): Void? {
-            mAsyncTaskDao.update(params[0])
+        override fun doInBackground(vararg params: HomeApp): Void? {
+            mAsyncTaskDao.addHomeApp(params[0])
             return null
         }
     }
 
-    private class BulkInsertAsyncTask internal constructor(private val mAsyncTaskDao: AppDao) : AsyncTask<List<App>, Void, Void>() {
+    private class DeleteAsyncTask internal constructor(private val mAsyncTaskDao: AppDao) : AsyncTask<HomeApp, Void, Void>() {
 
-        override fun doInBackground(vararg params: List<App>): Void? {
-            mAsyncTaskDao.deleteAll()
-            val apps = params[0]
-            for (i in apps.indices){
-                mAsyncTaskDao.insert(apps[i])
-            }
+        override fun doInBackground(vararg params: HomeApp): Void? {
+            mAsyncTaskDao.delete(params[0])
+            return null
+        }
+    }
+
+    private class UpdateAsyncTask internal constructor(private val mAsyncTaskDao: AppDao) : AsyncTask<App, Void, Void>() {
 
+        override fun doInBackground(vararg params: App): Void? {
+            mAsyncTaskDao.update(params[0])
             return null
         }
     }
 
-    private class DeleteAsyncTask internal constructor(private val mAsyncTaskDao: AppDao) : AsyncTask<String, Void, Void>() {
+    private class UpdateAppsAsyncTask internal constructor(private val mAsyncTaskDao: AppDao) : AsyncTask<PackageManager, Void, Void>() {
 
-        override fun doInBackground(vararg params: String): Void? {
-            mAsyncTaskDao.delete(params[0])
+        override fun doInBackground(vararg params: PackageManager): Void? {
+            val pm = params[0]
+            val main = Intent(Intent.ACTION_MAIN, null)
+
+            main.addCategory(Intent.CATEGORY_LAUNCHER)
+
+            val launchables = pm.queryIntentActivities(main, 0)
+            Collections.sort(launchables,
+                    ResolveInfo.DisplayNameComparator(pm))
+            mAsyncTaskDao.deleteAll()
+            for (i in launchables.indices) {
+                val item = launchables[i]
+                val activity = item.activityInfo
+                val app = App(activity.loadLabel(pm).toString(), activity.name, activity.applicationInfo.packageName)
+                mAsyncTaskDao.insert(app)
+            }
             return null
         }
     }

+ 1 - 1
app/src/main/java/com/sduduzog/slimlauncher/data/AppRoomDatabase.java

@@ -5,7 +5,7 @@ import android.arch.persistence.room.Room;
 import android.arch.persistence.room.RoomDatabase;
 import android.content.Context;
 
-@Database(entities = {App.class}, version = 1)
+@Database(entities = {App.class, HomeApp.class}, version = 1, exportSchema = false)
 public abstract class AppRoomDatabase extends RoomDatabase {
     private static volatile AppRoomDatabase INSTANCE;
     static AppRoomDatabase getDatabase(final Context context) {

+ 16 - 0
app/src/main/java/com/sduduzog/slimlauncher/data/HomeApp.kt

@@ -0,0 +1,16 @@
+package com.sduduzog.slimlauncher.data
+
+import android.arch.persistence.room.ColumnInfo
+import android.arch.persistence.room.Entity
+import android.arch.persistence.room.PrimaryKey
+
+@Entity(tableName = "home_apps")
+class HomeApp(
+        @field:ColumnInfo(name = "app_name")
+        var appName: String,
+        @PrimaryKey
+        @field:ColumnInfo(name = "package_name")
+        var packageName: String,
+        @field:ColumnInfo(name = "activity_name")
+        var activityName: String
+)

+ 4 - 4
app/src/main/java/com/sduduzog/slimlauncher/ui/apps/AppsFragment.kt

@@ -13,6 +13,7 @@ import android.view.ViewGroup
 import androidx.navigation.Navigation
 import com.sduduzog.slimlauncher.R
 import com.sduduzog.slimlauncher.data.App
+import com.sduduzog.slimlauncher.data.HomeApp
 import com.sduduzog.slimlauncher.ui.main.MainViewModel
 import java.util.*
 
@@ -50,7 +51,7 @@ class AppsFragment : Fragment() {
     override fun onActivityCreated(savedInstanceState: Bundle?) {
         super.onActivityCreated(savedInstanceState)
         viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
-        viewModel.availableApps.observe(this, Observer {
+        viewModel.apps.observe(this, Observer {
             if (it != null) {
                 mAdapter.setList(it)
             }
@@ -59,10 +60,9 @@ class AppsFragment : Fragment() {
 
     inner class InteractionHandler : OnListFragmentInteractionListener {
         override fun onListFragmentInteraction(app: App) {
-            app.home = true
-            viewModel.update(app)
+            viewModel.addToHomeScreen(app)
             val nav = Navigation.findNavController(layout)
-            nav.navigateUp()
+            nav.popBackStack()
         }
     }
 

+ 1 - 1
app/src/main/java/com/sduduzog/slimlauncher/ui/apps/AppsListAdapter.kt

@@ -36,7 +36,7 @@ class AppsListAdapter(
 
     override fun onBindViewHolder(holder: ViewHolder, position: Int) {
         val item = mValues.elementAt(position)
-        holder.mLabelView.text = item.label
+        holder.mLabelView.text = item.appName
         with(holder.mView) {
             tag = item
             setOnClickListener(mOnClickListener)

+ 5 - 5
app/src/main/java/com/sduduzog/slimlauncher/ui/main/MainAppsAdapter.kt

@@ -6,9 +6,9 @@ import android.view.View
 import android.view.ViewGroup
 import android.widget.TextView
 import com.sduduzog.slimlauncher.R
-import com.sduduzog.slimlauncher.data.App
+import com.sduduzog.slimlauncher.data.HomeApp
 
-class MainAppsAdapter(private var mValues: MutableSet<App>,
+class MainAppsAdapter(private var mValues: MutableSet<HomeApp>,
                       private val mListener: MainFragment.OnListFragmentInteractionListener?)
     : RecyclerView.Adapter<MainAppsAdapter.ViewHolder>() {
 
@@ -20,20 +20,20 @@ class MainAppsAdapter(private var mValues: MutableSet<App>,
 
     override fun onBindViewHolder(holder: MainAppsAdapter.ViewHolder, position: Int) {
         val item = mValues.elementAt(position)
-        holder.mLabelView.text = item.label
+        holder.mLabelView.text = item.appName
         holder.mLabelView.setOnClickListener {
             mListener?.onLaunch(item)
         }
     }
 
     override fun getItemCount(): Int = mValues.size
-    fun setApps(it: List<App>) {
+    fun setApps(it: List<HomeApp>) {
         mValues = mutableSetOf()
         mValues.addAll(it)
         notifyDataSetChanged()
     }
 
-    inner class ViewHolder(val mView: View) : RecyclerView.ViewHolder(mView) {
+    inner class ViewHolder(mView: View) : RecyclerView.ViewHolder(mView) {
         val mLabelView: TextView = mView.findViewById(R.id.main_label)
 
         override fun toString(): String {

+ 12 - 11
app/src/main/java/com/sduduzog/slimlauncher/ui/main/MainFragment.kt

@@ -1,6 +1,5 @@
 package com.sduduzog.slimlauncher.ui.main
 
-import android.annotation.TargetApi
 import android.arch.lifecycle.Observer
 import android.arch.lifecycle.ViewModelProviders
 import android.content.*
@@ -13,11 +12,10 @@ import android.view.ViewGroup
 import android.widget.Toast
 import androidx.navigation.Navigation
 import com.sduduzog.slimlauncher.R
-import com.sduduzog.slimlauncher.data.App
+import com.sduduzog.slimlauncher.data.HomeApp
 import kotlinx.android.synthetic.main.main_fragment.*
 import java.text.SimpleDateFormat
-import java.util.Date
-import java.util.Locale
+import java.util.*
 
 class MainFragment : Fragment() {
 
@@ -27,9 +25,7 @@ class MainFragment : Fragment() {
 
     override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                               savedInstanceState: Bundle?): View {
-        val view = inflater.inflate(R.layout.main_fragment, container, false)
-
-        return view
+        return inflater.inflate(R.layout.main_fragment, container, false)
     }
 
     override fun onActivityCreated(savedInstanceState: Bundle?) {
@@ -38,7 +34,7 @@ class MainFragment : Fragment() {
         adapter = MainAppsAdapter(mutableSetOf(), InteractionHandler())
         mainAppsList.adapter = adapter
         viewModel.homeApps.observe(this, Observer {
-            if (it !=null){
+            if (it != null) {
                 adapter.setApps(it)
             }
         })
@@ -77,18 +73,23 @@ class MainFragment : Fragment() {
     }
 
     inner class InteractionHandler : OnListFragmentInteractionListener {
-        override fun onLaunch(item: App) {
+        override fun onLaunch(item: HomeApp) {
             val name = ComponentName(item.packageName, item.activityName)
             val intent = Intent()
             intent.action = Intent.ACTION_MAIN
             intent.addCategory(Intent.CATEGORY_LAUNCHER)
             intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
             intent.component = name
-            startActivity(intent)
+            try {
+                startActivity(intent)
+            } catch (e: ActivityNotFoundException) {
+                Toast.makeText(activity, "${item.appName} seems to be uninstalled, removing from list", Toast.LENGTH_LONG).show()
+                viewModel.deleteApp(item)
+            }
         }
     }
 
     interface OnListFragmentInteractionListener {
-        fun onLaunch(item: App)
+        fun onLaunch(item: HomeApp)
     }
 }

+ 14 - 13
app/src/main/java/com/sduduzog/slimlauncher/ui/main/MainViewModel.kt

@@ -5,27 +5,27 @@ import android.arch.lifecycle.AndroidViewModel
 import android.arch.lifecycle.LiveData
 import com.sduduzog.slimlauncher.data.App
 import com.sduduzog.slimlauncher.data.AppRepository
+import com.sduduzog.slimlauncher.data.HomeApp
 
 class MainViewModel(application: Application) : AndroidViewModel(application) {
     private var _repository: AppRepository = AppRepository(application)
+    private var _homeApps: LiveData<List<HomeApp>>
     private var _apps: LiveData<List<App>>
-    private var _homeApps: LiveData<List<App>>
-    private var _availableApps: LiveData<List<App>>
 
     init {
-        _apps = _repository.allApps
         _homeApps = _repository.homeApps
-        _availableApps = _repository.availableApps
+        _apps = _repository.apps
     }
 
+    val homeApps: LiveData<List<HomeApp>>
+        get() = _homeApps
+
     val apps: LiveData<List<App>>
         get() = _apps
 
-    val homeApps: LiveData<List<App>>
-        get() = _homeApps
-
-    val availableApps: LiveData<List<App>>
-        get() = _availableApps
+    fun deleteApp(app: HomeApp) {
+        _repository.delete(app)
+    }
 
     fun insert(app: App) {
         _repository.insert(app)
@@ -35,11 +35,12 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
         _repository.update(app)
     }
 
-    fun deleteApp(packageName: String) {
-        _repository.delete(packageName)
+    fun updateApps() {
+        _repository.updateApps()
     }
 
-    fun bulkInsert(apps: MutableList<App>) {
-        _repository.bulkInsert(apps)
+    fun addToHomeScreen(app: App) {
+        val home = HomeApp(app.appName, app.packageName, app.activityName)
+        _repository.insertHomeApp(home)
     }
 }

+ 5 - 6
app/src/main/java/com/sduduzog/slimlauncher/ui/main/SettingsFragment.kt

@@ -14,7 +14,7 @@ import android.view.View
 import android.view.ViewGroup
 import androidx.navigation.Navigation
 import com.sduduzog.slimlauncher.R
-import com.sduduzog.slimlauncher.data.App
+import com.sduduzog.slimlauncher.data.HomeApp
 import kotlinx.android.synthetic.main.fragment_settings.*
 
 
@@ -40,7 +40,7 @@ class SettingsFragment : Fragment() {
                 }
             }
         })
-        var apps = viewModel.apps.value
+        var apps = viewModel.homeApps.value
         if (apps == null)
             apps = listOf()
         adapter = SettingsListAdapter(apps, InteractionHandler())
@@ -68,13 +68,12 @@ class SettingsFragment : Fragment() {
     }
 
     inner class InteractionHandler : OnListFragmentInteractionListener {
-        override fun onRemove(app: App) {
-            app.home = false
-            viewModel.update(app)
+        override fun onRemove(app: HomeApp) {
+            viewModel.deleteApp(app)
         }
     }
 
     interface OnListFragmentInteractionListener {
-        fun onRemove(app: App)
+        fun onRemove(app: HomeApp)
     }
 }

+ 4 - 4
app/src/main/java/com/sduduzog/slimlauncher/ui/main/SettingsListAdapter.kt

@@ -7,9 +7,9 @@ import android.view.ViewGroup
 import android.widget.Button
 import android.widget.TextView
 import com.sduduzog.slimlauncher.R
-import com.sduduzog.slimlauncher.data.App
+import com.sduduzog.slimlauncher.data.HomeApp
 
-class SettingsListAdapter(private var apps: List<App>, private val listener: SettingsFragment.OnListFragmentInteractionListener) : RecyclerView.Adapter<SettingsListAdapter.AppViewHolder>() {
+class SettingsListAdapter(private var apps: List<HomeApp>, private val listener: SettingsFragment.OnListFragmentInteractionListener) : RecyclerView.Adapter<SettingsListAdapter.AppViewHolder>() {
 
     private lateinit var inflater: LayoutInflater
 
@@ -20,7 +20,7 @@ class SettingsListAdapter(private var apps: List<App>, private val listener: Set
     }
 
     override fun onBindViewHolder(holder: AppViewHolder, position: Int) {
-        holder.labelText.text = apps[position].label
+        holder.labelText.text = apps[position].appName
         holder.removeButton.setOnClickListener {
                 listener.onRemove(apps[position])
         }
@@ -30,7 +30,7 @@ class SettingsListAdapter(private var apps: List<App>, private val listener: Set
         return apps.size
     }
 
-    internal fun setApps(apps: List<App>) {
+    internal fun setApps(apps: List<HomeApp>) {
         this.apps = apps
         notifyDataSetChanged()
     }