diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c4b8694..1c7e812 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,11 +2,15 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/uzlov/moviefind/HostActivity.kt b/app/src/main/java/com/uzlov/moviefind/HostActivity.kt index 065c5eb..0518186 100644 --- a/app/src/main/java/com/uzlov/moviefind/HostActivity.kt +++ b/app/src/main/java/com/uzlov/moviefind/HostActivity.kt @@ -1,25 +1,37 @@ package com.uzlov.moviefind +import com.uzlov.moviefind.services.SampleService +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter import android.os.Bundle import android.view.Menu import android.view.MenuItem import android.widget.Toast import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import com.uzlov.moviefind.databinding.ActivityMainBinding +import com.uzlov.moviefind.fragments.ErrorConnectionFragment import com.uzlov.moviefind.fragments.FilmFragment import com.uzlov.moviefind.fragments.HomeFragment import com.uzlov.moviefind.fragments.PopularFilmsFragment +import com.uzlov.moviefind.services.NetworkListener +import com.uzlov.moviefind.services.NetworkStateListener class HostActivity : AppCompatActivity() { + private lateinit var broadcastReceiver: NetworkStateListener private val popularFilmsFragment = PopularFilmsFragment() private val homeFragment = HomeFragment() private var activeFragment = Fragment() private var filmsFragmentL = FilmFragment() + private var errorFragment = ErrorConnectionFragment() private var _viewBinding: ActivityMainBinding ?= null private val viewBinding get() = _viewBinding!! + private val sampleReceiver = SampleReceiver() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -31,11 +43,11 @@ class HostActivity : AppCompatActivity() { viewBinding.bottomNavigation.setOnNavigationItemSelectedListener { when (it.itemId) { R.id.menu_home -> { - setActiveFragment(homeFragment) + replaceActiveFragment(homeFragment) true } R.id.menu_favorite-> { - setActiveFragment(popularFilmsFragment) + replaceActiveFragment(popularFilmsFragment) true } R.id.menu_settings -> { @@ -45,13 +57,39 @@ class HostActivity : AppCompatActivity() { else -> false } } + startNetworkListener() + startSampleDataListener() + } + + private fun startNetworkListener(){ + val intentFilter = IntentFilter() + intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE") + // слушатель состояния интернета + broadcastReceiver = NetworkStateListener(object : NetworkListener { + override fun networkStateChanged(isAvailable: Boolean) { + updateStateNetwork(isAvailable) + } + }) + registerReceiver(broadcastReceiver, intentFilter) + } + + private fun startSampleDataListener(){ + val intentFilter2 = IntentFilter().apply { + addAction(SampleService.ACTION) + } + registerReceiver(sampleReceiver, intentFilter2) + + val serviceIntent2 = Intent(this, SampleService::class.java) + ContextCompat.startForegroundService(this, serviceIntent2) } private fun initFragments(){ supportFragmentManager.beginTransaction().apply { add(R.id.fragment_container, homeFragment, "homeFragment").hide(homeFragment) add(R.id.fragment_container, popularFilmsFragment, "popularFilmsFragment").hide(popularFilmsFragment) - add(R.id.fragment_container, filmsFragmentL, "filmsFragmentL").hide(filmsFragmentL) + add(R.id.fragment_container, filmsFragmentL, "filmsFragment").hide(filmsFragmentL) + add(R.id.fragment_container, errorFragment, "errorFragment").hide(errorFragment) + setReorderingAllowed(true) }.commit() setActiveFragment(homeFragment) @@ -63,6 +101,10 @@ class HostActivity : AppCompatActivity() { activeFragment = fragment } + private fun replaceActiveFragment(fragment: Fragment){ + supportFragmentManager.beginTransaction().replace(R.id.fragment_container, fragment).commit() + } + override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_main, menu) return true @@ -75,8 +117,30 @@ class HostActivity : AppCompatActivity() { } } + fun updateStateNetwork(isAvailable: Boolean) { + if (isAvailable) { + setActiveFragment(homeFragment) + homeFragment.loadData() + } else { + setActiveFragment(errorFragment) + } + } + override fun onDestroy() { super.onDestroy() _viewBinding = null + unregisterReceiver(broadcastReceiver) + unregisterReceiver(sampleReceiver) + } + + /** + * Receiver sample data from com.uzlov.moviefind.services.SampleService.kt + **/ + private inner class SampleReceiver : BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent?) { + intent.let { + Toast.makeText(context, intent?.getStringExtra(SampleService.VALUE_KEY), Toast.LENGTH_SHORT).show() + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/uzlov/moviefind/fragments/ErrorConnectionFragment.kt b/app/src/main/java/com/uzlov/moviefind/fragments/ErrorConnectionFragment.kt new file mode 100644 index 0000000..e7e449e --- /dev/null +++ b/app/src/main/java/com/uzlov/moviefind/fragments/ErrorConnectionFragment.kt @@ -0,0 +1,36 @@ +package com.uzlov.moviefind.fragments + +import android.content.Intent +import android.os.Bundle +import android.provider.Settings +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.uzlov.moviefind.databinding.ErrorConnectionContentBinding + +class ErrorConnectionFragment : Fragment() { + private var _viewBinding: ErrorConnectionContentBinding?=null + private val viewBinding get() = _viewBinding!! + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _viewBinding = ErrorConnectionContentBinding.inflate(layoutInflater, container, false) + return viewBinding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + viewBinding.btnGoToSettings.setOnClickListener { + showSettings() + } + } + + private fun showSettings() { + val intent = Intent(Settings.ACTION_WIRELESS_SETTINGS) + startActivity(intent) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/uzlov/moviefind/services/NetworkListener.kt b/app/src/main/java/com/uzlov/moviefind/services/NetworkListener.kt new file mode 100644 index 0000000..41fd1bc --- /dev/null +++ b/app/src/main/java/com/uzlov/moviefind/services/NetworkListener.kt @@ -0,0 +1,5 @@ +package com.uzlov.moviefind.services + +interface NetworkListener { + fun networkStateChanged(isAvailable:Boolean) +} \ No newline at end of file diff --git a/app/src/main/java/com/uzlov/moviefind/services/NetworkStateListener.kt b/app/src/main/java/com/uzlov/moviefind/services/NetworkStateListener.kt new file mode 100644 index 0000000..ed79402 --- /dev/null +++ b/app/src/main/java/com/uzlov/moviefind/services/NetworkStateListener.kt @@ -0,0 +1,47 @@ +package com.uzlov.moviefind.services + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.net.ConnectivityManager + + +class NetworkStateListener(private val networkListener: NetworkListener) : BroadcastReceiver(){ + private lateinit var connectivityManager: ConnectivityManager + private val TYPE_WIFI = 1 + private val TYPE_MOBILE = 2 + private val TYPE_NOT_CONNECTED = 0 + private val NETWORK_STATUS_NOT_CONNECTED = 0 + private val NETWORK_STATUS_WIFI = 1 + private val NETWORK_STATUS_MOBILE = 2 + + override fun onReceive(context: Context, intent: Intent?) { + connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + intent.let { + if ("android.net.conn.CONNECTIVITY_CHANGE" == intent?.action){ + when(getConnectionState()){ + NETWORK_STATUS_NOT_CONNECTED-> networkListener.networkStateChanged(false) + else -> networkListener.networkStateChanged(true) + } + } + } + } + + private fun getConnectivityStatus(): Int { + val activeNetwork = connectivityManager.activeNetworkInfo + if (null != activeNetwork) { + if (activeNetwork.type == ConnectivityManager.TYPE_WIFI) return TYPE_WIFI + if (activeNetwork.type == ConnectivityManager.TYPE_MOBILE) return TYPE_MOBILE + } + return TYPE_NOT_CONNECTED + } + + private fun getConnectionState(): Int { + return when (getConnectivityStatus()) { + TYPE_WIFI -> NETWORK_STATUS_WIFI + TYPE_MOBILE -> NETWORK_STATUS_MOBILE + TYPE_NOT_CONNECTED -> NETWORK_STATUS_NOT_CONNECTED + else -> NETWORK_STATUS_NOT_CONNECTED + } + } +} diff --git a/app/src/main/java/com/uzlov/moviefind/services/SampleService.kt b/app/src/main/java/com/uzlov/moviefind/services/SampleService.kt new file mode 100644 index 0000000..5607a4b --- /dev/null +++ b/app/src/main/java/com/uzlov/moviefind/services/SampleService.kt @@ -0,0 +1,62 @@ +package com.uzlov.moviefind.services + +import android.app.* +import android.content.Intent +import android.os.Build +import android.os.IBinder +import android.util.Log +import androidx.core.app.NotificationCompat +import com.uzlov.moviefind.HostActivity +import com.uzlov.moviefind.R + +class SampleService : Service() { + private val CHANNEL_ID: String = "ForegroundServiceChannel" + + companion object{ + val VALUE_KEY: String = "sample_key" + val ACTION = "ACTION_SAMPLE_SERVICE" + } + + override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { + createNotificationChannel() + val notificationIntent = Intent(this, HostActivity::class.java) + val pendingIntent = PendingIntent.getActivity(this, + 0, notificationIntent, 0) + val notification: Notification = NotificationCompat.Builder(this, CHANNEL_ID) + .setContentTitle(getString(R.string.funny_string)) + .setSmallIcon(R.drawable.ic_baseline_favorite_border_24) + .setContentIntent(pendingIntent) + .build() + startForeground(1, notification) + + Thread { + for (i in 0..5){ + Thread.sleep(1000) + val data = Intent().apply { + putExtra(VALUE_KEY, (i % 2 == 0).toString()) + action = ACTION + } + sendBroadcast(data) + if (i == 4) stopSelf() + } + }.start() + + return START_STICKY + } + + private fun createNotificationChannel() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val serviceChannel = NotificationChannel( + CHANNEL_ID, + getString(R.string.string_from_moviefind), + NotificationManager.IMPORTANCE_DEFAULT + ) + val manager = getSystemService(NotificationManager::class.java) + manager.createNotificationChannel(serviceChannel) + } + } + + override fun onBind(p0: Intent?): IBinder? { + return null + } +} \ No newline at end of file