Commit d274a6de authored by Eric Fossum's avatar Eric Fossum

Merge tag 'v0.1' of fossum.ddns.net:ericfoss/NetworkCoverageTester

Alpha version 0.1
parents dc282380 978c90f2
......@@ -6,7 +6,6 @@
<option name="distributionType" value="LOCAL" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="$APPLICATION_HOME_DIR$/gradle/gradle-2.2.1" />
<option name="gradleJvm" value="1.7" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
......@@ -16,4 +15,5 @@
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
</project>
......@@ -3,7 +3,8 @@
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
</project>
\ No newline at end of file
</project>
......@@ -2,7 +2,7 @@
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/CoverageTest.iml" filepath="$PROJECT_DIR$/CoverageTest.iml" />
<module fileurl="file://$PROJECT_DIR$/NetworkCoverageTester.iml" filepath="$PROJECT_DIR$/NetworkCoverageTester.iml" />
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
</modules>
</component>
......
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="CoverageTest" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="java-gradle" name="Java-Gradle">
<configuration>
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
<option name="BUILDABLE" value="false" />
</configuration>
</facet>
</component>
......@@ -16,4 +15,5 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
</module>
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="CoverageTest" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="NetworkCoverageTester" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle">
<configuration>
......@@ -12,9 +12,8 @@
<option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
<option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugTestSources" />
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
<option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
......@@ -87,4 +86,5 @@
<orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
</module>
......@@ -3,13 +3,12 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "20.0.0"
defaultConfig {
applicationId "com.eastwood.coveragetest"
minSdkVersion 18
minSdkVersion 19
targetSdkVersion 22
versionCode 1
versionName "1.0"
versionName "0.1"
}
buildTypes {
release {
......@@ -17,8 +16,10 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
productFlavors {
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile fileTree(include: ['*.jar'], dir: 'libs')
}
......@@ -3,6 +3,7 @@
package="com.eastwood.coveragetest" >
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
......
......@@ -9,19 +9,18 @@ package com.eastwood.coveragetest;
*/
public class CellObject {
// public final float latitude, longitude;
public final long time_ms;
public final int gsm, cdma, wcdma, lte;
public final String carrier;
public CellObject(int _gsm, int _cdma, int _wcdma, int _lte) {
public CellObject(int _gsm, int _cdma, int _wcdma, int _lte, String _carrier) {
// latitude = _lat;
// longitude = _lon;
carrier = _carrier;
gsm = _gsm;
cdma = _cdma;
wcdma = _wcdma;
lte = _lte;
time_ms = System.currentTimeMillis();
}
}
package com.eastwood.coveragetest;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.location.Location;
import java.util.ArrayList;
import java.util.List;
/**
* Created by ericfoss on 4/23/15.
*/
public class Database extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "coverage.db";
public static final String TABLE_NAME = "coverage";
public static final double NMEA_RADIUS = 0.000278; // About 100 ft.
private static final double M_TO_FT = 3.28084;
public static final double M_RADIUS = 100 / M_TO_FT;
private static final String ID_COLUMN = "id";
private static final String CARRIER_COLUMN = "carrier";
private static final String LAT_COLUMN = "lat";
private static final String LON_COLUMN = "lon";
private static final String GSM_COLUMN = "gsm";
private static final String CDMA_COLUMN = "cdma";
private static final String WCDMA_COLUMN = "wcdma";
private static final String LTE_COLUMN = "lte";
public Database(Context context)
{
super(context, DATABASE_NAME , null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table "+TABLE_NAME+" ("+
ID_COLUMN +" INTEGER primary key, "+
LAT_COLUMN +" REAL, "+
LON_COLUMN +" REAL, "+
GSM_COLUMN +" INTEGER, "+
CDMA_COLUMN +" INTEGER, "+
WCDMA_COLUMN +" INTEGER, "+
LTE_COLUMN +" INTEGER, "+
CARRIER_COLUMN+" TEXT)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
onCreate(db);
}
private String where_str(double _lat, double _lon, double _radius) {
return (LAT_COLUMN+"<"+(_lat+_radius)+" AND "+LAT_COLUMN+">"+(_lat-_radius)+" AND "+
LON_COLUMN+"<"+(_lon+_radius)+" AND "+LON_COLUMN+">"+(_lon-_radius));
}
// public void clearData() {
// SQLiteDatabase db = this.getWritableDatabase();
//
// db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
// db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
// ID_COLUMN + " INTEGER primary key, " +
// LAT_COLUMN + " REAL, " +
// LON_COLUMN + " REAL, " +
// GSM_COLUMN + " INTEGER, " +
// CDMA_COLUMN + " INTEGER, " +
// WCDMA_COLUMN + " INTEGER, " +
// LTE_COLUMN + " INTEGER, " +
// CARRIER_COLUMN + " TEXT)");
// }
public List<String> getLocalData(Location loc) {
SQLiteDatabase db = this.getWritableDatabase();
List<String> dataArray = new ArrayList<>();
// Get closest location within 100 ft.
Cursor res = db.query(TABLE_NAME, null, where_str(loc.getLatitude(), loc.getLongitude(), NMEA_RADIUS *10), null, null, null, null);
while (res.moveToNext()) {
double newLat = res.getDouble(res.getColumnIndex(LAT_COLUMN));
double newLon = res.getDouble(res.getColumnIndex(LON_COLUMN));
float newDist[] = new float[3];
Location.distanceBetween(loc.getLatitude(), loc.getLongitude(), newLat, newLon, newDist);
// Add to array
StringBuilder str = new StringBuilder();
str.append("Dist: "+Math.round(newDist[0] * M_TO_FT)+"ft");
str.append(", Carrier: "+res.getString(res.getColumnIndex(CARRIER_COLUMN)));
if (res.getInt(res.getColumnIndex(GSM_COLUMN)) > Integer.MIN_VALUE) {
str.append(", GSM: " + res.getInt(res.getColumnIndex(GSM_COLUMN)));
}
if (res.getInt(res.getColumnIndex(CDMA_COLUMN)) > Integer.MIN_VALUE) {
str.append(", CDMA: " + res.getInt(res.getColumnIndex(CDMA_COLUMN)));
}
if (res.getInt(res.getColumnIndex(WCDMA_COLUMN)) > Integer.MIN_VALUE) {
str.append(", WCDMA: " + res.getInt(res.getColumnIndex(WCDMA_COLUMN)));
}
if (res.getInt(res.getColumnIndex(LTE_COLUMN)) > Integer.MIN_VALUE) {
str.append(", LTE: " + res.getInt(res.getColumnIndex(LTE_COLUMN)));
}
dataArray.add(str.toString());
}
if (!res.isClosed()) { res.close(); }
return dataArray;
}
public boolean insertCoverage(Location loc, CellObject _covObj) {
if (loc.getLatitude() == 0.0 && loc.getLatitude() == 0.0) {
return false;
}
SQLiteDatabase db = this.getWritableDatabase();
int closest = -1;
// Get closest location within 100 ft.
Cursor res = db.query(TABLE_NAME, null, where_str(loc.getLatitude(), loc.getLongitude(), NMEA_RADIUS), null, null, null, null);
while (res.moveToNext()) {
int currPos = res.getPosition();
if (closest == -1) {
closest = res.getPosition();
continue;
}
res.moveToPosition(closest);
double oldLat = res.getDouble(res.getColumnIndex("lat"));
double oldLon = res.getDouble(res.getColumnIndex("lon"));
float oldDist[] = new float[3];
Location.distanceBetween(loc.getLatitude(), loc.getLongitude(), oldLat, oldLon, oldDist);
res.moveToPosition(currPos);
double newLat = res.getDouble(res.getColumnIndex("lat"));
double newLon = res.getDouble(res.getColumnIndex("lon"));
float newDist[] = new float[3];
Location.distanceBetween(loc.getLatitude(), loc.getLongitude(), newLat, newLon, newDist);
if (newDist[0] < oldDist[0]) {
closest = currPos;
}
}
// Override any data that is higher than the old
ContentValues contentValues = new ContentValues();
if (closest != -1) {
res.moveToPosition(closest);
if (_covObj.gsm > res.getDouble(res.getColumnIndex("gsm"))) {
contentValues.put("gsm", _covObj.gsm);
}
if (_covObj.cdma > res.getDouble(res.getColumnIndex("cdma"))) {
contentValues.put("cdma", _covObj.cdma);
}
if (_covObj.wcdma > res.getDouble(res.getColumnIndex("wcdma"))) {
contentValues.put("wcdma", _covObj.wcdma);
}
if (_covObj.lte > res.getDouble(res.getColumnIndex("lte"))) {
contentValues.put("lte", _covObj.lte);
}
if (contentValues.size() > 0) {
db.update(TABLE_NAME, contentValues, "id = ?", new String[]{res.getString(res.getColumnIndex("id"))});
}
} else {
contentValues.put(LAT_COLUMN, loc.getLatitude());
contentValues.put(LON_COLUMN, loc.getLongitude());
contentValues.put(GSM_COLUMN, _covObj.gsm);
contentValues.put(CDMA_COLUMN, _covObj.cdma);
contentValues.put(WCDMA_COLUMN, _covObj.wcdma);
contentValues.put(LTE_COLUMN, _covObj.lte);
contentValues.put(CARRIER_COLUMN, _covObj.carrier);
db.insert(TABLE_NAME, null, contentValues);
}
// Close cursor
if (!res.isClosed()) { res.close(); }
return true;
}
}
......@@ -12,6 +12,7 @@ import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Environment;
import android.telephony.CellInfo;
import android.telephony.CellInfoCdma;
import android.telephony.CellInfoGsm;
......@@ -25,42 +26,168 @@ import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
import java.text.DateFormat;
import java.util.Date;
import java.util.List;
public class Main extends Activity {
private static final String locProvider = LocationManager.GPS_PROVIDER;
private static final double M_TO_FT = 3.28084;
private static final int MIN_ACCURACY_REQ = 30; // 30m or about 100ft
private LocationManager locationManager;
private LocationManager locManager;
private GPSLocationListener locListener;
private Database coverage_db;
private Location lastKnownLocation;
public static String PACKAGE_NAME;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, new GPSLocationListener());
PACKAGE_NAME = this.getApplicationContext().getPackageName();
coverage_db = new Database(this);
/*
REMOVE THIS AFTER DONE TESTING!!!!!!!!!
*/
// coverage_db.clearData();
locManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locListener = new GPSLocationListener();
locManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, locListener);
lastKnownLocation = new Location(locProvider);
}
public void updateText(CellObject cObj, Location loc) {
TextView tView = (TextView)findViewById(R.id.textBox);
// Location data
if (loc.getLatitude() == 0.0 && loc.getLatitude() == 0.0) {
tView.setText("No location data available\n");
} else {
tView.setText("Lat: " + loc.getLatitude() + ", Lon: " + loc.getLongitude() + "\n" +
"Accuracy: " + Math.round(loc.getAccuracy() * M_TO_FT) + "ft\n");
}
// Show cell data
if (cObj == null) {
tView.append("No cell data\n");
} else {
tView.append("Carrier: " + cObj.carrier + "\n");
if (cObj.gsm > Integer.MIN_VALUE) {
tView.append("GSM: " + cObj.gsm + "\n");
}
if (cObj.cdma > Integer.MIN_VALUE) {
tView.append("CDMA: " + cObj.cdma + "\n");
}
if (cObj.wcdma > Integer.MIN_VALUE) {
tView.append("WCDMA: " + cObj.wcdma + "\n");
}
if (cObj.lte > Integer.MIN_VALUE) {
tView.append("LTE: " + cObj.lte + "\n");
}
}
// Show date/time
String currentDateTimeString = DateFormat.getDateTimeInstance().format(new Date());
tView.append(currentDateTimeString+"\n");
// Print database info (if available)
List<String> savedData = coverage_db.getLocalData(loc);
if (loc.getAccuracy() > Database.M_RADIUS) {
savedData.clear();
savedData.add("Location accuracy too low");
} else if (savedData.size() == 0) {
savedData.add("No local data");
}
ListView lView = (ListView)findViewById(R.id.savedDataList);
ArrayAdapter<String> aAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, savedData);
lView.setAdapter(aAdapter);
}
public void storeData(Location loc) {
CellObject cObj = getCell();
if (cObj != null) {
TextView tView = (TextView)findViewById(R.id.textBox);
tView.setText("Lat: "+loc.getLatitude()+", Lon: "+loc.getLongitude()+"\n"+
"Accuracy: "+loc.getAccuracy()+"\n"+
"GSM: "+cObj.gsm+"\n"+
"CDMA: "+cObj.cdma+"\n"+
"WCDMA: "+cObj.wcdma+"\n"+
"LTE: "+cObj.lte);
// Update screen
updateText(cObj, loc);
// Update database
if (loc.getAccuracy() < MIN_ACCURACY_REQ) {
// Save accuracy here
coverage_db.insertCoverage(loc, cObj);
}
} else {
Log.d("GPSListener", "GPS fix, but could not update cell info");
}
}
public void toggleGps(MenuItem mItem) {
String usingGps = "GPS On";
if (usingGps.equals(mItem.getTitle())) {
// Stop GPS
locManager.removeUpdates(locListener);
// Set Button
mItem.setTitle(R.string.gps_off);
} else {
// Start GPS
locManager.requestLocationUpdates(locProvider, 0, 0, locListener);
// Set Button
mItem.setTitle(R.string.gps_on);
}
}
public void dumpDatabase(MenuItem mItem) {
try {
File sd = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File data = Environment.getDataDirectory();
sd.mkdirs();
if (sd.canWrite()) {
String currentDBPath = "/data/"+PACKAGE_NAME+"/databases/"+Database.DATABASE_NAME;
String backupDBPath = Database.DATABASE_NAME;
File currentDB = new File(data, currentDBPath);
File backupDB = new File(sd, backupDBPath);
if (currentDB.exists()) {
FileChannel src = new FileInputStream(currentDB).getChannel();
FileChannel dst = new FileOutputStream(backupDB).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
}
}
toastMsg("Database dumped to downloads folder");
Log.i("main", "Database dumped to downloads folder");
} catch (Exception e) {
Log.d("main", e.getMessage());
}
}
public void refreshData(View v) {
CellObject cObj = getCell();
updateText(cObj, lastKnownLocation);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
......@@ -108,7 +235,7 @@ public class Main extends Activity {
throw new Exception("Unknown type of cell signal!");
}
cObj = new CellObject(gsmSignal, cdmaSignal, wcdmaSignal, lteSignal);
cObj = new CellObject(gsmSignal, cdmaSignal, wcdmaSignal, lteSignal, tm.getNetworkOperatorName());
}
} catch (Exception e) {
Log.e("Main", "Unable to obtain cell signal information", e);
......@@ -118,7 +245,7 @@ public class Main extends Activity {
}
public void toastMsg(String msg) {
Toast.makeText(getApplicationContext(), ""+msg, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), "" + msg, Toast.LENGTH_SHORT).show();
}
public class GPSLocationListener implements LocationListener
......@@ -126,6 +253,7 @@ public class Main extends Activity {
@Override
public void onLocationChanged(Location loc)
{
lastKnownLocation = loc;
storeData(loc);
}
......
......@@ -15,11 +15,20 @@
android:text="@string/hello_world" />
<Button
android:id="@+id/refresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Refresh"
android:id="@+id/refresh"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="Refresh" />
android:onClick="refreshData"
android:layout_alignParentRight="true" />
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/savedDataList"
android:layout_alignParentStart="true"
android:layout_above="@+id/refresh"
android:layout_below="@+id/textBox" />
</RelativeLayout>
......@@ -5,4 +5,14 @@
android:title="@string/action_settings"
android:orderInCategory="100"
android:showAsAction="never" />
<item android:id="@+id/gps_toggle"
android:title="@string/gps_off"
android:onClick="toggleGps"
android:orderInCategory="99"
android:showAsAction="ifRoom" />
<item android:id="@+id/data_dump"
android:title="@string/dump_db"
android:onClick="dumpDatabase"
android:orderInCategory="98"
android:showAsAction="never" />
</menu>
......@@ -2,7 +2,10 @@
<resources>
<string name="app_name">Coverage Test</string>
<string name="hello_world">Hello world!</string>
<string name="hello_world">Waiting for data... Maybe you should enable GPS</string>
<string name="action_settings">Settings</string>
<string name="gps_off">GPS Off</string>
<string name="gps_on">GPS On</string>
<string name="dump_db">Dump Database</string>
</resources>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment