diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e53f2de20d9ab02a31d7164600506b4a2d7821fc..e52baae0b52c0d7b23950ee6472a45ee56941c00 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -11,6 +11,9 @@ android:roundIcon="@mipmap/ic_primary_logo_round" android:supportsRtl="true" android:theme="@style/Theme.NerbOS"> + + <service android:name=".service.NetworkManagerService" /> + <service android:name=".service.TokenCheckService" android:enabled="true" @@ -22,10 +25,10 @@ android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> - <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> + <activity android:name=".MainActivity" android:exported="true" /> diff --git a/app/src/main/java/com/example/nerbos/MainActivity.kt b/app/src/main/java/com/example/nerbos/MainActivity.kt index 2589404a14528e550bf4a99b500553cafa1f28e2..6d8eeeff1eb15860623002c357be67c0256fa461 100644 --- a/app/src/main/java/com/example/nerbos/MainActivity.kt +++ b/app/src/main/java/com/example/nerbos/MainActivity.kt @@ -10,7 +10,7 @@ import com.example.nerbos.fragments.scan.ScanFragment import com.example.nerbos.fragments.statistic.StatisticFragment import com.example.nerbos.fragments.transaction.TransactionFragment import com.example.nerbos.fragments.user.UserFragment -import com.example.nerbos.service.NetworkManager +import com.example.nerbos.service.NetworkManagerService import com.example.nerbos.service.TokenCheckService class MainActivity : AppCompatActivity() { @@ -30,15 +30,17 @@ class MainActivity : AppCompatActivity() { private var selectedItemId: Int = R.id.transaction internal lateinit var binding: ActivityMainBinding - internal lateinit var networkManager: NetworkManager + internal var networkManagerService: NetworkManagerService = NetworkManagerService() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + instance = this binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) setSupportActionBar(binding.toolbar) - networkManager = NetworkManager(this) + // Start the NetworkManagerService to monitor network changes + startService(Intent(this, NetworkManagerService::class.java)) // Start the TokenCheckService to check token validity val serviceIntent = Intent(this, TokenCheckService::class.java) @@ -55,6 +57,11 @@ class MainActivity : AppCompatActivity() { selectMenuItem(selectedItemId) } + override fun onDestroy() { + super.onDestroy() + instance = null + } + private fun setupNavigation() { if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) { binding.bottomNavigationView?.setOnItemSelectedListener { item -> @@ -93,11 +100,6 @@ class MainActivity : AppCompatActivity() { super.onSaveInstanceState(outState) } - override fun onDestroy() { - super.onDestroy() - networkManager.unregisterNetworkCallback() - } - fun getCurrentFragmentId(): Int { return selectedItemId } @@ -109,4 +111,12 @@ class MainActivity : AppCompatActivity() { fun getTitleFromId(id: Int): Int { return fragmentTitles[id] ?: R.string.navbar_transaction } + + companion object { + private var instance: MainActivity? = null + + fun getInstance(): MainActivity? { + return instance + } + } } diff --git a/app/src/main/java/com/example/nerbos/fragments/network/NoInternetFragment.kt b/app/src/main/java/com/example/nerbos/fragments/network/NoInternetFragment.kt index a0a708b71e17e81c03052a2ef88d21f1fe43e474..e9b20570df7e347dda7865b4d0dbeda2820e50d5 100644 --- a/app/src/main/java/com/example/nerbos/fragments/network/NoInternetFragment.kt +++ b/app/src/main/java/com/example/nerbos/fragments/network/NoInternetFragment.kt @@ -26,7 +26,7 @@ class NoInternetFragment : Fragment() { binding.closeButton.setOnClickListener { val mainActivity = requireActivity() as MainActivity - mainActivity.networkManager.handleCloseButtonClick() + mainActivity.networkManagerService.handleCloseButtonClick(mainActivity) } } diff --git a/app/src/main/java/com/example/nerbos/service/NetworkManager.kt b/app/src/main/java/com/example/nerbos/service/NetworkManager.kt deleted file mode 100644 index ba34a779aa7cf49219fb79718827ac60de7ea3f6..0000000000000000000000000000000000000000 --- a/app/src/main/java/com/example/nerbos/service/NetworkManager.kt +++ /dev/null @@ -1,95 +0,0 @@ -package com.example.nerbos.service - -import android.content.Context -import android.content.res.Configuration -import android.net.ConnectivityManager -import android.net.Network -import android.view.View -import android.widget.Toast -import com.example.nerbos.MainActivity -import com.example.nerbos.R -import com.example.nerbos.fragments.network.NoInternetFragment - -class NetworkManager(private val context: Context) { - - private val connectivityManager: ConnectivityManager = - context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager - private var isInternetAvailable = false - - private val networkCallback = object : ConnectivityManager.NetworkCallback() { - override fun onAvailable(network: Network) { - isInternetAvailable = true - handleNetworkChanges() - } - - override fun onLost(network: Network) { - isInternetAvailable = false - handleNetworkChanges() - } - } - - init { - // Register network callback to monitor network changes - connectivityManager.registerDefaultNetworkCallback(networkCallback) - } - - fun unregisterNetworkCallback() { - // Unregister the network callback when the activity is destroyed - connectivityManager.unregisterNetworkCallback(networkCallback) - } - - private fun handleNetworkChanges() { - val mainActivity = context as MainActivity - val currentFragmentId = mainActivity.getCurrentFragmentId() - - if (!isInternetAvailable) { - // If not connected to the internet, show NoInternetFragment and hide ActionBar and BottomNavigationView - mainActivity.runOnUiThread { - Toast.makeText(context, "No internet connection", Toast.LENGTH_SHORT).show() - showNoInternetFragment(mainActivity) - hideActionBarAndNavBar(mainActivity) - } - } else { - // If internet is available and NoInternetFragment is visible, replace with the appropriate fragment and show ActionBar and BottomNavigationView - if (mainActivity.supportFragmentManager.findFragmentById(R.id.frameLayout) is NoInternetFragment) { - Toast.makeText(context, "Connected to the internet", Toast.LENGTH_SHORT).show() - mainActivity.runOnUiThread { - mainActivity.replaceFragment(mainActivity.getFragmentFromId(currentFragmentId)) // Reinflate the previous fragment - mainActivity.supportActionBar?.title = - context.getString(mainActivity.getTitleFromId(currentFragmentId)) // Reinflate the previous fragment's title - showActionBarAndNavBar(mainActivity) - } - } - } - } - - private fun showNoInternetFragment(mainActivity: MainActivity) { - // Show NoInternetFragment - mainActivity.replaceFragment(NoInternetFragment()) - } - - private fun hideActionBarAndNavBar(mainActivity: MainActivity) { - mainActivity.supportActionBar?.hide() - mainActivity.binding.bottomNavigationView?.visibility = View.GONE - mainActivity.binding.navigationView?.visibility = View.GONE - } - - private fun showActionBarAndNavBar(mainActivity: MainActivity) { - mainActivity.supportActionBar?.show() - if (mainActivity.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) { - mainActivity.binding.bottomNavigationView?.visibility = View.VISIBLE - } else { - mainActivity.binding.navigationView?.visibility = View.VISIBLE - } - } - - fun handleCloseButtonClick() { - val mainActivity = context as MainActivity - val currentFragmentId = mainActivity.getCurrentFragmentId() - mainActivity.runOnUiThread { - mainActivity.replaceFragment(mainActivity.getFragmentFromId(currentFragmentId)) - mainActivity.supportActionBar?.title = context.getString(mainActivity.getTitleFromId(currentFragmentId)) - showActionBarAndNavBar(mainActivity) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/nerbos/service/NetworkManagerService.kt b/app/src/main/java/com/example/nerbos/service/NetworkManagerService.kt new file mode 100644 index 0000000000000000000000000000000000000000..efe66c38c960c6785b01b9462555458bad58f0cd --- /dev/null +++ b/app/src/main/java/com/example/nerbos/service/NetworkManagerService.kt @@ -0,0 +1,121 @@ +package com.example.nerbos.service + +import android.app.Service +import android.content.Context +import android.content.Intent +import android.content.res.Configuration +import android.net.ConnectivityManager +import android.net.Network +import android.os.Binder +import android.os.Handler +import android.os.IBinder +import android.os.Looper +import android.view.View +import android.widget.Toast +import com.example.nerbos.MainActivity +import com.example.nerbos.R +import com.example.nerbos.fragments.network.NoInternetFragment + +class NetworkManagerService : Service() { + + private lateinit var connectivityManager: ConnectivityManager + private val binder = LocalBinder() + + inner class LocalBinder : Binder() + + override fun onBind(intent: Intent?): IBinder { + return binder + } + + override fun onCreate() { + super.onCreate() + connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + startNetworkMonitoring() + } + + private fun startNetworkMonitoring() { + val handler = Handler(Looper.getMainLooper()) + handler.post { + connectivityManager.registerDefaultNetworkCallback(object : ConnectivityManager.NetworkCallback() { + override fun onAvailable(network: Network) { + handler.post { + showNetworkToast("Connected to the internet") + handleNetworkChanges(true) + } + } + + override fun onLost(network: Network) { + handler.post { + showNetworkToast("No internet connection") + handleNetworkChanges(false) + } + } + }) + } + } + + private fun showNetworkToast(message: String) { + // Use application context for Toast since services don't have UI context + Toast.makeText(applicationContext, message, Toast.LENGTH_SHORT).show() + } + + fun handleNetworkChanges(isInternetAvailable: Boolean) { + val mainActivity = MainActivity.getInstance() + + if (mainActivity != null) { + val currentFragmentId = mainActivity.getCurrentFragmentId() + val fragmentManager = mainActivity.supportFragmentManager + + if (!isInternetAvailable) { + // If not connected to the internet, show NoInternetFragment and hide ActionBar and BottomNavigationView + mainActivity.runOnUiThread { + showNoInternetFragment(mainActivity) + hideActionBarAndNavBar(mainActivity) + } + } else { + // If internet is available and NoInternetFragment is visible, replace with the appropriate fragment and show ActionBar and BottomNavigationView + if (fragmentManager.findFragmentById(R.id.frameLayout) is NoInternetFragment) { + mainActivity.runOnUiThread { + mainActivity.replaceFragment( + mainActivity.getFragmentFromId(currentFragmentId), + ) // Reinflate the previous fragment + mainActivity.supportActionBar?.title = applicationContext.getString(mainActivity.getTitleFromId(currentFragmentId)) // Reinflate the previous fragment's title + showActionBarAndNavBar(mainActivity) + } + } + } + } + } + + private fun showNoInternetFragment(mainActivity: MainActivity) { + // Show NoInternetFragment + val noInternetFragment = NoInternetFragment() + mainActivity.replaceFragment(noInternetFragment) + } + + private fun hideActionBarAndNavBar(mainActivity: MainActivity) { + mainActivity.supportActionBar?.hide() + mainActivity.binding.bottomNavigationView?.visibility = View.GONE + mainActivity.binding.navigationView?.visibility = View.GONE + } + + private fun showActionBarAndNavBar(mainActivity: MainActivity) { + mainActivity.supportActionBar?.show() + if (mainActivity.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) { + mainActivity.binding.bottomNavigationView?.visibility = View.VISIBLE + } else { + mainActivity.binding.navigationView?.visibility = View.VISIBLE + } + } + + fun handleCloseButtonClick(mainActivity: MainActivity) { + val currentFragmentId = mainActivity.getCurrentFragmentId() + mainActivity.runOnUiThread { + mainActivity.replaceFragment( + mainActivity.getFragmentFromId(currentFragmentId), + ) // Reinflate the previous fragment + mainActivity.supportActionBar?.title = mainActivity.getString(mainActivity.getTitleFromId(currentFragmentId)) // Reinflate the previous fragment's title + } + showActionBarAndNavBar(mainActivity) + } +} \ No newline at end of file