Internet check

This commit is contained in:
Universall 2025-02-20 10:59:21 +03:00
parent a9e9bdf257
commit 1102451210
10 changed files with 200 additions and 51 deletions

View File

@ -7,6 +7,7 @@
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application <application
android:allowBackup="true" android:allowBackup="true"
android:name="com.displaynone.ACSSApplication" android:name="com.displaynone.ACSSApplication"

View File

@ -4,72 +4,65 @@ import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.annotation.IdRes
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.NavigationUI import androidx.navigation.ui.NavigationUI
import com.displaynone.acss.components.auth.models.user.UserServiceST import com.displaynone.acss.components.auth.models.user.UserServiceST
import com.displaynone.acss.components.auth.models.user.repository.dto.UserDTO
import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.bottomnavigation.BottomNavigationView
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_main) setupUI()
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> setupNavigation()
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
} }
val navController: NavController = this.setupNavigation() private fun setupNavigation() {
if(isUserAuthenticated()) { navigateTo(navController, R.id.action_nav_main_to_nav_profile)} else {navigateTo(navController, R.id.action_nav_main_to_nav_auth)}
}
fun navigateTo(navController: NavController, @IdRes actionId: Int) {
navController.navigate(actionId)
}
private fun setupNavigation(): NavController {
val navView = findViewById<BottomNavigationView>(R.id.bottom_navigation) val navView = findViewById<BottomNavigationView>(R.id.bottom_navigation)
val toolbar = findViewById<Toolbar>(R.id.toolbar); val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as? NavHostFragment val navHostFragment =
if (navHostFragment == null){ supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as? NavHostFragment
throw IllegalStateException("NavHostFragment is null") ?: throw IllegalStateException("NavHostFragment is null")
}
val navController = navHostFragment.navController val navController = navHostFragment.navController
val appBarConfiguration = AppBarConfiguration(setOf(R.id.nav_auth,R.id.nav_scan, R.id.nav_profile, R.id.nav_admin)) val appBarConfiguration = AppBarConfiguration(
setOf(R.id.nav_auth, R.id.nav_scan, R.id.nav_profile, R.id.nav_admin)
)
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration) NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration)
NavigationUI.setupWithNavController(navView, navController) NavigationUI.setupWithNavController(navView, navController)
navController.addOnDestinationChangedListener { _, destination, _ -> navController.addOnDestinationChangedListener { _, destination, _ ->
Log.d("Navigate", "Navigate to " + destination.label) Log.d("Navigate", "Navigate to " + destination.label)
navView.visibility = if (destination.id == R.id.nav_auth) View.GONE else View.VISIBLE navView.visibility = if (destination.id == R.id.nav_auth || destination.id == R.id.nav_init) View.GONE else View.VISIBLE
val userDTO = UserServiceST.getInstance().getUserDTO()
val userDTO = getCachedUser()
if (userDTO != null) { if (userDTO != null) {
if (!userDTO.roles.any { it.name == "ROLE_ADMIN" }) navView.menu.findItem(R.id.nav_admin) if (!userDTO.roles.any { it.name == "ROLE_ADMIN" }) navView.menu.findItem(R.id.nav_admin)
.setVisible(false) else navView.menu.findItem(R.id.nav_admin).setVisible(true) .setVisible(false) else navView.menu.findItem(R.id.nav_admin).setVisible(true)
} }
} }
return navController
} }
private fun isUserAuthenticated(): Boolean { private fun getCachedUser(): UserDTO? {
return UserServiceST.getInstance().hasTokens() return UserServiceST.getInstance().getUserDTO();
}
private fun checkForAdmin() {
val userDTO = UserServiceST.getInstance().getUserDTO()
if (userDTO != null){
if (userDTO.roles.any {it.name == "ROLE_ADMIN"}) {
Log.d("adminlog", "i'm admin")
} }
private fun setupUI() {
enableEdgeToEdge()
setContentView(R.layout.activity_main)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
} }
} }
} }

View File

@ -0,0 +1,22 @@
package com.displaynone.acss.components.main.utils
import com.displaynone.acss.config.Constants.serverUrl
import com.displaynone.acss.config.Network
import io.ktor.client.request.get
import io.ktor.client.request.headers
import io.ktor.http.HttpHeaders
import io.ktor.http.HttpStatusCode
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
suspend fun pingServer(token: String): Result<Boolean> = withContext(Dispatchers.IO) {
runCatching {
val result = Network.client.get("$serverUrl/api/ping") {
headers {
append(HttpHeaders.Authorization, "Bearer $token")
}
}
result.status == HttpStatusCode.OK
}
}

View File

@ -0,0 +1,94 @@
package com.displaynone.acss.ui.init
import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import androidx.navigation.fragment.findNavController
import com.displaynone.acss.R
import com.displaynone.acss.components.auth.models.user.UserServiceST
import com.displaynone.acss.components.auth.models.user.repository.dto.UserDTO
import com.displaynone.acss.databinding.FragmentInitBinding
import com.displaynone.acss.util.navigateTo
class InitFragment : Fragment(R.layout.fragment_init) {
private var _binding: FragmentInitBinding? = null
private val binding: FragmentInitBinding get() = _binding!!
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentInitBinding.bind(view)
if (!checkInternetConnection()) {
handleError(R.string.noInternet)
return
}
if (!pingServer()) {
handleError(R.string.serverIsUnabailable)
return
}
val navController: NavController = findNavController()
if (!isUserAuthenticated()) {
navigateTo(navController, R.id.action_nav_init_to_nav_auth)
return
}
val user: UserDTO? = updateUser()
if (user == null) {
navigateTo(navController, R.id.action_nav_init_to_nav_auth)
return
}
navigateTo(navController, R.id.action_nav_init_to_nav_profile)
}
private fun pingServer(): Boolean {
return true
}
private fun updateUser(): UserDTO? {
return null
}
private fun checkInternetConnection(): Boolean {
if (context == null) return false;
val connectivityManager =
context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val capabilities =
connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
?: return false
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
Log.i("Internet", "NetworkCapabilities.TRANSPORT_CELLULAR")
return true
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
Log.i("Internet", "NetworkCapabilities.TRANSPORT_WIFI")
return true
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
Log.i("Internet", "NetworkCapabilities.TRANSPORT_ETHERNET")
return true
}
return false
}
private fun getCachedUser(): UserDTO? {
return UserServiceST.getInstance().getUserDTO();
}
private fun isUserAuthenticated(): Boolean {
return UserServiceST.getInstance().hasTokens()
}
private fun handleError(string: Int) {
binding.error.text = requireContext().getString(string)
}
}

View File

@ -0,0 +1,14 @@
package com.displaynone.acss.ui.init
import androidx.lifecycle.ViewModel
import com.displaynone.acss.components.auth.models.user.repository.dto.UserDTO
class InitFragmentViewModel: ViewModel() {
private fun pingServer(): Boolean {
}
private fun updateUser(): UserDTO? {
}
}

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/error"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="24sp"
android:letterSpacing="0.05"
android:background="?android:attr/colorBackground"
android:textColor="?attr/colorOnBackground"
tools:text="@string/noInternet"
tools:ignore="MissingConstraints" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -2,7 +2,18 @@
<navigation xmlns:android="http://schemas.android.com/apk/res/android" <navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
app:startDestination="@id/nav_auth"> app:startDestination="@id/nav_init">
<fragment
android:id="@+id/nav_init"
android:name="com.displaynone.acss.ui.init.InitFragment"
android:label="InitFragment">
<action
android:id="@+id/action_nav_init_to_nav_profile"
app:destination="@id/nav_profile" />
<action
android:id="@+id/action_nav_init_to_nav_auth"
app:destination="@id/nav_auth" />
</fragment>
<fragment <fragment
android:id="@+id/nav_profile" android:id="@+id/nav_profile"
android:name="com.displaynone.acss.ui.profile.ProfileFragment" android:name="com.displaynone.acss.ui.profile.ProfileFragment"
@ -21,14 +32,6 @@
android:id="@+id/action_profileFragment_to_adminFragment" android:id="@+id/action_profileFragment_to_adminFragment"
app:destination="@id/nav_admin" /> app:destination="@id/nav_admin" />
</fragment> </fragment>
<action
android:id="@+id/action_nav_main_to_nav_profile"
app:destination="@id/nav_profile" />
<action
android:id="@+id/action_nav_main_to_nav_auth"
app:destination="@id/nav_auth" />
<fragment <fragment
android:id="@+id/nav_auth" android:id="@+id/nav_auth"
android:name="com.displaynone.acss.ui.auth.AuthFragment" android:name="com.displaynone.acss.ui.auth.AuthFragment"

View File

@ -19,5 +19,5 @@
<string name="title_profile">Your profile</string> <string name="title_profile">Your profile</string>
<string name="сhange_rights">Change rights using smartphone</string> <string name="сhange_rights">Change rights using smartphone</string>
<string name="admin">Admin panel</string> <string name="admin">Admin panel</string>
<string name="noInternet">Internet disconnected</string>
</resources> </resources>

View File

@ -19,5 +19,6 @@
<string name="administrator_searc_button_search">🔍 Поиск 🔍</string> <string name="administrator_searc_button_search">🔍 Поиск 🔍</string>
<string name="title_profile">Профиль</string> <string name="title_profile">Профиль</string>
<string name="сhange_rights">Изменить права входа с помощью смартфона</string> <string name="сhange_rights">Изменить права входа с помощью смартфона</string>
><string name="admin">Панель администратора</string> <string name="admin">Панель администратора</string>
<string name="noInternet">Интернет соединение потеряно</string>
</resources> </resources>

View File

@ -20,6 +20,6 @@
<string name="сhange_rights">Change rights using smartphone</string> <string name="сhange_rights">Change rights using smartphone</string>
<string name="admin">Admin panel</string> <string name="admin">Admin panel</string>
<string name="profile">Profile</string> <string name="profile">Profile</string>
<string name="noInternet">Internet disconnected</string>
<string name="serverIsUnabailable">Server is unavailable</string>
</resources> </resources>