diff --git a/networksurvey/src/main/java/com/craxiom/networksurvey/fragments/CalculatorFragment.java b/networksurvey/src/main/java/com/craxiom/networksurvey/fragments/CalculatorFragment.java deleted file mode 100644 index 62cc09de5..000000000 --- a/networksurvey/src/main/java/com/craxiom/networksurvey/fragments/CalculatorFragment.java +++ /dev/null @@ -1,273 +0,0 @@ -package com.craxiom.networksurvey.fragments; - -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.EditText; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.fragment.app.Fragment; - -import com.craxiom.networksurvey.R; -import com.craxiom.networksurvey.util.CalculationUtils; -import com.craxiom.networksurvey.util.CellularUtils; - -import timber.log.Timber; - -/** - * A fragment to hold the LTE eNodeB ID calculator. - * - * @since 0.0.2 - */ -public class CalculatorFragment extends Fragment -{ - static final String TITLE = "Calculators"; - private static final String INVALID_CELL_ID_MESSAGE = "Invalid Cell ID. Valid Range is 0 - 268435455"; - private static final String INVALID_PCI_MESSAGE = "Invalid PCI. Valid Range is 0 - 503"; - private static final String INVALID_EARFCN_MESSAGE = "Invalid EARFCN. Valid Range is 0 - 262143"; - - private View view; - - private final TextWatcher lteCellIdTextWatcher = new TextWatcher() - { - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) - { - final String enteredText = s.toString(); - try - { - if (enteredText.isEmpty()) - { - Timber.v("The entered text for the LTE Cell ID is empty. Can't calculate the eNodeB ID."); - clearCellIdCalculatedValues(); - return; - } - - final int cellId; - try - { - cellId = Integer.parseInt(enteredText); - } catch (Exception e) - { - showToast(INVALID_CELL_ID_MESSAGE); - clearCellIdCalculatedValues(); - return; - } - - if (!CalculationUtils.isLteCellIdValid(cellId)) - { - showToast(INVALID_CELL_ID_MESSAGE); - clearCellIdCalculatedValues(); - return; - } - - // The Cell Identity is 28 bits long. The first 20 bits represent the Macro eNodeB ID. The last 8 bits - // represent the sector. Strip off the last 8 bits to get the Macro eNodeB ID. - int eNodebId = CalculationUtils.getEnodebIdFromCellId(cellId); - ((TextView) view.findViewById(R.id.calculatedEnbIdValue)).setText(String.valueOf(eNodebId)); - - int sectorId = CalculationUtils.getSectorIdFromCellId(cellId); - ((TextView) view.findViewById(R.id.calculatedSectorIdValue)).setText(String.valueOf(sectorId)); - } catch (Exception e) - { - Timber.w(e, "Unable to parse the provide LTE Cell ID as an Integer:%s", enteredText); - } - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) - { - - } - - @Override - public void afterTextChanged(Editable s) - { - - } - }; - - private final TextWatcher ltePciTextWatcher = new TextWatcher() - { - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) - { - final String enteredText = s.toString(); - try - { - if (enteredText.isEmpty()) - { - Timber.v("The entered text for the LTE PCI is empty. Can't calculate the PSS and SSS."); - clearPciCalculatedValues(); - return; - } - - final int pci; - try - { - pci = Integer.parseInt(enteredText); - } catch (Exception e) - { - showToast(INVALID_PCI_MESSAGE); - clearPciCalculatedValues(); - return; - } - - if (pci < 0 || pci > 503) - { - showToast(INVALID_PCI_MESSAGE); - clearPciCalculatedValues(); - return; - } - - int primarySyncSequence = CalculationUtils.getPrimarySyncSequence(pci); - ((TextView) view.findViewById(R.id.calculatedPssValue)).setText(String.valueOf(primarySyncSequence)); - - int secondarySyncSequence = CalculationUtils.getSecondarySyncSequence(pci); - ((TextView) view.findViewById(R.id.calculatedSssValue)).setText(String.valueOf(secondarySyncSequence)); - } catch (Exception e) - { - Timber.w(e, "Unable to parse the provide LTE PCI as an Integer:%s", enteredText); - } - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) - { - - } - - @Override - public void afterTextChanged(Editable s) - { - - } - }; - - private final TextWatcher lteEarfcnTextWatcher = new TextWatcher() - { - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) - { - final String enteredText = s.toString(); - try - { - if (enteredText.isEmpty()) - { - Timber.v("The entered text for the LTE EARFCN is empty. Can't calculate the Band."); - clearEarfcnCalculatedValues(); - return; - } - - final int earfcn; - try - { - earfcn = Integer.parseInt(enteredText); - } catch (Exception e) - { - showToast(INVALID_EARFCN_MESSAGE); - clearEarfcnCalculatedValues(); - return; - } - - if (earfcn < 0 || earfcn > 262143) - { - showToast(INVALID_EARFCN_MESSAGE); - clearEarfcnCalculatedValues(); - return; - } - - int band = CellularUtils.downlinkEarfcnToBand(earfcn); - if (band == -1) - { - ((TextView) view.findViewById(R.id.calculatedBandValue)).setText("Unknown"); - } else - { - ((TextView) view.findViewById(R.id.calculatedBandValue)).setText(String.valueOf(band)); - } - } catch (Exception e) - { - Timber.w(e, "Unable to parse the provide LTE EARFCN as an Integer:%s", enteredText); - } - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) - { - - } - - @Override - public void afterTextChanged(Editable s) - { - - } - }; - - public CalculatorFragment() - { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) - { - // Inflate the layout for this fragment - view = inflater.inflate(R.layout.fragment_calculator, container, false); - - final EditText cellIdField = view.findViewById(R.id.lteCalculatorCellId); - cellIdField.addTextChangedListener(lteCellIdTextWatcher); - - final EditText pciField = view.findViewById(R.id.lteCalculatorPci); - pciField.addTextChangedListener(ltePciTextWatcher); - - final EditText earfcnField = view.findViewById(R.id.lteCalculatorEarfcn); - earfcnField.addTextChangedListener(lteEarfcnTextWatcher); - - return view; - } - - /** - * Sets the text in the Cell ID calculated TextView's to an empty string. - */ - private void clearCellIdCalculatedValues() - { - ((TextView) view.findViewById(R.id.calculatedEnbIdValue)).setText(""); - ((TextView) view.findViewById(R.id.calculatedSectorIdValue)).setText(""); - } - - /** - * Sets the text in the PCI calculated TextView's to an empty string. - */ - private void clearPciCalculatedValues() - { - ((TextView) view.findViewById(R.id.calculatedPssValue)).setText(""); - ((TextView) view.findViewById(R.id.calculatedSssValue)).setText(""); - } - - /** - * Sets the text in the Band calculated TextView to an empty string. - */ - private void clearEarfcnCalculatedValues() - { - ((TextView) view.findViewById(R.id.calculatedBandValue)).setText(""); - } - - /** - * Shows a short toast to the user with the provided message. - *
- * This method also logs a warning.
- *
- * @param toastMessage The message to show the user.
- */
- private void showToast(String toastMessage)
- {
- Timber.d(toastMessage);
- Toast.makeText(getActivity(), toastMessage, Toast.LENGTH_SHORT).show();
- }
-}
diff --git a/networksurvey/src/main/java/com/craxiom/networksurvey/ui/main/NsMainScreen.kt b/networksurvey/src/main/java/com/craxiom/networksurvey/ui/main/NsMainScreen.kt
index 5c3193ee0..c5761e107 100644
--- a/networksurvey/src/main/java/com/craxiom/networksurvey/ui/main/NsMainScreen.kt
+++ b/networksurvey/src/main/java/com/craxiom/networksurvey/ui/main/NsMainScreen.kt
@@ -1,5 +1,7 @@
package com.craxiom.networksurvey.ui.main
+import android.content.Intent
+import android.net.Uri
import androidx.activity.compose.BackHandler
import androidx.compose.material3.DrawerState
import androidx.compose.material3.DrawerValue
@@ -7,6 +9,7 @@ import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.Scaffold
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.navigation.NavController
import androidx.navigation.NavHostController
@@ -27,6 +30,7 @@ fun MainCompose(
appVersion: String
) {
// TODO Is this needed? HandleBackPress(navController)
+ val context = LocalContext.current
NsTheme {
Scaffold { paddingValues ->
@@ -37,6 +41,7 @@ fun MainCompose(
appVersion = appVersion,
drawerState = drawerState,
menuItems = DrawerParams.drawerButtons,
+ externalLinks = DrawerParams.externalDrawerLinks,
defaultPick = NavDrawerOption.None
) { onUserPickedOption ->
when (onUserPickedOption) {
@@ -69,6 +74,38 @@ fun MainCompose(
popUpTo(NavDrawerOption.None.name)
}
}
+
+ NavDrawerOption.UserManual -> {
+ val intent = Intent(
+ Intent.ACTION_VIEW,
+ Uri.parse("https://networksurvey.app/manual")
+ )
+ context.startActivity(intent)
+ }
+
+ NavDrawerOption.MessagingDocs -> {
+ val intent = Intent(
+ Intent.ACTION_VIEW,
+ Uri.parse("https://messaging.networksurvey.app/")
+ )
+ context.startActivity(intent)
+ }
+
+ NavDrawerOption.ReportAnIssue -> {
+ val intent = Intent(
+ Intent.ACTION_VIEW,
+ Uri.parse("https://github.com/christianrowlands/android-network-survey/issues/new/choose")
+ )
+ context.startActivity(intent)
+ }
+
+ NavDrawerOption.GitHub -> {
+ val intent = Intent(
+ Intent.ACTION_VIEW,
+ Uri.parse("https://github.com/christianrowlands/android-network-survey")
+ )
+ context.startActivity(intent)
+ }
}
}
}
@@ -101,7 +138,6 @@ enum class NavRoutes {
object DrawerParams {
val drawerButtons = arrayListOf(
- // TODO Update all of these
AppDrawerItemInfo(
NavDrawerOption.ServerConnection,
R.string.grpc_connection_title,
@@ -127,6 +163,33 @@ object DrawerParams {
R.string.device_status_stream_description
)
)
+
+ val externalDrawerLinks = arrayListOf(
+ AppDrawerItemInfo(
+ NavDrawerOption.UserManual,
+ R.string.manual,
+ R.drawable.ic_user_manual,
+ R.string.manual
+ ),
+ AppDrawerItemInfo(
+ NavDrawerOption.MessagingDocs,
+ R.string.messaging_docs,
+ R.drawable.ic_schema,
+ R.string.messaging_docs
+ ),
+ AppDrawerItemInfo(
+ NavDrawerOption.ReportAnIssue,
+ R.string.report_issue,
+ R.drawable.ic_bug,
+ R.string.report_issue
+ ),
+ AppDrawerItemInfo(
+ NavDrawerOption.GitHub,
+ R.string.github,
+ R.drawable.ic_github,
+ R.string.github
+ )
+ )
}
@Preview
diff --git a/networksurvey/src/main/java/com/craxiom/networksurvey/ui/main/appdrawer/AppDrawerContent.kt b/networksurvey/src/main/java/com/craxiom/networksurvey/ui/main/appdrawer/AppDrawerContent.kt
index 0e804d4a6..04ab2387b 100644
--- a/networksurvey/src/main/java/com/craxiom/networksurvey/ui/main/appdrawer/AppDrawerContent.kt
+++ b/networksurvey/src/main/java/com/craxiom/networksurvey/ui/main/appdrawer/AppDrawerContent.kt
@@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.DrawerState
+import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.Surface
@@ -26,6 +27,7 @@ fun