diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..aa724b7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..b589d56
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
new file mode 100644
index 0000000..0c0c338
--- /dev/null
+++ b/.idea/deploymentTargetDropDown.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..0897082
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/migrations.xml b/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..0ad17cb
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..285340c
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,48 @@
+plugins {
+ alias(libs.plugins.androidApplication)
+}
+
+android {
+ namespace 'org.nanick.nr5gperf'
+ compileSdk 34
+
+ defaultConfig {
+ applicationId "org.nanick.nr5gperf"
+ minSdk 33
+ targetSdk 34
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+dependencies {
+
+ implementation libs.appcompat
+ implementation libs.material
+ implementation libs.activity
+ implementation libs.constraintlayout
+ testImplementation libs.junit
+ androidTestImplementation libs.ext.junit
+ androidTestImplementation libs.espresso.core
+ implementation 'com.fasterxml.jackson.core:jackson-core:2.10.1'
+ implementation 'com.fasterxml.jackson.core:jackson-annotations:2.10.1'
+ implementation 'com.fasterxml.jackson.core:jackson-databind:2.10.1'
+ implementation group: 'commons-io', name: 'commons-io', version: '2.0.1'
+ implementation(platform("com.squareup.okhttp3:okhttp-bom:4.12.0"))
+ // define any required OkHttp artifacts without version
+ implementation("com.squareup.okhttp3:okhttp")
+ implementation("com.squareup.okhttp3:logging-interceptor")
+}
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/app/src/androidTest/java/org/nanick/nr5gperf/ExampleInstrumentedTest.java b/app/src/androidTest/java/org/nanick/nr5gperf/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..d0f81fa
--- /dev/null
+++ b/app/src/androidTest/java/org/nanick/nr5gperf/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package org.nanick.nr5gperf;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ assertEquals("org.nanick.nr5gperf", appContext.getPackageName());
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..5ce629f
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/org/nanick/nr5gperf/LteBands.java b/app/src/main/java/org/nanick/nr5gperf/LteBands.java
new file mode 100644
index 0000000..e4f57cf
--- /dev/null
+++ b/app/src/main/java/org/nanick/nr5gperf/LteBands.java
@@ -0,0 +1,30 @@
+package org.nanick.nr5gperf;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.ArrayList;
+
+public class LteBands{
+ @JsonProperty("Downlink")
+ public ArrayList downlink;
+ @JsonProperty("DLEARFCN")
+ public ArrayList dLEARFCN;
+ @JsonProperty("Uplink")
+ public ArrayList uplink;
+ @JsonProperty("ULEARFCN")
+ public ArrayList uLEARFCN;
+ @JsonProperty("Band")
+ public int band;
+ @JsonProperty("Name")
+ public String name;
+ @JsonProperty("Mode")
+ public String mode;
+ @JsonProperty("Bandwidth")
+ public double bandwidth;
+ @JsonProperty("DuplexSpacing")
+ public int duplexSpacing;
+ @JsonProperty("Geographical")
+ public String geographical;
+ @JsonProperty("GSM3GPP")
+ public int gSM3GPP;
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/nanick/nr5gperf/MainActivity.java b/app/src/main/java/org/nanick/nr5gperf/MainActivity.java
new file mode 100644
index 0000000..df1d980
--- /dev/null
+++ b/app/src/main/java/org/nanick/nr5gperf/MainActivity.java
@@ -0,0 +1,845 @@
+package org.nanick.nr5gperf;
+
+//import android.content.pm.PackageManager;
+//import android.os.Bundle;
+//
+//import androidx.activity.EdgeToEdge;
+//import androidx.appcompat.app.AppCompatActivity;
+//import androidx.core.app.ActivityCompat;
+//import androidx.core.graphics.Insets;
+//import androidx.core.view.ViewCompat;
+//import androidx.core.view.WindowInsetsCompat;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.app.ActivityCompat;
+
+import android.Manifest;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+
+import android.annotation.SuppressLint;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.os.AsyncTask;
+import android.telephony.CellIdentityLte;
+import android.telephony.CellIdentityNr;
+import android.telephony.CellInfo;
+import android.telephony.CellInfoLte;
+import android.telephony.CellInfoNr;
+import android.telephony.CellSignalStrengthLte;
+import android.telephony.CellSignalStrengthNr;
+import android.telephony.TelephonyCallback;
+import android.telephony.TelephonyDisplayInfo;
+import android.telephony.TelephonyManager;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.View;
+import android.widget.TextView;
+
+/*import com.google.android.gms.location.FusedLocationProviderClient;
+import com.google.android.gms.location.LocationCallback;
+import com.google.android.gms.location.LocationRequest;
+import com.google.android.gms.location.LocationResult;
+import com.google.android.gms.location.LocationServices;*/
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import java.nio.charset.StandardCharsets;
+import java.text.DecimalFormat;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+//import com.google.android.gms.location.Priority;
+
+import java.util.ArrayList;
+import java.util.StringJoiner;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.IntStream;
+import java.util.Random;
+import org.apache.commons.io.IOUtils;
+
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.MediaType;
+import okhttp3.MultipartBody;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+
+public class MainActivity extends AppCompatActivity {
+ public CellInfoObj cio = null;
+ private TelephonyManager telephonyManager;
+ public Double Latitude;
+ public Double Longitude;
+ private LocationManager locationManager;
+ private LocationListener locationListener;
+ private DiCb telephonyCallback;
+ public File csv;
+ public File upload_file;
+ public FileWriter upload_writer;
+ public FileWriter csv_writer;
+ public LteBands[] bands;
+ public Nr5GBands[] nr5gbands;
+ public float densityDpi = 1;
+ public int fortydpi = 40;
+ public String lte_string = "[{\"Downlink\":[2110.0,2140.0,2170.0],\"DLEARFCN\":[0.0,300.0,599.0],\"Uplink\":[1920.0,1950.0,1980.0],\"ULEARFCN\":[18000.0,18300.0,18599.0],\"Band\":1,\"Name\":\"2100\",\"Mode\":\"FDD\",\"Bandwidth\":60.0,\"DuplexSpacing\":190,\"Geographical\":\"Global\",\"GSM3GPP\":8},{\"Downlink\":[1930.0,1960.0,1990.0],\"DLEARFCN\":[600.0,900.0,1199.0],\"Uplink\":[1850.0,1880.0,1910.0],\"ULEARFCN\":[18600.0,18900.0,19199.0],\"Band\":2,\"Name\":\"1900 PCS\",\"Mode\":\"FDD\",\"Bandwidth\":60.0,\"DuplexSpacing\":80,\"Geographical\":\"NAR\",\"GSM3GPP\":8},{\"Downlink\":[1805.0,1842.5,1880.0],\"DLEARFCN\":[1200.0,1575.0,1949.0],\"Uplink\":[1710.0,1747.5,1785.0],\"ULEARFCN\":[19200.0,19575.0,19949.0],\"Band\":3,\"Name\":\"1800+\",\"Mode\":\"FDD\",\"Bandwidth\":75.0,\"DuplexSpacing\":95,\"Geographical\":\"Global\",\"GSM3GPP\":8},{\"Downlink\":[2110.0,2132.5,2155.0],\"DLEARFCN\":[1950.0,2175.0,2399.0],\"Uplink\":[1710.0,1732.5,1755.0],\"ULEARFCN\":[19950.0,20175.0,20399.0],\"Band\":4,\"Name\":\"AWS-1\",\"Mode\":\"FDD\",\"Bandwidth\":45.0,\"DuplexSpacing\":400,\"Geographical\":\"NAR\",\"GSM3GPP\":8},{\"Downlink\":[869.0,881.5,894.0],\"DLEARFCN\":[2400.0,2525.0,2649.0],\"Uplink\":[824.0,836.5,849.0],\"ULEARFCN\":[20400.0,20525.0,20649.0],\"Band\":5,\"Name\":\"850\",\"Mode\":\"FDD\",\"Bandwidth\":25.0,\"DuplexSpacing\":45,\"Geographical\":\"NAR\",\"GSM3GPP\":8},{\"Downlink\":[2620.0,2655.0,2690.0],\"DLEARFCN\":[2750.0,3100.0,3449.0],\"Uplink\":[2500.0,2535.0,2570.0],\"ULEARFCN\":[20750.0,21100.0,21449.0],\"Band\":7,\"Name\":\"2600\",\"Mode\":\"FDD\",\"Bandwidth\":70.0,\"DuplexSpacing\":120,\"Geographical\":\"EMEA\",\"GSM3GPP\":8},{\"Downlink\":[925.0,942.5,960.0],\"DLEARFCN\":[3450.0,3625.0,3799.0],\"Uplink\":[880.0,897.5,915.0],\"ULEARFCN\":[21450.0,21625.0,21799.0],\"Band\":8,\"Name\":\"900 GSM\",\"Mode\":\"FDD\",\"Bandwidth\":35.0,\"DuplexSpacing\":45,\"Geographical\":\"Global\",\"GSM3GPP\":8},{\"Downlink\":[1844.9,1862.5,1879.9],\"DLEARFCN\":[3800.0,3975.0,4149.0],\"Uplink\":[1749.9,1767.5,1784.9],\"ULEARFCN\":[21800.0,21975.0,22149.0],\"Band\":9,\"Name\":\"1800\",\"Mode\":\"FDD\",\"Bandwidth\":35.0,\"DuplexSpacing\":95,\"Geographical\":\"APAC\",\"GSM3GPP\":8},{\"Downlink\":[2110.0,2140.0,2170.0],\"DLEARFCN\":[4150.0,4450.0,4749.0],\"Uplink\":[1710.0,1740.0,1770.0],\"ULEARFCN\":[22150.0,22450.0,22749.0],\"Band\":10,\"Name\":\"AWS-3\",\"Mode\":\"FDD\",\"Bandwidth\":60.0,\"DuplexSpacing\":400,\"Geographical\":\"NAR\",\"GSM3GPP\":8},{\"Downlink\":[1475.9,1486.0,1495.9],\"DLEARFCN\":[4750.0,4850.0,4949.0],\"Uplink\":[1427.9,1438.0,1447.9],\"ULEARFCN\":[22750.0,22850.0,22949.0],\"Band\":11,\"Name\":\"1500 Lower\",\"Mode\":\"FDD\",\"Bandwidth\":20.0,\"DuplexSpacing\":48,\"Geographical\":\"Japan\",\"GSM3GPP\":8},{\"Downlink\":[729.0,737.5,746.0],\"DLEARFCN\":[5010.0,5095.0,5179.0],\"Uplink\":[699.0,707.5,716.0],\"ULEARFCN\":[23010.0,23095.0,23179.0],\"Band\":12,\"Name\":\"700 a\",\"Mode\":\"FDD\",\"Bandwidth\":17.0,\"DuplexSpacing\":30,\"Geographical\":\"NAR\",\"GSM3GPP\":8},{\"Downlink\":[746.0,751.0,756.0],\"DLEARFCN\":[5180.0,5230.0,5279.0],\"Uplink\":[777.0,782.0,787.0],\"ULEARFCN\":[23180.0,23230.0,23279.0],\"Band\":13,\"Name\":\"700 c\",\"Mode\":\"FDD\",\"Bandwidth\":10.0,\"DuplexSpacing\":-31,\"Geographical\":\"NAR\",\"GSM3GPP\":8},{\"Downlink\":[758.0,763.0,768.0],\"DLEARFCN\":[5280.0,5330.0,5379.0],\"Uplink\":[788.0,793.0,798.0],\"ULEARFCN\":[23280.0,23330.0,23379.0],\"Band\":14,\"Name\":\"700 PS\",\"Mode\":\"FDD\",\"Bandwidth\":10.0,\"DuplexSpacing\":-30,\"Geographical\":\"NAR\",\"GSM3GPP\":8},{\"Downlink\":[734.0,740.0,746.0],\"DLEARFCN\":[5730.0,5790.0,5849.0],\"Uplink\":[704.0,710.0,716.0],\"ULEARFCN\":[23730.0,23790.0,23849.0],\"Band\":17,\"Name\":\"700 b\",\"Mode\":\"FDD\",\"Bandwidth\":12.0,\"DuplexSpacing\":30,\"Geographical\":\"NAR\",\"GSM3GPP\":8},{\"Downlink\":[860.0,867.5,875.0],\"DLEARFCN\":[5850.0,5925.0,5999.0],\"Uplink\":[815.0,822.5,830.0],\"ULEARFCN\":[23850.0,23925.0,23999.0],\"Band\":18,\"Name\":\"800 Lower\",\"Mode\":\"FDD\",\"Bandwidth\":15.0,\"DuplexSpacing\":45,\"Geographical\":\"Japan\",\"GSM3GPP\":9},{\"Downlink\":[875.0,882.5,890.0],\"DLEARFCN\":[6000.0,6075.0,6149.0],\"Uplink\":[830.0,837.5,845.0],\"ULEARFCN\":[24000.0,24075.0,24149.0],\"Band\":19,\"Name\":\"800 Upper\",\"Mode\":\"FDD\",\"Bandwidth\":15.0,\"DuplexSpacing\":45,\"Geographical\":\"Japan\",\"GSM3GPP\":9},{\"Downlink\":[791.0,806.0,821.0],\"DLEARFCN\":[6150.0,6300.0,6449.0],\"Uplink\":[832.0,847.0,862.0],\"ULEARFCN\":[24150.0,24300.0,24449.0],\"Band\":20,\"Name\":\"800 DD\",\"Mode\":\"FDD\",\"Bandwidth\":30.0,\"DuplexSpacing\":-41,\"Geographical\":\"EMEA\",\"GSM3GPP\":9},{\"Downlink\":[1495.9,1503.5,1510.9],\"DLEARFCN\":[6450.0,6525.0,6599.0],\"Uplink\":[1447.9,1455.5,1462.9],\"ULEARFCN\":[24450.0,24525.0,24599.0],\"Band\":21,\"Name\":\"1500 Upper\",\"Mode\":\"FDD\",\"Bandwidth\":15.0,\"DuplexSpacing\":48,\"Geographical\":\"Japan\",\"GSM3GPP\":9},{\"Downlink\":[3510.0,3550.0,3590.0],\"DLEARFCN\":[6600.0,7000.0,7399.0],\"Uplink\":[3410.0,3450.0,3490.0],\"ULEARFCN\":[24600.0,25000.0,25399.0],\"Band\":22,\"Name\":\"3500\",\"Mode\":\"FDD\",\"Bandwidth\":80.0,\"DuplexSpacing\":100,\"Geographical\":\"EMEA\",\"GSM3GPP\":10},{\"Downlink\":[1525.0,1542.0,1559.0],\"DLEARFCN\":[7700.0,7870.0,8039.0],\"Uplink\":[1626.5,1643.5,1660.5],\"ULEARFCN\":[25700.0,25870.0,26039.0],\"Band\":24,\"Name\":\"1600 L-band\",\"Mode\":\"FDD\",\"Bandwidth\":34.0,\"DuplexSpacing\":-102,\"Geographical\":\"NAR\",\"GSM3GPP\":10},{\"Downlink\":[1930.0,1962.5,1995.0],\"DLEARFCN\":[8040.0,8365.0,8689.0],\"Uplink\":[1850.0,1882.5,1915.0],\"ULEARFCN\":[26040.0,26365.0,26689.0],\"Band\":25,\"Name\":\"1900+\",\"Mode\":\"FDD\",\"Bandwidth\":65.0,\"DuplexSpacing\":80,\"Geographical\":\"NAR\",\"GSM3GPP\":10},{\"Downlink\":[859.0,876.5,894.0],\"DLEARFCN\":[8690.0,8865.0,9039.0],\"Uplink\":[814.0,831.5,849.0],\"ULEARFCN\":[26690.0,26865.0,27039.0],\"Band\":26,\"Name\":\"850+\",\"Mode\":\"FDD\",\"Bandwidth\":35.0,\"DuplexSpacing\":45,\"Geographical\":\"NAR\",\"GSM3GPP\":11},{\"Downlink\":[852.0,860.5,869.0],\"DLEARFCN\":[9040.0,9125.0,9209.0],\"Uplink\":[807.0,815.5,824.0],\"ULEARFCN\":[27040.0,27125.0,27209.0],\"Band\":27,\"Name\":\"800 SMR\",\"Mode\":\"FDD\",\"Bandwidth\":17.0,\"DuplexSpacing\":45,\"Geographical\":\"NAR\",\"GSM3GPP\":11},{\"Downlink\":[758.0,780.5,803.0],\"DLEARFCN\":[9210.0,9435.0,9659.0],\"Uplink\":[703.0,725.5,748.0],\"ULEARFCN\":[27210.0,27435.0,27659.0],\"Band\":28,\"Name\":\"700 APT\",\"Mode\":\"FDD\",\"Bandwidth\":45.0,\"DuplexSpacing\":55,\"Geographical\":\"APAC,EU\",\"GSM3GPP\":11},{\"Downlink\":[717.0,722.5,728.0],\"DLEARFCN\":[9660.0,9715.0,9769.0],\"Uplink\":[],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":29,\"Name\":\"700 d\",\"Mode\":\"SDL\",\"Bandwidth\":11.0,\"DuplexSpacing\":0,\"Geographical\":\"NAR\",\"GSM3GPP\":11},{\"Downlink\":[2350.0,2355.0,2360.0],\"DLEARFCN\":[9770.0,9820.0,9869.0],\"Uplink\":[2305.0,2310.0,2315.0],\"ULEARFCN\":[27660.0,27710.0,27759.0],\"Band\":30,\"Name\":\"2300 WCS\",\"Mode\":\"FDD\",\"Bandwidth\":10.0,\"DuplexSpacing\":45,\"Geographical\":\"NAR\",\"GSM3GPP\":12},{\"Downlink\":[462.5,465.0,467.5],\"DLEARFCN\":[9870.0,9895.0,9919.0],\"Uplink\":[452.5,455.0,457.5],\"ULEARFCN\":[27760.0,27785.0,27809.0],\"Band\":31,\"Name\":\"450\",\"Mode\":\"FDD\",\"Bandwidth\":5.0,\"DuplexSpacing\":10,\"Geographical\":\"Global\",\"GSM3GPP\":12},{\"Downlink\":[1452.0,1474.0,1496.0],\"DLEARFCN\":[9920.0,10140.0,10359.0],\"Uplink\":[],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":32,\"Name\":\"1500 L-band\",\"Mode\":\"SDL\",\"Bandwidth\":44.0,\"DuplexSpacing\":0,\"Geographical\":\"EMEA\",\"GSM3GPP\":12},{\"Downlink\":[1900.0,1910.0,1920.0],\"DLEARFCN\":[36000.0,36100.0,36199.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":33,\"Name\":\"TD 1900\",\"Mode\":\"TDD\",\"Bandwidth\":20.0,\"DuplexSpacing\":0,\"Geographical\":\"EMEA\",\"GSM3GPP\":8},{\"Downlink\":[2010.0,2017.5,2025.0],\"DLEARFCN\":[36200.0,36275.0,36349.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":34,\"Name\":\"TD 2000\",\"Mode\":\"TDD\",\"Bandwidth\":15.0,\"DuplexSpacing\":0,\"Geographical\":\"EMEA\",\"GSM3GPP\":8},{\"Downlink\":[1850.0,1880.0,1910.0],\"DLEARFCN\":[36350.0,36650.0,36949.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":35,\"Name\":\"TD PCS Lower\",\"Mode\":\"TDD\",\"Bandwidth\":60.0,\"DuplexSpacing\":0,\"Geographical\":\"NAR\",\"GSM3GPP\":8},{\"Downlink\":[1930.0,1960.0,1990.0],\"DLEARFCN\":[36950.0,37250.0,37549.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":36,\"Name\":\"TD PCS Upper\",\"Mode\":\"TDD\",\"Bandwidth\":60.0,\"DuplexSpacing\":0,\"Geographical\":\"NAR\",\"GSM3GPP\":8},{\"Downlink\":[1910.0,1920.0,1930.0],\"DLEARFCN\":[37550.0,37650.0,37749.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":37,\"Name\":\"TD PCS Center gap\",\"Mode\":\"TDD\",\"Bandwidth\":20.0,\"DuplexSpacing\":0,\"Geographical\":\"NAR\",\"GSM3GPP\":8},{\"Downlink\":[2570.0,2595.0,2620.0],\"DLEARFCN\":[37750.0,38000.0,38249.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":38,\"Name\":\"TD 2600\",\"Mode\":\"TDD\",\"Bandwidth\":50.0,\"DuplexSpacing\":0,\"Geographical\":\"EMEA\",\"GSM3GPP\":8},{\"Downlink\":[1880.0,1900.0,1920.0],\"DLEARFCN\":[38250.0,38450.0,38649.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":39,\"Name\":\"TD 1900+\",\"Mode\":\"TDD\",\"Bandwidth\":40.0,\"DuplexSpacing\":0,\"Geographical\":\"China\",\"GSM3GPP\":8},{\"Downlink\":[2300.0,2350.0,2400.0],\"DLEARFCN\":[38650.0,39150.0,39649.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":40,\"Name\":\"TD 2300\",\"Mode\":\"TDD\",\"Bandwidth\":100.0,\"DuplexSpacing\":0,\"Geographical\":\"China\",\"GSM3GPP\":8},{\"Downlink\":[2496.0,2593.0,2690.0],\"DLEARFCN\":[39650.0,40620.0,41589.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":41,\"Name\":\"TD 2600+\",\"Mode\":\"TDD\",\"Bandwidth\":194.0,\"DuplexSpacing\":0,\"Geographical\":\"Global\",\"GSM3GPP\":10},{\"Downlink\":[3400.0,3500.0,3600.0],\"DLEARFCN\":[41590.0,42590.0,43589.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":42,\"Name\":\"TD 3500\",\"Mode\":\"TDD\",\"Bandwidth\":200.0,\"DuplexSpacing\":0,\"Geographical\":\"\",\"GSM3GPP\":10},{\"Downlink\":[3600.0,3700.0,3800.0],\"DLEARFCN\":[43590.0,44590.0,45589.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":43,\"Name\":\"TD 3700\",\"Mode\":\"TDD\",\"Bandwidth\":200.0,\"DuplexSpacing\":0,\"Geographical\":\"\",\"GSM3GPP\":10},{\"Downlink\":[703.0,753.0,803.0],\"DLEARFCN\":[45590.0,46090.0,46589.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":44,\"Name\":\"TD 700\",\"Mode\":\"TDD\",\"Bandwidth\":100.0,\"DuplexSpacing\":0,\"Geographical\":\"APAC\",\"GSM3GPP\":11},{\"Downlink\":[1447.0,1457.0,1467.0],\"DLEARFCN\":[46590.0,46690.0,46789.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":45,\"Name\":\"TD 1500\",\"Mode\":\"TDD\",\"Bandwidth\":20.0,\"DuplexSpacing\":0,\"Geographical\":\"China\",\"GSM3GPP\":13},{\"Downlink\":[5150.0,5537.5,5925.0],\"DLEARFCN\":[46790.0,50665.0,54539.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":46,\"Name\":\"TD Unlicensed\",\"Mode\":\"TDD\",\"Bandwidth\":775.0,\"DuplexSpacing\":0,\"Geographical\":\"Global\",\"GSM3GPP\":13},{\"Downlink\":[5855.0,5890.0,5925.0],\"DLEARFCN\":[54540.0,54890.0,55239.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":47,\"Name\":\"TD V2X\",\"Mode\":\"TDD\",\"Bandwidth\":70.0,\"DuplexSpacing\":0,\"Geographical\":\"Global\",\"GSM3GPP\":14},{\"Downlink\":[3550.0,3625.0,3700.0],\"DLEARFCN\":[55240.0,55990.0,56739.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":48,\"Name\":\"TD 3600\",\"Mode\":\"TDD\",\"Bandwidth\":150.0,\"DuplexSpacing\":0,\"Geographical\":\"Global\",\"GSM3GPP\":14},{\"Downlink\":[3550.0,3625.0,3700.0],\"DLEARFCN\":[56740.0,57490.0,58239.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":49,\"Name\":\"TD 3600r\",\"Mode\":\"TDD\",\"Bandwidth\":150.0,\"DuplexSpacing\":0,\"Geographical\":\"Global\",\"GSM3GPP\":15},{\"Downlink\":[1432.0,1474.5,1517.0],\"DLEARFCN\":[58240.0,58665.0,59089.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":50,\"Name\":\"TD 1500+\",\"Mode\":\"TDD\",\"Bandwidth\":85.0,\"DuplexSpacing\":0,\"Geographical\":\"EU\",\"GSM3GPP\":15},{\"Downlink\":[1427.0,1429.5,1432.0],\"DLEARFCN\":[59090.0,59115.0,59139.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":51,\"Name\":\"TD 1500-\",\"Mode\":\"TDD\",\"Bandwidth\":5.0,\"DuplexSpacing\":0,\"Geographical\":\"EU\",\"GSM3GPP\":15},{\"Downlink\":[3300.0,3350.0,3400.0],\"DLEARFCN\":[59140.0,59640.0,60139.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":52,\"Name\":\"TD 3300\",\"Mode\":\"TDD\",\"Bandwidth\":100.0,\"DuplexSpacing\":0,\"Geographical\":\"\",\"GSM3GPP\":15},{\"Downlink\":[2483.5,2489.5,2495.0],\"DLEARFCN\":[60140.0,60197.0,60254.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":53,\"Name\":\"TD 2500\",\"Mode\":\"TDD\",\"Bandwidth\":11.5,\"DuplexSpacing\":0,\"Geographical\":\"\",\"GSM3GPP\":16},{\"Downlink\":[1670.0,1672.5,1675.0],\"DLEARFCN\":[60255.0,60280.0,60304.0],\"Uplink\":[0.0,0.0,0.0],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":54,\"Name\":\"TD 1700\",\"Mode\":\"TDD\",\"Bandwidth\":5.0,\"DuplexSpacing\":0,\"Geographical\":\"\",\"GSM3GPP\":18},{\"Downlink\":[2110.0,2155.0,2200.0],\"DLEARFCN\":[65536.0,65986.0,66435.0],\"Uplink\":[1920.0,1965.0,2010.0],\"ULEARFCN\":[131072.0,131522.0,131971.0],\"Band\":65,\"Name\":\"2100+\",\"Mode\":\"FDD\",\"Bandwidth\":90.0,\"DuplexSpacing\":190,\"Geographical\":\"Global\",\"GSM3GPP\":13},{\"Downlink\":[2110.0,2155.0,2200.0],\"DLEARFCN\":[66436.0,66886.0,67335.0],\"Uplink\":[1710.0,1745.0,1780.0],\"ULEARFCN\":[131972.0,132322.0,132671.0],\"Band\":66,\"Name\":\"AWS\",\"Mode\":\"FDD\",\"Bandwidth\":90.0,\"DuplexSpacing\":400,\"Geographical\":\"NAR\",\"GSM3GPP\":13},{\"Downlink\":[738.0,748.0,758.0],\"DLEARFCN\":[67336.0,67436.0,67535.0],\"Uplink\":[],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":67,\"Name\":\"700 EU\",\"Mode\":\"SDL\",\"Bandwidth\":20.0,\"DuplexSpacing\":0,\"Geographical\":\"EMEA\",\"GSM3GPP\":13},{\"Downlink\":[753.0,768.0,783.0],\"DLEARFCN\":[67536.0,67686.0,67835.0],\"Uplink\":[698.0,713.0,728.0],\"ULEARFCN\":[132672.0,132822.0,132971.0],\"Band\":68,\"Name\":\"700 ME\",\"Mode\":\"FDD\",\"Bandwidth\":30.0,\"DuplexSpacing\":55,\"Geographical\":\"EMEA\",\"GSM3GPP\":13},{\"Downlink\":[2570.0,2595.0,2620.0],\"DLEARFCN\":[67836.0,68086.0,68335.0],\"Uplink\":[],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":69,\"Name\":\"DL b38\",\"Mode\":\"SDL\",\"Bandwidth\":50.0,\"DuplexSpacing\":0,\"Geographical\":\"\",\"GSM3GPP\":14},{\"Downlink\":[1995.0,2007.5,2020.0],\"DLEARFCN\":[68336.0,68461.0,68585.0],\"Uplink\":[1695.0,1702.5,1710.0],\"ULEARFCN\":[132972.0,133047.0,133121.0],\"Band\":70,\"Name\":\"AWS-4\",\"Mode\":\"FDD\",\"Bandwidth\":25.0,\"DuplexSpacing\":300,\"Geographical\":\"NAR\",\"GSM3GPP\":14},{\"Downlink\":[617.0,634.5,652.0],\"DLEARFCN\":[68586.0,68761.0,68935.0],\"Uplink\":[663.0,680.5,698.0],\"ULEARFCN\":[133122.0,133297.0,133471.0],\"Band\":71,\"Name\":\"600\",\"Mode\":\"FDD\",\"Bandwidth\":35.0,\"DuplexSpacing\":-46,\"Geographical\":\"NAR\",\"GSM3GPP\":15},{\"Downlink\":[461.0,463.5,466.0],\"DLEARFCN\":[68936.0,68961.0,68985.0],\"Uplink\":[451.0,453.5,456.0],\"ULEARFCN\":[133472.0,133497.0,133521.0],\"Band\":72,\"Name\":\"450 PMR/PAMR\",\"Mode\":\"FDD\",\"Bandwidth\":5.0,\"DuplexSpacing\":10,\"Geographical\":\"EMEA\",\"GSM3GPP\":15},{\"Downlink\":[460.0,462.5,465.0],\"DLEARFCN\":[68986.0,69011.0,69035.0],\"Uplink\":[450.0,452.5,455.0],\"ULEARFCN\":[133522.0,133547.0,133571.0],\"Band\":73,\"Name\":\"450 APAC\",\"Mode\":\"FDD\",\"Bandwidth\":5.0,\"DuplexSpacing\":10,\"Geographical\":\"APAC\",\"GSM3GPP\":15},{\"Downlink\":[1475.0,1496.5,1518.0],\"DLEARFCN\":[69036.0,69251.0,69465.0],\"Uplink\":[1427.0,1448.5,1470.0],\"ULEARFCN\":[133572.0,133787.0,134001.0],\"Band\":74,\"Name\":\"L-band\",\"Mode\":\"FDD\",\"Bandwidth\":43.0,\"DuplexSpacing\":48,\"Geographical\":\"NAR\",\"GSM3GPP\":15},{\"Downlink\":[1432.0,1474.5,1517.0],\"DLEARFCN\":[69466.0,69891.0,70315.0],\"Uplink\":[],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":75,\"Name\":\"DL b50\",\"Mode\":\"SDL\",\"Bandwidth\":85.0,\"DuplexSpacing\":0,\"Geographical\":\"EU\",\"GSM3GPP\":15},{\"Downlink\":[1427.0,1429.5,1432.0],\"DLEARFCN\":[70316.0,70341.0,70365.0],\"Uplink\":[],\"ULEARFCN\":[0.0,0.0,0.0],\"Band\":76,\"Name\":\"DL b51\",\"Mode\":\"SDL\",\"Bandwidth\":5.0,\"DuplexSpacing\":0,\"Geographical\":\"EU\",\"GSM3GPP\":15},{\"Downlink\":[728.0,737.0,746.0],\"DLEARFCN\":[70366.0,70456.0,70545.0],\"Uplink\":[698.0,707.0,716.0],\"ULEARFCN\":[134002.0,134092.0,134181.0],\"Band\":85,\"Name\":\"700 a+\",\"Mode\":\"FDD\",\"Bandwidth\":18.0,\"DuplexSpacing\":30,\"Geographical\":\"NAR\",\"GSM3GPP\":15},{\"Downlink\":[420.0,422.5,425.0],\"DLEARFCN\":[70546.0,70571.0,70595.0],\"Uplink\":[410.0,412.5,415.0],\"ULEARFCN\":[134182.0,134207.0,134231.0],\"Band\":87,\"Name\":\"410\",\"Mode\":\"FDD\",\"Bandwidth\":5.0,\"DuplexSpacing\":10,\"Geographical\":\"EMEA\",\"GSM3GPP\":16},{\"Downlink\":[422.0,424.5,427.0],\"DLEARFCN\":[70596.0,70621.0,70645.0],\"Uplink\":[412.0,414.5,417.0],\"ULEARFCN\":[134232.0,134257.0,134281.0],\"Band\":88,\"Name\":\"410+\",\"Mode\":\"FDD\",\"Bandwidth\":5.0,\"DuplexSpacing\":10,\"Geographical\":\"EMEA\",\"GSM3GPP\":16},{\"Downlink\":[757.0,757.5,758.0],\"DLEARFCN\":[70646.0,70651.0,70655.0],\"Uplink\":[787.0,787.5,788.0],\"ULEARFCN\":[134282.0,134287.0,134291.0],\"Band\":103,\"Name\":\"NB-IoT\",\"Mode\":\"FDD\",\"Bandwidth\":1.0,\"DuplexSpacing\":-30,\"Geographical\":\"\",\"GSM3GPP\":18},{\"Downlink\":[935.0,937.5,940.0],\"DLEARFCN\":[70656.0,70681.0,70705.0],\"Uplink\":[896.0,898.5,901.0],\"ULEARFCN\":[134292.0,134317.0,134341.0],\"Band\":106,\"Name\":\"900\",\"Mode\":\"FDD\",\"Bandwidth\":5.0,\"DuplexSpacing\":39,\"Geographical\":\"\",\"GSM3GPP\":18}]";
+ public String nr5g_string = "[\n{\n\"Downlink\": [\n2110.0,\n2170.0\n],\n\"Uplink\": [\n1920.0,\n1980.0\n],\n\"DLNRARFCN\": [\n422000.0,\n434000.0\n],\n\"UPNRARFCN\": [\n384000.0,\n396000.0\n],\n\"Band\": \"n1\",\n\"Name\": \"2100\",\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n1930.0,\n1990.0\n],\n\"Uplink\": [\n1850.0,\n1910.0\n],\n\"DLNRARFCN\": [\n386000.0,\n398000.0\n],\n\"UPNRARFCN\": [\n370000.0,\n382000.0\n],\n\"Band\": \"n2\",\n\"Name\": \"1900 PCS\",\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n1805.0,\n1880.0\n],\n\"Uplink\": [\n1710.0,\n1785.0\n],\n\"DLNRARFCN\": [\n361000.0,\n376000.0\n],\n\"UPNRARFCN\": [\n342000.0,\n357000.0\n],\n\"Band\": \"n3\",\n\"Name\": \"1800\",\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n869.0,\n894.0\n],\n\"Uplink\": [\n824.0,\n849.0\n],\n\"DLNRARFCN\": [\n173800.0,\n178800.0\n],\n\"UPNRARFCN\": [\n164800.0,\n169800.0\n],\n\"Band\": \"n5\",\n\"Name\": \"850\",\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n2620.0,\n2690.0\n],\n\"Uplink\": [\n2500.0,\n2570.0\n],\n\"DLNRARFCN\": [\n524000.0,\n538000.0\n],\n\"UPNRARFCN\": [\n500000.0,\n514000.0\n],\n\"Band\": \"n7\",\n\"Name\": \"2600\",\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n925.0,\n960.0\n],\n\"Uplink\": [\n880.0,\n915.0\n],\n\"DLNRARFCN\": [\n185000.0,\n192000.0\n],\n\"UPNRARFCN\": [\n176000.0,\n183000.0\n],\n\"Band\": \"n8\",\n\"Name\": \"900\",\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n729.0,\n746.0\n],\n\"Uplink\": [\n699.0,\n716.0\n],\n\"DLNRARFCN\": [\n145800.0,\n149200.0\n],\n\"UPNRARFCN\": [\n139800.0,\n143200.0\n],\n\"Band\": \"n12\",\n\"Name\": \"700a - Lower SMH blocks A/B/C\",\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n746.0,\n756.0\n],\n\"Uplink\": [\n777.0,\n787.0\n],\n\"DLNRARFCN\": [\n149200.0,\n151200.0\n],\n\"UPNRARFCN\": [\n155400.0,\n157400.0\n],\n\"Band\": \"n13\",\n\"Name\": null,\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n758.0,\n768.0\n],\n\"Uplink\": [\n788.0,\n798.0\n],\n\"DLNRARFCN\": [\n151600.0,\n153600.0\n],\n\"UPNRARFCN\": [\n157600.0,\n159600.0\n],\n\"Band\": \"n14\",\n\"Name\": \"Upper SMH\",\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n860.0,\n875.0\n],\n\"Uplink\": [\n815.0,\n830.0\n],\n\"DLNRARFCN\": [\n172000.0,\n175000.0\n],\n\"UPNRARFCN\": [\n163000.0,\n166000.0\n],\n\"Band\": \"n18\",\n\"Name\": \"Lower 800 (Japan)\",\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n791.0,\n821.0\n],\n\"Uplink\": [\n832.0,\n862.0\n],\n\"DLNRARFCN\": [\n158200.0,\n164200.0\n],\n\"UPNRARFCN\": [\n166400.0,\n172400.0\n],\n\"Band\": \"n20\",\n\"Name\": \"EU Digital Dividend\",\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n1525.0,\n1559.0\n],\n\"Uplink\": [\n1626.5,\n1660.5\n],\n\"DLNRARFCN\": [\n305000.0,\n311800.0\n],\n\"UPNRARFCN\": [\n325300.0,\n332100.0\n],\n\"Band\": \"n24\",\n\"Name\": null,\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n1930.0,\n1995.0\n],\n\"Uplink\": [\n1850.0,\n1915.0\n],\n\"DLNRARFCN\": [\n386000.0,\n399000.0\n],\n\"UPNRARFCN\": [\n370000.0,\n383000.0\n],\n\"Band\": \"n25\",\n\"Name\": \"PCS blocks A-G\",\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n859.0,\n894.0\n],\n\"Uplink\": [\n814.0,\n849.0\n],\n\"DLNRARFCN\": [\n171800.0,\n178800.0\n],\n\"UPNRARFCN\": [\n162800.0,\n169800.0\n],\n\"Band\": \"n26\",\n\"Name\": \"Extended CLR\",\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n758.0,\n803.0\n],\n\"Uplink\": [\n703.0,\n748.0\n],\n\"DLNRARFCN\": [\n151600.0,\n160600.0\n],\n\"UPNRARFCN\": [\n140600.0,\n149600.0\n],\n\"Band\": \"n28\",\n\"Name\": \"700 APT\",\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n717.0,\n728.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n143400.0,\n145600.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n29\",\n\"Name\": \"DL 700 blocks D/E\",\n\"Mode\": \"SDL\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n2350.0,\n2360.0\n],\n\"Uplink\": [\n2305.0,\n2315.0\n],\n\"DLNRARFCN\": [\n470000.0,\n472000.0\n],\n\"UPNRARFCN\": [\n461000.0,\n463000.0\n],\n\"Band\": \"n30\",\n\"Name\": \"WCS blocks A/B\",\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n2010.0,\n2025.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n402000.0,\n405000.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n34\",\n\"Name\": \"TD 2000\",\n\"Mode\": \"TDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n2570.0,\n2620.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n514000.0,\n524000.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n38\",\n\"Name\": \"TD 2600\",\n\"Mode\": \"TDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n1880.0,\n1920.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n376000.0,\n384000.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n39\",\n\"Name\": \"TD 1900+\",\n\"Mode\": \"TDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n2300.0,\n2400.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n460000.0,\n480000.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n40\",\n\"Name\": \"TD 2300\",\n\"Mode\": \"TDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n2496.0,\n2690.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n499200.0,\n537999.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n41\",\n\"Name\": \"TD 2500\",\n\"Mode\": \"TDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n5150.0,\n5925.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n743333.0,\n795000.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n46\",\n\"Name\": \"TD 5200\",\n\"Mode\": \"TDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n3550.0,\n3700.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n636667.0,\n646666.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n48\",\n\"Name\": \"CBRS\",\n\"Mode\": \"TDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n1432.0,\n1517.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n286400.0,\n303400.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n50\",\n\"Name\": \"L-Band\",\n\"Mode\": \"TDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n1427.0,\n1432.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n285400.0,\n286400.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n51\",\n\"Name\": \"TD 1500-\",\n\"Mode\": \"TDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n2483.5,\n2495.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n496700.0,\n499000.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n53\",\n\"Name\": \"S Band\",\n\"Mode\": \"TDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n2110.0,\n2200.0\n],\n\"Uplink\": [\n1920.0,\n2010.0\n],\n\"DLNRARFCN\": [\n422000.0,\n440000.0\n],\n\"UPNRARFCN\": [\n384000.0,\n402000.0\n],\n\"Band\": \"n65\",\n\"Name\": null,\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n2110.0,\n2200.0\n],\n\"Uplink\": [\n1710.0,\n1780.0\n],\n\"DLNRARFCN\": [\n422000.0,\n440000.0\n],\n\"UPNRARFCN\": [\n342000.0,\n356000.0\n],\n\"Band\": \"n66\",\n\"Name\": \"AWS-3\",\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n738.0,\n758.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n147600.0,\n151600.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n67\",\n\"Name\": null,\n\"Mode\": \"SDL\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n1995.0,\n2020.0\n],\n\"Uplink\": [\n1695.0,\n1710.0\n],\n\"DLNRARFCN\": [\n399000.0,\n404000.0\n],\n\"UPNRARFCN\": [\n339000.0,\n342000.0\n],\n\"Band\": \"n70\",\n\"Name\": \"AWS-4\",\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n617.0,\n652.0\n],\n\"Uplink\": [\n663.0,\n698.0\n],\n\"DLNRARFCN\": [\n123400.0,\n130400.0\n],\n\"UPNRARFCN\": [\n132600.0,\n139600.0\n],\n\"Band\": \"n71\",\n\"Name\": \"600\",\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n1475.0,\n1518.0\n],\n\"Uplink\": [\n1427.0,\n1470.0\n],\n\"DLNRARFCN\": [\n295000.0,\n303600.0\n],\n\"UPNRARFCN\": [\n285400.0,\n294000.0\n],\n\"Band\": \"n74\",\n\"Name\": \"Lower L-Band\",\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n1432.0,\n1517.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n286400.0,\n303400.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n75\",\n\"Name\": \"DL 1500+\",\n\"Mode\": \"SDL\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n1427.0,\n1432.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n285400.0,\n286400.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n76\",\n\"Name\": \"DL 1500-\",\n\"Mode\": \"SDL\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n3300.0,\n4200.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n620000.0,\n680000.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n77\",\n\"Name\": \"TD 3700 (C-Band)\",\n\"Mode\": \"TDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n3300.0,\n3800.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n620000.0,\n653333.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n78\",\n\"Name\": \"TD 3500\",\n\"Mode\": \"TDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n4400.0,\n5000.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n693334.0,\n733333.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n79\",\n\"Name\": \"TD 4500\",\n\"Mode\": \"TDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n0.0,\n0.0\n],\n\"Uplink\": [\n1710.0,\n1785.0\n],\n\"DLNRARFCN\": [\n0.0,\n0.0\n],\n\"UPNRARFCN\": [\n342000.0,\n357000.0\n],\n\"Band\": \"n80\",\n\"Name\": \"UL 1800\",\n\"Mode\": \"SUL\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n0.0,\n0.0\n],\n\"Uplink\": [\n880.0,\n915.0\n],\n\"DLNRARFCN\": [\n0.0,\n0.0\n],\n\"UPNRARFCN\": [\n176000.0,\n183000.0\n],\n\"Band\": \"n81\",\n\"Name\": \"UL 900\",\n\"Mode\": \"SUL\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n0.0,\n0.0\n],\n\"Uplink\": [\n832.0,\n862.0\n],\n\"DLNRARFCN\": [\n0.0,\n0.0\n],\n\"UPNRARFCN\": [\n166400.0,\n172400.0\n],\n\"Band\": \"n82\",\n\"Name\": \"UL 800\",\n\"Mode\": \"SUL\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n0.0,\n0.0\n],\n\"Uplink\": [\n703.0,\n748.0\n],\n\"DLNRARFCN\": [\n0.0,\n0.0\n],\n\"UPNRARFCN\": [\n140600.0,\n149600.0\n],\n\"Band\": \"n83\",\n\"Name\": \"UL 700\",\n\"Mode\": \"SUL\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n0.0,\n0.0\n],\n\"Uplink\": [\n1920.0,\n1980.0\n],\n\"DLNRARFCN\": [\n0.0,\n0.0\n],\n\"UPNRARFCN\": [\n384000.0,\n396000.0\n],\n\"Band\": \"n84\",\n\"Name\": \"UL 2000\",\n\"Mode\": \"SUL\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n728.0,\n746.0\n],\n\"Uplink\": [\n698.0,\n716.0\n],\n\"DLNRARFCN\": [\n145600.0,\n149200.0\n],\n\"UPNRARFCN\": [\n139600.0,\n143200.0\n],\n\"Band\": \"n85\",\n\"Name\": null,\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n0.0,\n0.0\n],\n\"Uplink\": [\n1710.0,\n1780.0\n],\n\"DLNRARFCN\": [\n0.0,\n0.0\n],\n\"UPNRARFCN\": [\n342000.0,\n356000.0\n],\n\"Band\": \"n86\",\n\"Name\": \"UL 1800-\",\n\"Mode\": \"SUL\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n0.0,\n0.0\n],\n\"Uplink\": [\n824.0,\n849.0\n],\n\"DLNRARFCN\": [\n0.0,\n0.0\n],\n\"UPNRARFCN\": [\n164800.0,\n169800.0\n],\n\"Band\": \"n89\",\n\"Name\": null,\n\"Mode\": \"SUL\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n2496.0,\n2690.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n499200.0,\n537999.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n90\",\n\"Name\": \"MMDS\",\n\"Mode\": \"TDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n1427.0,\n1432.0\n],\n\"Uplink\": [\n832.0,\n862.0\n],\n\"DLNRARFCN\": [\n285400.0,\n286400.0\n],\n\"UPNRARFCN\": [\n166400.0,\n172400.0\n],\n\"Band\": \"n91\",\n\"Name\": null,\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n1432.0,\n1517.0\n],\n\"Uplink\": [\n832.0,\n862.0\n],\n\"DLNRARFCN\": [\n286400.0,\n303400.0\n],\n\"UPNRARFCN\": [\n166400.0,\n172400.0\n],\n\"Band\": \"n92\",\n\"Name\": null,\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n1427.0,\n1432.0\n],\n\"Uplink\": [\n880.0,\n915.0\n],\n\"DLNRARFCN\": [\n285400.0,\n286400.0\n],\n\"UPNRARFCN\": [\n176000.0,\n183000.0\n],\n\"Band\": \"n93\",\n\"Name\": null,\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n1432.0,\n1517.0\n],\n\"Uplink\": [\n880.0,\n915.0\n],\n\"DLNRARFCN\": [\n286400.0,\n303400.0\n],\n\"UPNRARFCN\": [\n176000.0,\n183000.0\n],\n\"Band\": \"n94\",\n\"Name\": null,\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n0.0,\n0.0\n],\n\"Uplink\": [\n2010.0,\n2025.0\n],\n\"DLNRARFCN\": [\n0.0,\n0.0\n],\n\"UPNRARFCN\": [\n402000.0,\n405000.0\n],\n\"Band\": \"n95\",\n\"Name\": null,\n\"Mode\": \"SUL\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n5925.0,\n7125.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n795000.0,\n875000.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n96\",\n\"Name\": \"U-NII\",\n\"Mode\": \"TDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n0.0,\n0.0\n],\n\"Uplink\": [\n2300.0,\n2400.0\n],\n\"DLNRARFCN\": [\n0.0,\n0.0\n],\n\"UPNRARFCN\": [\n460000.0,\n480000.0\n],\n\"Band\": \"n97\",\n\"Name\": null,\n\"Mode\": \"SUL\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n0.0,\n0.0\n],\n\"Uplink\": [\n1880.0,\n1920.0\n],\n\"DLNRARFCN\": [\n0.0,\n0.0\n],\n\"UPNRARFCN\": [\n376000.0,\n384000.0\n],\n\"Band\": \"n98\",\n\"Name\": null,\n\"Mode\": \"SUL\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n0.0,\n0.0\n],\n\"Uplink\": [\n1626.5,\n1660.5\n],\n\"DLNRARFCN\": [\n0.0,\n0.0\n],\n\"UPNRARFCN\": [\n325300.0,\n332100.0\n],\n\"Band\": \"n99\",\n\"Name\": null,\n\"Mode\": \"SUL\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n919.4,\n925.0\n],\n\"Uplink\": [\n874.4,\n880.0\n],\n\"DLNRARFCN\": [\n183880.0,\n185000.0\n],\n\"UPNRARFCN\": [\n174880.0,\n176000.0\n],\n\"Band\": \"n100\",\n\"Name\": null,\n\"Mode\": \"FDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n1900.0,\n1910.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n380000.0,\n382000.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n101\",\n\"Name\": null,\n\"Mode\": \"TDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n5925.0,\n6425.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n795000.0,\n828333.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n102\",\n\"Name\": null,\n\"Mode\": \"TDD\",\n\"BandWidth\": 0.0\n},\n{\n\"Downlink\": [\n6425.0,\n7125.0\n],\n\"Uplink\": [\n0.0,\n0.0\n],\n\"DLNRARFCN\": [\n828334.0,\n875000.0\n],\n\"UPNRARFCN\": [\n0.0,\n0.0\n],\n\"Band\": \"n104\",\n\"Name\": null,\n\"Mode\": \"TDD\",\n\"BandWidth\": 0.0\n}\n]";
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ String[] permissions = new String[]{Manifest.permission.INTERNET,Manifest.permission.ACCESS_NETWORK_STATE,Manifest.permission.READ_PHONE_STATE,Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.MANAGE_EXTERNAL_STORAGE};
+ while(
+ ActivityCompat.checkSelfPermission(this, Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED ||ActivityCompat.checkSelfPermission(this, Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) != PackageManager.PERMISSION_GRANTED || (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.MANAGE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
+ ){
+ ActivityCompat.requestPermissions(MainActivity.this, permissions, 1);
+ }
+ setContentView(R.layout.activity_main);
+ enableCloseGuard();
+ DisplayMetrics metrics = getResources().getDisplayMetrics();
+ this.densityDpi = metrics.density;
+ this.fortydpi = (int) (40 * this.densityDpi);
+ Log.i("nr5gperf","this.fortydpi is " + this.fortydpi + "\nthis.densityDpi is " + this.densityDpi);
+// this.densityDpi = (int)(metrics.density * 160f);
+ this.cio = new CellInfoObj();
+ this.bands = BandsFromJson(this.lte_string);
+ this.nr5gbands = Nr5GBandsFromJson(this.nr5g_string);
+ try {
+ Runtime.getRuntime().exec("su");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ this.locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
+ this.telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
+ this.cio.Plmn = this.telephonyManager.getNetworkOperator();
+ this.locationListener = new LocationListener() {
+ @Override
+ public void onLocationChanged(@NonNull Location location) {
+ updateLocation(location);
+ }
+ };
+ this.locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this.locationListener);
+ if (telephonyManager != null) {
+ this.telephonyCallback = new DiCb();
+ this.telephonyManager.registerTelephonyCallback(this.executorist,this.telephonyCallback);
+ }
+ CreateCSVFile();
+ CreateFileForUpload();
+ ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
+ executorService.scheduleAtFixedRate(new Runnable() {
+ @Override
+ public void run() {
+ SpeedTestTask test = new SpeedTestTask();
+ test.execute();
+ }
+ }, 0, 5, TimeUnit.SECONDS);
+ }
+ public void enableCloseGuard(){
+ try {
+ Class.forName("dalvik.system.CloseGuard")
+ .getMethod("setEnabled", boolean.class)
+ .invoke(null, true);
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ public void writeCsvRow(CellInfoObj cio){
+ StringBuilder csvstring = new StringBuilder();
+ csvstring.append(cio.Rsrp+",");
+ csvstring.append(cio.SsRsrp+",");
+ csvstring.append(new DecimalFormat("0.00").format(cio.Speed) + ",");
+ csvstring.append(new DecimalFormat("0.00").format(cio.Upload) + ",");
+ csvstring.append(cio.TimingAdvance+",");
+ csvstring.append(cio.Plmn+",");
+ csvstring.append(cio.Tac+",");
+ csvstring.append(cio.CellId+",");
+ csvstring.append(cio.eNodeB+",");
+ csvstring.append(cio.Rat+",");
+ csvstring.append(cio.Lat+",");
+ csvstring.append(cio.Lng+",");
+ csvstring.append(cio.EARFCN+",");
+ csvstring.append(cio.Band+",");
+ csvstring.append(cio.Spectrum+",");
+ csvstring.append(cio.NRSpectrum+",");
+ csvstring.append(cio.Bandwidth+",");
+ csvstring.append(cio.Pci+",");
+ csvstring.append(cio.Rsrq+",");
+ csvstring.append(cio.IPAddress+",");
+ csvstring.append(cio.NRPci+",");
+ csvstring.append(cio.NRTac+",");
+ csvstring.append(cio.NRARFCN+",");
+ csvstring.append(cio.NR5GBandName+",");
+ csvstring.append(cio.TimeStamp+"\n");
+ String csv_string = csvstring.toString();
+ try {
+ csv_writer = new FileWriter(csv,true);
+ csv_writer.write(csv_string);
+ csv_writer.close();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ public void updateDownloadSpeed(Double mbps){
+ if(mbps > 0){
+ this.cio.Speed = mbps;
+ }
+ }
+ public void updateUploadSpeed(Double mbps){
+ if(mbps > 0){
+ this.cio.Upload = mbps;
+ }
+ }
+ public void updatePublicIP(String ipaddress){
+ if(ipaddress != null){
+ this.cio.IPAddress = ipaddress;
+ }
+ }
+ public void updateTextViews(){
+ writeTextViews(this.cio);
+ }
+ public void updateCsv(){
+ writeCsvRow(this.cio);
+ }
+ public class SpeedTestTask extends AsyncTask {
+// String testUrl = "https://nlp-137cf635-6c92-49b5-b943-f5c8c75e686f.s3.us-east-2.amazonaws.com/testing.bin";
+// String begin_multipart = "------WebKitFormBoundary0CEaUEFum5RO9St7\nContent-Disposition: form-data; name=\"uploadfile[]\"; filename=\"upload_test.bin\"\nContent-Type: application/octet-stream\n\n";
+// String end_multipart = "\n------WebKitFormBoundary0CEaUEFum5RO9St7\nContent-Disposition: form-data; name=\"submit\"\n\nSubmit\n------WebKitFormBoundary0CEaUEFum5RO9St7--\n\n";
+ @Override
+ protected Integer doInBackground(Void...Params) {
+ try {
+ Log.i("nr5gperf","begin speed test task");
+ DownloadTest();
+ UploadTest();
+ getPubIP();
+ return 0;
+ } catch (IOException e) {
+ e.printStackTrace();
+ return 1;
+ }
+ }
+ @Override
+ protected void onPostExecute(Integer result) {
+ Log.i("nr5gperf","doInBackground: " + String.valueOf(result) + "\nonPostExecute");
+ updateTextViews();
+ updateCsv();
+ }
+ private void DownloadTest() throws IOException {
+ //"https://nlp-137cf635-6c92-49b5-b943-f5c8c75e686f.s3.us-east-2.amazonaws.com/testing.bin"
+ Log.i("nr5gperf","begin download test");
+ byte[] buffer = new byte[32];
+ OkHttpClient client = new OkHttpClient();
+ Request request = new Request.Builder()
+ .url("https://fast.nanick.org/uploads/testing.bin")
+ .build();
+ Double startTime = Double.valueOf(System.currentTimeMillis());
+ client.newCall(request).enqueue(new Callback() {
+ @Override
+ public void onFailure(Call call, IOException e) {
+ e.printStackTrace();
+ }
+ @Override
+ public void onResponse(Call call, Response response) throws IOException {
+ if (!response.isSuccessful()) {
+ response.body().close();
+ throw new IOException("Failed to download file: " + response);
+ }
+ int bytesRead;
+ int totalBytesRead = 0;
+ Double startTime = Double.valueOf(System.currentTimeMillis());
+ InputStream inputStream = response.body().byteStream();
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ totalBytesRead += bytesRead;
+ }
+ Double endTime = Double.valueOf(System.currentTimeMillis());
+ Double totalSeconds = (endTime - startTime) / 1000;
+ final Double download_mbps = 100 / totalSeconds;
+ inputStream.close();
+ response.body().close();
+ Log.i("nr5gperf","download: " + download_mbps);
+ updateDownloadSpeed(download_mbps);
+ }
+ });
+
+ }
+ private void UploadTest() throws IOException {
+ Log.i("nr5gperf","begin upload test");
+ OkHttpClient client = new OkHttpClient();
+ String boundary = "----WebKitFormBoundary0CEaUEFum5RO9St7";
+ File f = new File(MainActivity.this.getExternalFilesDir(null),"upload_test.bin");
+ RequestBody requestBody = new MultipartBody.Builder(boundary)
+ .setType(MultipartBody.FORM)
+ .addFormDataPart("uploadfile[]", f.getName(), RequestBody.create(f, MediaType.parse("application/octet-stream")))
+ .addFormDataPart("submit","Submit")
+ .build();
+ Request request = new Request.Builder()
+ .url("https://fast.nanick.org/upload.php")
+ .post(requestBody)
+ .build();
+ Double startTimeUp = Double.valueOf(System.currentTimeMillis());
+ client.newCall(request).enqueue(new Callback() {
+ @Override
+ public void onFailure(Call call, IOException e) {
+ e.printStackTrace();
+ }
+ @Override
+ public void onResponse(Call call, Response response) throws IOException {
+ if (!response.isSuccessful()) {
+ response.body().close();
+ throw new IOException("Unexpected code " + response);
+ }
+ Double endTimeUp = Double.valueOf(System.currentTimeMillis());
+ Double totalSecondsUp = (endTimeUp - startTimeUp) / 1000;
+ final Double upload_mbps = 10 / totalSecondsUp;
+ Log.i("nr5gperf","upload: " + upload_mbps);
+ response.body().close();
+ updateUploadSpeed(upload_mbps);
+ }
+ });
+ }
+ public void getPubIP() throws IOException {
+ InputStream inputStream = ((HttpURLConnection) new URL("https://fast.nanick.org/ip.php").openConnection()).getInputStream();
+ StringBuilder textBuilder = new StringBuilder();
+ Reader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
+ int c = 0;
+ while ((c = reader.read()) != -1) {
+ if((char)c != (char)10 && (char)c != (char)13){
+ textBuilder.append((char) c);
+ }
+ }
+ String ipaddress = textBuilder.toString();
+ Log.i("nr5gperf","ipaddress: " + ipaddress);
+ inputStream.close();
+ reader.close();
+ updatePublicIP(ipaddress);
+ }
+ }
+ public String parseNetworkType(int networkType){
+ switch (networkType) {
+ case TelephonyManager.NETWORK_TYPE_GPRS:
+ return "GPRS";
+ case TelephonyManager.NETWORK_TYPE_EDGE:
+ return "EDGE";
+ case TelephonyManager.NETWORK_TYPE_CDMA:
+ return "CDMA";
+ case TelephonyManager.NETWORK_TYPE_1xRTT:
+ return "1xRTT";
+ case TelephonyManager.NETWORK_TYPE_IDEN:
+ return "IDEN";
+ case TelephonyManager.NETWORK_TYPE_UMTS:
+ return "UMTS";
+ case TelephonyManager.NETWORK_TYPE_EVDO_0:
+ return "EVDO_0";
+ case TelephonyManager.NETWORK_TYPE_EVDO_A:
+ return "EVDO_A";
+ case TelephonyManager.NETWORK_TYPE_HSDPA:
+ return "HSDPA";
+ case TelephonyManager.NETWORK_TYPE_HSUPA:
+ return "HSUPA";
+ case TelephonyManager.NETWORK_TYPE_HSPA:
+ return "HSPA";
+ case TelephonyManager.NETWORK_TYPE_EVDO_B:
+ return "EVDO_B";
+ case TelephonyManager.NETWORK_TYPE_EHRPD:
+ return "EHRPD";
+ case TelephonyManager.NETWORK_TYPE_HSPAP:
+ return "HSPAP";
+ case TelephonyManager.NETWORK_TYPE_LTE:
+ return "LTE";
+ case TelephonyManager.NETWORK_TYPE_NR:
+ return "NR";
+ default:
+ return "Unknown";
+ }
+ }
+ public void fixTextViewHeight(TextView tv,int height){
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ tv.setHeight(height);
+ tv.setEnabled(true);
+ tv.setVisibility(View.VISIBLE);
+ }
+ });
+ }
+ public void writeTextViews(CellInfoObj cio){
+ fixTextViewHeight(((TextView)findViewById(R.id.rsrp)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.rsrp_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.rsrp)).setText(cio.Rsrp+" dBm");
+ if(cio.SsRsrp != 0){
+ fixTextViewHeight(((TextView)findViewById(R.id.ssrsrp)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.ssrsrp_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.ssrsrp)).setText(cio.SsRsrp+" dBm");
+ }
+ if(cio.Speed > 0){
+ fixTextViewHeight(((TextView)findViewById(R.id.downloadspeed)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.downloadspeed_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.downloadspeed)).setText(new DecimalFormat("0.00").format(cio.Speed)+" Mbps");
+ }
+ if(cio.Upload > 0){
+ fixTextViewHeight(((TextView)findViewById(R.id.uploadspeed)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.uploadspeed_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.uploadspeed)).setText(new DecimalFormat("0.00").format(cio.Upload)+" Mbps");
+ }
+ if(cio.TimingAdvance != Integer.MAX_VALUE){
+ fixTextViewHeight(((TextView)findViewById(R.id.ta)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.ta_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.ta)).setText(cio.TimingAdvance+"");
+ }
+ fixTextViewHeight(((TextView)findViewById(R.id.plmn)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.plmn_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.plmn)).setText(cio.Plmn);
+ fixTextViewHeight(((TextView)findViewById(R.id.lac)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.lac_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.lac)).setText(cio.Tac+"");
+ fixTextViewHeight(((TextView)findViewById(R.id.cellid)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.cellid_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.cellid)).setText(cio.CellId+"");
+ fixTextViewHeight(((TextView)findViewById(R.id.enodeb)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.enodeb_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.enodeb)).setText(cio.eNodeB+"");
+ fixTextViewHeight(((TextView)findViewById(R.id.rat)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.rat_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.rat)).setText(cio.Rat);
+ fixTextViewHeight(((TextView)findViewById(R.id.latitude)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.latitude_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.latitude)).setText(cio.Lat+"");
+ fixTextViewHeight(((TextView)findViewById(R.id.longitude)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.longitude_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.longitude)).setText(cio.Lng+"");
+ fixTextViewHeight(((TextView)findViewById(R.id.channel)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.channel_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.channel)).setText(cio.EARFCN+"");
+ if(cio.NRARFCN != 0){
+ fixTextViewHeight(((TextView)findViewById(R.id.nrarfcn)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.nrarfcn_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.nrarfcn)).setText(cio.NRARFCN+"");
+ }
+ fixTextViewHeight(((TextView)findViewById(R.id.lte_band)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.lte_band_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.lte_band)).setText(cio.Band+"");
+ if(cio.NR5GBandName != null){
+ //byte[] byteArray = cio.NR5GBandName.getBytes();
+ //StringBuilder ssbb = new StringBuilder();
+ //for(int b = 0; b < byteArray.length; b++){
+ // ssbb.append(Integer.valueOf(byteArray[b]));
+ //}
+ //Log.i("nr5gperf",ssbb.toString());
+ fixTextViewHeight(((TextView)findViewById(R.id.nr5gband)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.nr5gband_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.nr5gband)).setText(cio.NR5GBandName);
+ }
+ fixTextViewHeight(((TextView)findViewById(R.id.spectrum)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.spectrum_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.spectrum)).setText(cio.Spectrum);
+ if(cio.NRSpectrum != null){
+ fixTextViewHeight(((TextView)findViewById(R.id.nrspectrum)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.nrspectrum_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.nrspectrum)).setText(cio.NRSpectrum);
+ }
+ if(cio.Bandwidth != 0){
+ fixTextViewHeight(((TextView)findViewById(R.id.bandwidth)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.bandwidth_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.bandwidth)).setText(cio.Bandwidth+" MHz");
+ }
+ fixTextViewHeight(((TextView)findViewById(R.id.pci)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.pci_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.pci)).setText(cio.Pci+"");
+ if(cio.NRPci != 0){
+ fixTextViewHeight(((TextView)findViewById(R.id.nrpci)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.nrpci_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.nrpci)).setText(cio.NRPci+"");
+ }
+ fixTextViewHeight(((TextView)findViewById(R.id.rsrq)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.rsrq_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.rsrq)).setText(cio.Rsrq+"");
+ fixTextViewHeight(((TextView)findViewById(R.id.ipaddress)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.ipaddress_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.ipaddress)).setText(cio.IPAddress);
+ if(cio.NRTac != 0){
+ fixTextViewHeight(((TextView)findViewById(R.id.nrtac)),this.fortydpi);
+ fixTextViewHeight(((TextView)findViewById(R.id.nrtac_label)),this.fortydpi);
+ ((TextView)findViewById(R.id.nrtac)).setText(cio.NRTac+"");
+ }
+ }
+ public LteBands[] BandsFromJson(String jsonString){
+ ObjectMapper om = new ObjectMapper();
+ try {
+ return om.readValue(jsonString, LteBands[].class);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ public void CreateFileForUpload(){
+ File upload_file = new File(MainActivity.this.getExternalFilesDir(null),"upload_test.bin");
+ try {
+ if(upload_file.exists()){
+ Log.i("nr5gperf", "upload_file.bin already exists");
+ } else {
+ if (upload_file.createNewFile()) {
+ FileOutputStream outp = new FileOutputStream(upload_file);
+ Log.i("nr5gperf","Creating file with 1.25 MB random bytes");
+ Random rd = new Random();
+ byte[] bytera = new byte[1310720];
+ rd.nextBytes(bytera);
+ IOUtils.write(bytera,outp);
+ Log.i("nr5gperf","Done creating file with 1.25 MB random bytes");
+ outp.close();
+ }
+ }
+ }
+ catch (IOException e){
+ throw new RuntimeException(e);
+ }
+ }
+ public void CreateCSVFile(){
+ File csvdir = MainActivity.this.getExternalFilesDir(null);
+ this.csv = new File(csvdir,Integer.valueOf((int) (System.currentTimeMillis() / 1000))+".csv");
+ try {
+ if (this.csv.createNewFile()) {
+ this.csv_writer = new FileWriter(this.csv);
+ this.csv_writer.write("Rsrp,SsRsrp,Speed,Upload,TimingAdvance,Plmn,Tac,CellId,eNodeB,Rat,Lat,Lng,EARFCN,Band,Spectrum,NRSpectrum,Bandwidth,Pci,Rsrq,IPAddress,NRPci,NRTac,NRARFCN,NR5GBandName,TimeStamp\n");
+ this.csv_writer.close();
+ Log.i("nr5gperf", "Csv file created.");
+ } else {
+ Log.i("nr5gperf", "Failed to create csv file.");
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ public Nr5GBands[] Nr5GBandsFromJson(String jsonString){
+ ObjectMapper om = new ObjectMapper();
+ try {
+
+ return om.readValue(jsonString, Nr5GBands[].class);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ private Executor executorist = new Executor() {
+ @Override
+ public void execute(Runnable r) {
+ r.run();
+ }
+ };
+ public class CellInfoObj {
+ public CellInfoObj(){
+ }
+ public int Rsrp;
+ public int SsRsrp;
+ public double Speed;
+ public double Upload;
+ public int TimingAdvance;
+ public String Plmn;
+ public int Tac;
+ public int CellId;
+ public int eNodeB;
+ public String Rat;
+ public double Lat;
+ public double Lng;
+ public int EARFCN;
+ public int Band;
+ public String Spectrum;
+ public String NRSpectrum;
+ public int Bandwidth;
+ public int Pci;
+ public int Rsrq;
+ public String IPAddress;
+ public int NRPci;
+ public int NRTac;
+ public int NRARFCN;
+ public Nr5GBands Nr5GBand;
+ public String NR5GBandName;
+ public long TimeStamp;
+ }
+ public static String phoneState;
+ public class DiCb extends TelephonyCallback implements TelephonyCallback.DisplayInfoListener,TelephonyCallback.CellInfoListener {
+ public String GetNetworkOverride(int networkOverride){
+ switch(networkOverride){
+ case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE:
+ return "None";
+ case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA:
+ return "LTE CA";
+ case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO:
+ return "LTE Advanced Pro";
+ case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA:
+ return "NR NSA";
+ case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE:
+ return "NR NSA mmWave";
+ case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED:
+ return "NR Advanced";
+ default:
+ return "Unknown";
+ }
+ }
+ @Override
+ public void onCellInfoChanged(List cellInfo) {
+ if(cellInfo != null){
+ updateCellInfo(cellInfo);
+ }
+ }
+ @Override
+ public void onDisplayInfoChanged(TelephonyDisplayInfo displayInfo) {
+ if (displayInfo != null) {
+ String networkType;
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
+ MainActivity.phoneState = GetNetworkOverride(displayInfo.getOverrideNetworkType());
+ updateDisplayInfo(MainActivity.phoneState);
+ }
+ }
+ }
+ }
+ private void updateDisplayInfo(String state){
+ if(state != null){
+ this.cio.Rat = state;
+ ((TextView)findViewById(R.id.rat)).setHeight(this.fortydpi);
+ ((TextView)findViewById(R.id.rat_label)).setHeight(this.fortydpi);
+ ((TextView)findViewById(R.id.rat)).setEnabled(true);
+ ((TextView)findViewById(R.id.rat)).setVisibility(View.VISIBLE);
+ ((TextView)findViewById(R.id.rat)).setText(this.cio.Rat);
+ ((TextView)findViewById(R.id.rat_label)).setVisibility(View.VISIBLE);
+ ((TextView)findViewById(R.id.rat_label)).setEnabled(true);
+ }
+ }
+ @SuppressLint("MissingPermission")
+ private void updateCellInfo(List allCells){
+ CellInfo cellInfo = allCells.get(0);
+ if(cellInfo instanceof CellInfoLte){
+ CellIdentityLte cellId = (CellIdentityLte)cellInfo.getCellIdentity();
+ CellSignalStrengthLte signalStrengthLte = ((CellInfoLte) cellInfo).getCellSignalStrength();
+ StringJoiner sj = new StringJoiner(", ");
+ IntStream.of(cellId.getBands()).forEach(x -> sj.add(String.valueOf(x)));
+ cio.CellId = cellId.getCi();
+ cio.Tac = cellId.getTac();
+ cio.EARFCN = cellId.getEarfcn();
+ Boolean found = false;
+ for(int a = 0; a < this.bands.length; a++){
+ LteBands b = this.bands[a];
+ ArrayList earfcnlist = b.dLEARFCN;
+ Collections.sort(earfcnlist);
+ double n_low = earfcnlist.get(0);
+ double n_high = earfcnlist.get((earfcnlist.toArray().length - 1));
+ if(cio.EARFCN >= n_low & cio.EARFCN <= n_high){
+ cio.Band = b.band;
+ cio.Spectrum = b.name;
+ found = true;
+ }
+ }
+ cio.Bandwidth = cellId.getBandwidth() / 1000;
+ cio.Pci = cellId.getPci();
+ cio.Rsrp = signalStrengthLte.getRsrp();
+ cio.Rsrq = signalStrengthLte.getRsrq();
+ //cio.Snr = signalStrengthLte.getRssnr();
+ cio.eNodeB = Math.floorDiv((int)cio.CellId,256);
+ cio.TimingAdvance = signalStrengthLte.getTimingAdvance();
+ } else if (cellInfo instanceof CellInfoNr) {
+ CellInfoNr cinr = (CellInfoNr)cellInfo;
+ CellSignalStrengthNr signalStrengthNr = (CellSignalStrengthNr) ((CellInfoNr)cellInfo).getCellSignalStrength();
+ CellIdentityNr cellIdNr = (CellIdentityNr) ((CellInfoNr)cellInfo).getCellIdentity();
+ int[] nrbands = cellIdNr.getBands();
+ StringJoiner sj = new StringJoiner(",");
+ for(int b : nrbands){
+ sj.add(String.valueOf(b));
+ }
+ String nrbands_join = sj.toString();
+ Log.i("nr5gperf","CellIdentityNr.getBands();\n" + nrbands_join);
+ String nci = String.valueOf(cellIdNr.getNci());
+ Log.i("nr5gperf","CellIdentityNr.getNci();\n" + nci);
+ cio.NRARFCN = cellIdNr.getNrarfcn();
+ cio.NRPci = cellIdNr.getPci();
+ cio.NRTac = cellIdNr.getTac();
+ int ssrsrp = signalStrengthNr.getSsRsrp();
+ if(ssrsrp == Integer.MAX_VALUE){
+ ssrsrp = signalStrengthNr.getCsiRsrp();
+ }
+ if(ssrsrp != Integer.MAX_VALUE){
+ cio.SsRsrp = ssrsrp;
+ }
+ Boolean found = false;
+ ArrayList five1 = new ArrayList();
+ for(int a = 0; a < this.nr5gbands.length; a++){
+ Nr5GBands b = this.nr5gbands[a];
+ ArrayList nrarfcnlist = b.dlNRARFCN;
+ Collections.sort(nrarfcnlist);
+ double n_low = nrarfcnlist.get(0);
+ double n_high = nrarfcnlist.get((nrarfcnlist.toArray().length - 1));
+ if(cio.NRARFCN >= n_low & cio.NRARFCN <= n_high){
+ five1.add(b);
+ }
+ }
+ if(five1.stream().count() == 1){
+ cio.Nr5GBand = five1.get(0);
+ cio.NR5GBandName = five1.get(0).band;
+ cio.NRSpectrum = five1.get(0).name;
+ } else if(five1.stream().count() > 1){
+ ArrayList five2 = new ArrayList();
+ for(int a = 0; a < five1.stream().count(); a++){
+ Nr5GBands b = five1.get(a);
+ if(b.name != ""){
+ five2.add(b);
+ }
+ }
+ if(five2.stream().count() == 1){
+ cio.Nr5GBand = five2.get(0);
+ cio.NR5GBandName = five2.get(0).band;
+ cio.NRSpectrum = five2.get(0).name;
+ } else if(five2.stream().count() > 1){
+ Hashtable width = new Hashtable();
+ for(int a = 0; a < five2.stream().count(); a++){
+ Nr5GBands b = five2.get(a);
+ ArrayList nrarfcnlist = b.dlNRARFCN;
+ Collections.sort(nrarfcnlist);
+ double n_low = nrarfcnlist.get(0);
+ double n_high = nrarfcnlist.get((nrarfcnlist.toArray().length - 1));
+ width.put((n_high - n_low),b.band);
+ }
+ ArrayList keys = new ArrayList();
+ Enumeration key = width.keys();
+ while (key.hasMoreElements())
+ {
+ Double d = Double.parseDouble(key.nextElement().toString());
+ keys.add(d);
+ }
+ Double max = Collections.max(keys);
+ String ba = width.get(max);
+ for(int a = 0; a < five2.stream().count(); a++){
+ Nr5GBands b = five2.get(a);
+ if(b.band == ba){
+ cio.Nr5GBand = b;
+ cio.NR5GBandName = b.band;
+ cio.NRSpectrum = b.name;
+ }
+ }
+
+ }
+ }
+ }
+ for(CellInfo cellInfos : allCells){
+ if(cellInfos instanceof CellInfoNr){
+ CellInfoNr cinr = (CellInfoNr)cellInfos;
+ CellSignalStrengthNr signalStrengthNr = (CellSignalStrengthNr) ((CellInfoNr)cellInfos).getCellSignalStrength();
+ CellIdentityNr cellIdNr = (CellIdentityNr) ((CellInfoNr)cellInfos).getCellIdentity();
+ int[] nrbands = cellIdNr.getBands();
+ StringJoiner sj = new StringJoiner(",");
+ for(int b : nrbands){
+ sj.add(String.valueOf(b));
+ }
+ String nrbands_join = sj.toString();
+ Log.i("nr5gperf","CellIdentityNr.getBands();\n" + nrbands_join);
+ String nci = String.valueOf(cellIdNr.getNci());
+ Log.i("nr5gperf","CellIdentityNr.getNci();\n" + nci);
+ cio.NRARFCN = cellIdNr.getNrarfcn();
+ cio.NRPci = cellIdNr.getPci();
+ cio.NRTac = cellIdNr.getTac();
+ int ssrsrp = signalStrengthNr.getSsRsrp();
+ if(ssrsrp == Integer.MAX_VALUE){
+ ssrsrp = signalStrengthNr.getCsiRsrp();
+ }
+ if(ssrsrp != Integer.MAX_VALUE){
+ cio.SsRsrp = ssrsrp;
+ }
+ Boolean found = false;
+ ArrayList five1 = new ArrayList();
+ for(int a = 0; a < this.nr5gbands.length; a++){
+ Nr5GBands b = this.nr5gbands[a];
+ ArrayList nrarfcnlist = b.dlNRARFCN;
+ Collections.sort(nrarfcnlist);
+ double n_low = nrarfcnlist.get(0);
+ double n_high = nrarfcnlist.get((nrarfcnlist.toArray().length - 1));
+ if(cio.NRARFCN >= n_low & cio.NRARFCN <= n_high){
+ five1.add(b);
+ }
+ }
+ if(five1.stream().count() == 1){
+ cio.Nr5GBand = five1.get(0);
+ cio.NR5GBandName = five1.get(0).band;
+ cio.NRSpectrum = five1.get(0).name;
+ } else if(five1.stream().count() > 1){
+ ArrayList five2 = new ArrayList();
+ for(int a = 0; a < five1.stream().count(); a++){
+ Nr5GBands b = five1.get(a);
+ if(b.name != ""){
+ five2.add(b);
+ }
+ }
+ if(five2.stream().count() == 1){
+ cio.Nr5GBand = five2.get(0);
+ cio.NR5GBandName = five2.get(0).band;
+ cio.NRSpectrum = five2.get(0).name;
+ } else if(five2.stream().count() > 1){
+ Hashtable width = new Hashtable();
+ for(int a = 0; a < five2.stream().count(); a++){
+ Nr5GBands b = five2.get(a);
+ ArrayList nrarfcnlist = b.dlNRARFCN;
+ Collections.sort(nrarfcnlist);
+ double n_low = nrarfcnlist.get(0);
+ double n_high = nrarfcnlist.get((nrarfcnlist.toArray().length - 1));
+ width.put((n_high - n_low),b.band);
+ }
+ ArrayList keys = new ArrayList();
+ Enumeration key = width.keys();
+ while (key.hasMoreElements())
+ {
+ Double d = Double.parseDouble(key.nextElement().toString());
+ keys.add(d);
+ }
+ Double max = Collections.max(keys);
+ String ba = width.get(max);
+ for(int a = 0; a < five2.stream().count(); a++){
+ Nr5GBands b = five2.get(a);
+ if(b.band == ba){
+ cio.Nr5GBand = b;
+ cio.NR5GBandName = b.band;
+ cio.NRSpectrum = b.name;
+ }
+ }
+
+ }
+ }
+ }
+ }
+ if(MainActivity.phoneState == null || MainActivity.phoneState == "None"){
+ cio.Rat = parseNetworkType(this.telephonyManager.getDataNetworkType());
+ }
+ writeTextViews(cio);
+ }
+ private void updateLocation(Location location) {
+ this.Latitude = location.getLatitude();
+ this.Longitude = location.getLongitude();
+ this.cio.Lat = this.Latitude;
+ this.cio.Lng = this.Longitude;
+ ((TextView)findViewById(R.id.latitude)).setHeight(this.fortydpi);
+ ((TextView)findViewById(R.id.latitude_label)).setHeight(this.fortydpi);
+ ((TextView)findViewById(R.id.latitude)).setEnabled(true);
+ ((TextView)findViewById(R.id.latitude)).setVisibility(View.VISIBLE);
+ ((TextView)findViewById(R.id.latitude)).setText(this.Latitude+"");
+ ((TextView)findViewById(R.id.latitude_label)).setVisibility(View.VISIBLE);
+ ((TextView)findViewById(R.id.latitude_label)).setEnabled(true);
+ ((TextView)findViewById(R.id.longitude)).setHeight(this.fortydpi);
+ ((TextView)findViewById(R.id.longitude_label)).setHeight(this.fortydpi);
+ ((TextView)findViewById(R.id.longitude)).setEnabled(true);
+ ((TextView)findViewById(R.id.longitude)).setVisibility(View.VISIBLE);
+ ((TextView)findViewById(R.id.longitude)).setText(this.Longitude+"");
+ ((TextView)findViewById(R.id.longitude_label)).setVisibility(View.VISIBLE);
+ ((TextView)findViewById(R.id.longitude_label)).setEnabled(true);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/nanick/nr5gperf/Nr5GBands.java b/app/src/main/java/org/nanick/nr5gperf/Nr5GBands.java
new file mode 100644
index 0000000..dbcdc8e
--- /dev/null
+++ b/app/src/main/java/org/nanick/nr5gperf/Nr5GBands.java
@@ -0,0 +1,30 @@
+package org.nanick.nr5gperf;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.ArrayList;
+
+public class Nr5GBands {
+ @JsonProperty("Downlink")
+ public ArrayList downlink;
+ @JsonProperty("DLNRARFCN")
+ public ArrayList dlNRARFCN;
+ @JsonProperty("Uplink")
+ public ArrayList uplink;
+ @JsonProperty("UPNRARFCN")
+ public ArrayList upNRARFCN;
+ @JsonProperty("Band")
+ public String band;
+ @JsonProperty("Name")
+ public String name;
+ @JsonProperty("Mode")
+ public String mode;
+ @JsonProperty("BandWidth")
+ public double bandwidth;
+ @JsonProperty("DuplexSpacing")
+ public int duplexSpacing;
+ @JsonProperty("Geographical")
+ public String geographical;
+ @JsonProperty("GSM3GPP")
+ public int gSM3GPP;
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/circle_icon.xml b/app/src/main/res/drawable/circle_icon.xml
new file mode 100644
index 0000000..4bf03ca
--- /dev/null
+++ b/app/src/main/res/drawable/circle_icon.xml
@@ -0,0 +1,14 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/tower_icon.xml b/app/src/main/res/drawable/tower_icon.xml
new file mode 100644
index 0000000..0ce4309
--- /dev/null
+++ b/app/src/main/res/drawable/tower_icon.xml
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..b9a14d1
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,852 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/mipmap-anydpi/ic_launcher.xml b/app/src/main/res/mipmap-anydpi/ic_launcher.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi/ic_launcher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..b2dfe3d
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..62b611d
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1b9a695
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9287f50
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9126ae3
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..8bfc24a
--- /dev/null
+++ b/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..c8524cd
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,5 @@
+
+
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..d946509
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,4 @@
+
+ Nr5GPerf
+ Serving Cell Data
+
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..ff52014
--- /dev/null
+++ b/app/src/main/res/values/themes.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/backup_rules.xml b/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 0000000..fa0f996
--- /dev/null
+++ b/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 0000000..9ee9997
--- /dev/null
+++ b/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/test/java/org/nanick/nr5gperf/ExampleUnitTest.java b/app/src/test/java/org/nanick/nr5gperf/ExampleUnitTest.java
new file mode 100644
index 0000000..44635d7
--- /dev/null
+++ b/app/src/test/java/org/nanick/nr5gperf/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package org.nanick.nr5gperf;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..e61198d
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,4 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+alias(libs.plugins.androidApplication) apply false
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..4387edc
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,21 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. For more details, visit
+# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
new file mode 100644
index 0000000..b026330
--- /dev/null
+++ b/gradle/libs.versions.toml
@@ -0,0 +1,22 @@
+[versions]
+agp = "8.3.1"
+junit = "4.13.2"
+junitVersion = "1.1.5"
+espressoCore = "3.5.1"
+appcompat = "1.6.1"
+material = "1.10.0"
+activity = "1.8.0"
+constraintlayout = "2.1.4"
+
+[libraries]
+junit = { group = "junit", name = "junit", version.ref = "junit" }
+ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
+espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
+appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
+material = { group = "com.google.android.material", name = "material", version.ref = "material" }
+activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
+constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
+
+[plugins]
+androidApplication = { id = "com.android.application", version.ref = "agp" }
+
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..f384f9f
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri May 03 01:50:17 CDT 2024
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..4f906e0
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..20bb86d
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,23 @@
+pluginManagement {
+ repositories {
+ google {
+ content {
+ includeGroupByRegex("com\\.android.*")
+ includeGroupByRegex("com\\.google.*")
+ includeGroupByRegex("androidx.*")
+ }
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.name = "NR5GPerf"
+include ':app'