handling no internet situations

This commit is contained in:
leca 2024-11-12 17:57:45 +03:00
parent ec7062602d
commit d08a79e981
9 changed files with 220 additions and 90 deletions

View File

@ -13,6 +13,7 @@
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:allowBackup="true"

View File

@ -1,5 +1,6 @@
package org.foxarmy.barcodescannerforemployees
import android.content.Context
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
@ -17,6 +18,28 @@ class Net {
var server = "bsfe.foxarmy.org"
var token = ""
fun serverIsAvailable(context: Context): Boolean {
if (!isInternetConnectionAvailable(context)) {
return false
}
var flag = false
thread {
val client = OkHttpClient();
val request = Request.Builder()
.url("https://$server/status")
.get()
.build();
try {
val response = client.newCall(request).execute();
flag = response.code == 200;
} catch (e: Exception) {
flag = false;
}
}.join()
return flag
}
fun requestProductFromOnlineDB(barcode: String): String {
var response = ""
thread {

View File

@ -7,10 +7,15 @@ import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Matrix
import android.media.ExifInterface
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.net.Uri
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog
import androidx.core.content.FileProvider
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKeys
import com.google.firebase.components.BuildConfig
import java.io.File
import java.io.FileInputStream
@ -18,6 +23,7 @@ import java.io.FileOutputStream
import java.security.MessageDigest
import java.text.SimpleDateFormat
import java.util.*
import kotlin.system.exitProcess
fun convertToUnixEpochTimestamp(dateString: String): Long {
val format = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
@ -27,7 +33,11 @@ fun convertToUnixEpochTimestamp(dateString: String): Long {
}
fun getImageUri(activity: Activity, imageFile: File): Uri? {
return FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + "." + activity.localClassName + ".provider", imageFile)
return FileProvider.getUriForFile(
activity,
BuildConfig.APPLICATION_ID + "." + activity.localClassName + ".provider",
imageFile
)
}
@RequiresApi(Build.VERSION_CODES.R)
@ -65,7 +75,10 @@ fun String.md5(): String {
}
fun stripNetWeight(netWeight: String): Double {
return removeSubstringsFromString(netWeight, arrayOf("Л", "л", "мл", "Мл", "г", "Г", "кг", "Кг", "шт", "Шт", ",", " ", ".")).toDouble()
return removeSubstringsFromString(
netWeight,
arrayOf("Л", "л", "мл", "Мл", "г", "Г", "кг", "Кг", "шт", "Шт", ",", " ", ".")
).toDouble()
}
fun removeSubstringsFromString(text: String, toRemove: Array<String>): String {
@ -101,12 +114,29 @@ fun calculateProductFreshness(dateOfProduction: Long, dateOfExpiry: Long): Doubl
fun getUnitNameById(context: Context, id: Int): String {
return when (id) {
0 -> { context.getString(R.string.kilogram) }
1 -> { context.getString(R.string.gram) }
2 -> { context.getString(R.string.liter) }
3 -> { context.getString(R.string.milliliter) }
4 -> { context.getString(R.string.pieces) }
else -> { "" }
0 -> {
context.getString(R.string.kilogram)
}
1 -> {
context.getString(R.string.gram)
}
2 -> {
context.getString(R.string.liter)
}
3 -> {
context.getString(R.string.milliliter)
}
4 -> {
context.getString(R.string.pieces)
}
else -> {
""
}
}
}
@ -138,3 +168,46 @@ fun bytesToHex(bytes: ByteArray): String {
}
return hexString.toString()
}
fun isInternetConnectionAvailable(context: Context): Boolean {
if (context.getSystemService(Context.CONNECTIVITY_SERVICE) == null) return false
val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (connectivityManager != null) {
val capabilities =
connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
if (capabilities != null) {
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
return true
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
return true
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
return true
}
}
}
return false
}
fun noInternetConnectionAvailableNotification(context: Context) {
AlertDialog.Builder(context)
.setMessage(context.getString(R.string.no_internet_connection))
.setPositiveButton(R.string.quit) { _, _ ->
exitProcess(0)
}
.setNeutralButton(R.string.logout) { _, _ ->
val sharedPreferences = EncryptedSharedPreferences.create(
"sensitive",
MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
context,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
sharedPreferences.edit().putString("token", "").apply()
sharedPreferences.edit().putString("server", "").apply()
sharedPreferences.edit().putStringSet("groups", emptySet()).apply()
sharedPreferences.edit().putString("currentGroup", "").apply()
exitProcess(0)
}.show()
}

View File

@ -8,6 +8,7 @@ import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKeys
import org.foxarmy.barcodescannerforemployees.Net
import org.foxarmy.barcodescannerforemployees.databinding.ActivityGroupBinding
import org.foxarmy.barcodescannerforemployees.noInternetConnectionAvailableNotification
class GroupActivity : AppCompatActivity() {
@ -31,12 +32,15 @@ class GroupActivity : AppCompatActivity() {
val groupName = binding.groupNameTextEdit.text.toString()
val groupPassword = binding.groupPasswordTextEdit.text.toString()
// group is set to "successful"
val n = Net()
n.language = sharedPreferences.getString("language", "en-US")!!
n.server = sharedPreferences.getString("server", "")!!
n.token = sharedPreferences.getString("token", "")!!
val net = Net()
net.language = sharedPreferences.getString("language", "en-US")!!
net.server = sharedPreferences.getString("server", "")!!
net.token = sharedPreferences.getString("token", "")!!
val response = n.createGroup(groupName, groupPassword)
if (!net.serverIsAvailable(this)) {
noInternetConnectionAvailableNotification(this)
} else {
val response = net.createGroup(groupName, groupPassword)
val responseText = response.body!!.string()
if (response.code == 200) {
@ -51,18 +55,22 @@ class GroupActivity : AppCompatActivity() {
Toast.makeText(this, responseText, Toast.LENGTH_LONG).show()
}
}
}
binding.joinGroupButton.setOnClickListener {
val groupName = binding.groupNameTextEdit.text.toString()
val groupPassword = binding.groupPasswordTextEdit.text.toString()
val n = Net()
n.language = sharedPreferences.getString("language", "en-US")!!
n.server = sharedPreferences.getString("server", "")!!
n.token = sharedPreferences.getString("token", "")!!
val net = Net()
net.language = sharedPreferences.getString("language", "en-US")!!
net.server = sharedPreferences.getString("server", "")!!
net.token = sharedPreferences.getString("token", "")!!
val groupId = n.getGroupId(groupName).toInt()
val response = n.joinGroup(groupId, groupPassword)
if (!net.serverIsAvailable(this)) {
noInternetConnectionAvailableNotification(this)
} else {
val groupId = net.getGroupId(groupName).toInt()
val response = net.joinGroup(groupId, groupPassword)
val responseText = response.body!!.string()
if (response.code == 200) {
@ -79,3 +87,4 @@ class GroupActivity : AppCompatActivity() {
}
}
}
}

View File

@ -10,6 +10,7 @@ import androidx.security.crypto.MasterKeys
import org.foxarmy.barcodescannerforemployees.Net
import org.foxarmy.barcodescannerforemployees.R
import org.foxarmy.barcodescannerforemployees.databinding.ActivityLoginBinding
import org.foxarmy.barcodescannerforemployees.noInternetConnectionAvailableNotification
import org.foxarmy.barcodescannerforemployees.parseArray
import org.json.JSONObject
@ -40,23 +41,26 @@ class LoginActivity : AppCompatActivity() {
val language = resources.getStringArray(R.array.languages)[binding.languageSpinner.selectedItemPosition]
sharedPreferences.edit().putString("language", language).apply()
val n = Net()
n.language = sharedPreferences.getString("language", "en-US")!!
n.server = server
val net = Net()
net.language = sharedPreferences.getString("language", "en-US")!!
net.server = server
val response = n.login(username, password)
if (!net.serverIsAvailable(this)) {
noInternetConnectionAvailableNotification(this)
} else {
val response = net.login(username, password)
val responseText = response.body!!.string()
if (response.code != 200) {
Toast.makeText(this, responseText, Toast.LENGTH_SHORT).show()
} else {
val json = JSONObject(responseText)
sharedPreferences.edit().putString("token", json["token"].toString()).apply()
n.token = json["token"].toString()
net.token = json["token"].toString()
sharedPreferences.edit().putInt("userId", json["id"].toString().toInt()).apply()
sharedPreferences.edit().putString("server", server).apply()
val r = n.getMyGroups().body!!.string()
val r = net.getMyGroups().body!!.string()
val myGroups = parseArray(r).map { a -> a.toString()}
sharedPreferences.edit().putStringSet("groups", myGroups.toSet()).apply()
@ -67,6 +71,7 @@ class LoginActivity : AppCompatActivity() {
finish()
}
}
}
binding.registerButton.setOnClickListener {
val server = binding.serverTextEdit.text.toString()
@ -76,16 +81,20 @@ class LoginActivity : AppCompatActivity() {
sharedPreferences.edit().putString("language", language).apply()
sharedPreferences.edit().putString("server", server).apply()
val n = Net()
n.language = language
n.server = server
val response = n.registerAccount(username, password);
val net = Net()
net.language = language
net.server = server
if (!net.serverIsAvailable(this)) {
noInternetConnectionAvailableNotification(this)
} else {
val response = net.registerAccount(username, password);
val responseText = response.body!!.string()
if (response.code != 200) {
Toast.makeText(this, responseText, Toast.LENGTH_SHORT).show();
} else {
sharedPreferences.edit().putInt("userId", responseText.toInt()).apply()
val token = JSONObject(n.login(username, password).body!!.string())["token"].toString()
val token = JSONObject(net.login(username, password).body!!.string())["token"].toString()
sharedPreferences.edit().putString("token", token).apply()
sharedPreferences.edit().putString("server", server).apply()
@ -95,6 +104,7 @@ class LoginActivity : AppCompatActivity() {
}
}
}
}
private fun fillUpLanguagesSpinner() {
val languages = resources.getStringArray(R.array.languages)

View File

@ -16,10 +16,7 @@ import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKeys
import androidx.viewpager.widget.ViewPager
import com.google.android.material.navigation.NavigationView
import org.foxarmy.barcodescannerforemployees.Net
import org.foxarmy.barcodescannerforemployees.R
import org.foxarmy.barcodescannerforemployees.ViewPagerAdapter
import org.foxarmy.barcodescannerforemployees.convertToUnixEpochTimestamp
import org.foxarmy.barcodescannerforemployees.*
import org.foxarmy.barcodescannerforemployees.database.AbstractProductDAO
import org.foxarmy.barcodescannerforemployees.database.CategoryDAO
import org.foxarmy.barcodescannerforemployees.database.DBStorageController
@ -60,9 +57,16 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
actionBarDrawerToggle!!.syncState()
binding.navView.setNavigationItemSelectedListener(this)
// to make the Navigation drawer icon always appear on the action bar
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
val sharedPreferences = EncryptedSharedPreferences.create(
"sensitive",
MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
applicationContext,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
binding.expiryCalendarFab.setOnClickListener { _ ->
val expiryCalendarIntent = Intent(this, ExpiryCalendarActivity::class.java)
val extras = Bundle()
@ -78,8 +82,6 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
"StorageFragment" -> {
val addAbstractProductIntent = Intent(this, AddAbstractProductActivity::class.java)
val extras = Bundle()
// I reuse the same stuff for editing and adding new product.
// if abstractProduct == null, it means that we need to create new object
extras.putParcelable("abstractProduct", null)
extras.putString("action", "new")
addAbstractProductIntent.putExtras(extras)
@ -104,8 +106,15 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
}
}
}
val net = Net()
net.server = sharedPreferences.getString("server", "")!!
if (!net.serverIsAvailable(this)) {
noInternetConnectionAvailableNotification(this)
} else {
synchronize()
}
}
private fun synchronize() {

View File

@ -32,7 +32,6 @@ class NavigatorActivity : Activity() {
intent = Intent(this, LoginActivity::class.java);
}
startActivity(intent);
finish();
}

View File

@ -114,6 +114,9 @@
<string name="image_compress_factor">Степень сжатия изображения</string>
<string name="current_group">Текущая группа</string>
<string name="cancel">Отмена</string>
<string name="no_internet_connection">No internet connection available. Please, connect to a network.</string>
<string name="ok">Ok</string>
<string name="logout">Log out</string>
<string-array name="languages">
<item>en-US</item>
<item>ru-RU</item>

View File

@ -112,6 +112,9 @@
<string name="image_compress_factor">Image compression factor</string>
<string name="current_group">Current group</string>
<string name="cancel">Cancel</string>
<string name="no_internet_connection">No internet connection available. Please, connect to a network.</string>
<string name="ok">Ok</string>
<string name="logout">Log out</string>
<string-array name="languages">
<item>en-US</item>
<item>ru-RU</item>