Skip to content

Commit

Permalink
Merge branch 'release/0.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
hjorthjort committed Oct 2, 2015
2 parents 440b790 + 8f341b6 commit 98bb644
Show file tree
Hide file tree
Showing 71 changed files with 2,657 additions and 0 deletions.
1 change: 1 addition & 0 deletions app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
34 changes: 34 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 23
buildToolsVersion "23.0.1"

defaultConfig {
applicationId "com.example.erik.commutity"
minSdkVersion 19
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
packagingOptions {
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.google.code.gson:gson:2.3.1'
provided "org.projectlombok:lombok:1.12.6"
}



17 changes: 17 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /home/erik/Android/Sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# 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 *;
#}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.alive_n_clickin.commutity.infrastructure;

import android.content.Context;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.test.AndroidTestCase;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
* @author hjorthjort
* Created 29/09/15
* @since 0.1
*/
public class WifiHelperTest extends AndroidTestCase {

//Check that at least SOME scans, possibly made at two different times, have some common results.
//Threading and state changes can make this test fail even though the method might work (if scan results
//are updated while the method is run). But this should check against severe breakage.
public void testScanning() {
WifiManager wifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
List<ScanResult> lastScans = wifiManager.getScanResults();
List<ScanResult> scansToTest = WifiHelper.getInstance().getNearbyMacAddresses(getContext());

Set<String> bssids = new HashSet<>();
Set<String> bssidsToTest = new HashSet<>();

for (ScanResult result :
lastScans) {
bssids.add(result.BSSID);
}

for (ScanResult result :
scansToTest) {
bssidsToTest.add(result.BSSID);
}
bssids.retainAll(bssidsToTest);

assertFalse("No common bssids", bssids.isEmpty());

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.alive_n_clickin.commutity.infrastructure.api;

import android.test.AndroidTestCase;

/**
* @author hjorthjort
* Created 22/09/15
*
* @since 0.1
*/
public class ApiConnectionTest extends AndroidTestCase {

private final ElectricityApiConnection connection = new ElectricityApiConnection();
private static final String TEST_QUERY = "dgw=Ericsson$Vin_Num_001&t1=1442922895000&t2=1442922899000";
private static final String TEST_RESPONSE = "[{\"resourceSpec\":\"RMC_Value\",\"timestamp\":1442922897094,\"value\":\"$GPRMC,135456,A,5743,2398,N,1157,6162,E,,,2282015,,,A*89\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Cell_Id2_Value\",\"timestamp\":1442922897657,\"value\":\"00086315\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Cell_Id_Value\",\"timestamp\":1442922897657,\"value\":\"01B1A105\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Destination_Value\",\"timestamp\":1442922897568,\"value\":\"Lindholmen\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Journey_Name_Value\",\"timestamp\":1442922897568,\"value\":\"45\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Bus_Stop_Name_Value\",\"timestamp\":1442922897190,\"value\":\"Frihamnen\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Turn_Signals_Value\",\"timestamp\":1442922897480,\"value\":\"011\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Course_Value\",\"timestamp\":1442922897004,\"value\":\"105\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Accelerator_Pedal_Position_Value\",\"timestamp\":1442922897845,\"value\":\"50\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Total_Vehicle_Distance_Value\",\"timestamp\":1442922897752,\"value\":\"120814\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Authenticated_Users_Value\",\"timestamp\":1442922896790,\"value\":\"24\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Total_Online_Users_Value\",\"timestamp\":1442922896790,\"value\":\"26\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Rssi2_Value\",\"timestamp\":1442922897657,\"value\":\"-110\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Rssi_Value\",\"timestamp\":1442922897657,\"value\":\"-105\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Latitude_Value\",\"timestamp\":1442922897004,\"value\":\"57.720664\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Speed_Value\",\"timestamp\":1442922897004,\"value\":\"52.7\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Longitude_Value\",\"timestamp\":1442922897004,\"value\":\"11.96027\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Driver_Cabin_Temperature_Value\",\"timestamp\":1442922897286,\"value\":\"27.578844\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Ambient_Temperature_Value\",\"timestamp\":1442922897385,\"value\":\"25.111962\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Speed2_Value\",\"timestamp\":1442922896896,\"value\":\"11.8\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Altitude_Value\",\"timestamp\":1442922896897,\"value\":\"66.0\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Longitude2_Value\",\"timestamp\":1442922896896,\"value\":\"11.96027\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Course2_Value\",\"timestamp\":1442922896897,\"value\":\"359.0\",\"gatewayId\":\"Vin_Num_001\"},{\"resourceSpec\":\"Latitude2_Value\",\"timestamp\":1442922896896,\"value\":\"57.720664\",\"gatewayId\":\"Vin_Num_001\"}]";

private static final String INCORRECT_QUERY = "apabepa91";

public void testGetFromElectricity() {
String response = connection.sendGetToElectricity(TEST_QUERY);
assertEquals("Wrong response to Electricity API query", TEST_RESPONSE, response);

response = connection.sendGetToElectricity(INCORRECT_QUERY);
assertEquals("Response should be null", null, response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package com.alive_n_clickin.commutity.infrastructure.api;

import android.test.AndroidTestCase;

import com.google.gson.internal.LinkedTreeMap;

/**
* @author hjorthjort
* Created 22/09/15
* @since 0.1
*/
public class JsonJavaConverterTest extends AndroidTestCase {

private JsonJavaConverter<BagOfThings> converter;
private final String JSON_PRIMITIVES1 = "\"value1\":1";
private final String JSON_PRIMITIVES2 = "\"value2\":\"abc\"";
private final String JSON_OBJECT = "\"objectValue\":{" + JSON_PRIMITIVES1 + "," + JSON_PRIMITIVES2 + "}";
private final String JSON_OBJECT_REVERSE = "\"objectValue\":{" + JSON_PRIMITIVES2 + "," + JSON_PRIMITIVES1 + "}";
public final BagOfThings BAG_OF_PRIMITIVES = BagOfThings.getBagOfPrimitives();
public final BagOfThings BAG_WITH_OBJECT = BagOfThings.getBagWithObject();

@Override
protected void setUp() throws Exception {
converter = new JsonJavaConverter<>(BagOfThings.class);
}

public void testFromJson() {
//Convert object with only primitives
BagOfThings testObject1 = converter.toJava("{start: {" + JSON_PRIMITIVES1 + "," + JSON_PRIMITIVES2 + "} }", "start");
assertEquals("Primitive JSON to Java", testObject1, BAG_OF_PRIMITIVES);

//Convert an object with an object in it.
BagOfThings testObject2 = converter.toJava("{start: {" + JSON_PRIMITIVES1 + "," + JSON_PRIMITIVES1 + "," + JSON_OBJECT + "} }", "start");
assertEquals("JSON with object to Java", testObject2.value1, BAG_WITH_OBJECT.value1);
assertEquals("JSON with object to Java", testObject2.value2, BAG_WITH_OBJECT.value2);
//The object will become a LinkedTreeMap. We could also test if it contains the right values, but this might be overkill.
assertTrue("JSON with object to Java", testObject2.objectValue instanceof LinkedTreeMap);
}

public void testToJson() {
//An object with only primitive fields and a Null object field. The null object should be ignored
assertTrue("Primitive Java to Json", converter.toJson(BAG_OF_PRIMITIVES).contains(JSON_PRIMITIVES1));
assertTrue("Primitive Java to Json", converter.toJson(BAG_OF_PRIMITIVES).contains(JSON_PRIMITIVES2));

//An object with at least one field that is an object
String json = converter.toJson(BAG_WITH_OBJECT);
//The order in which the parameters appear int the object value doesn't matter
assertTrue("Bag with object to Json", json.contains(JSON_OBJECT) || json.contains(JSON_OBJECT_REVERSE));
}

private static class BagOfThings {

private int value1 = 1;
private String value2 = "abc";
private transient int value3 = 3;
private Object objectValue;

public static BagOfThings getBagOfPrimitives() {
return new BagOfThings();
}

public static BagOfThings getBagWithObject() {
BagOfThings bag = new BagOfThings();
bag.objectValue = new BagOfThings();
return bag;
}

@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this == obj) {
return true;
}
if (!(obj instanceof BagOfThings)) {
return false;
}
BagOfThings tempObj = (BagOfThings) obj;
if (tempObj.objectValue != null) {
return tempObj.value1 == this.value1 &&
tempObj.value2.equals(value2) &&
tempObj.value3 == this.value3 &&
tempObj.objectValue.equals(this.objectValue);
}
return tempObj.value1 == this.value1 &&
tempObj.value2.equals(this.value2) &&
tempObj.value3 == this.value3 &&
null == this.objectValue;
}

@Override
public String toString() {
return value1 + value2 + value3 + objectValue;
}
}
}
40 changes: 40 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.alive_n_clickin.commutity" >

<uses-feature android:name="android.hardware.wifi" />

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".presentation.main.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".presentation.flagreport.FlagVehicle" >
</activity>

<receiver
android:name=".infrastructure.WifiBroadcastReceiver"
android:enabled="true" >
<intent-filter>
<action android:name="android.net.wifi.SCAN_RESULTS" />
<action android:name="android.net.wifi.STATE_CHANGE" />
</intent-filter>
</receiver>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package com.alive_n_clickin.commutity.application;

import android.util.Log;

import com.alive_n_clickin.commutity.util.FlagType;
import com.alive_n_clickin.commutity.presentation.flagreport.FlagVehicleDetailFragment;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;

/**
* An class handling the network connection, since this cannot be done on the main activity
* thread. Accepts an URL and a query string. The IP address of the server is hard coded into
* this class
*/
public class HttpRequest {
private final String LOG_TAG = FlagVehicleDetailFragment.class.getSimpleName();

//Set up server handling variables
private final String baseIP = "http://95.85.21.47/";
private final String flags = "flags";
private final String charset = "UTF-8";
private final String contentType = "application/x-www-form-urlencoded";
private static final int minumumOtherCommentLength = 5;

/**
* Posts a new flag to the server
* @param flagTypeID The type of flag
* @param comment The flag comment
* @return The response code from the server, or -1 if the flag couldn't be sent
*/
public int postFlag(int flagTypeID, String comment){
String ipAddress = baseIP + flags;
String query = String.format("flagType=%s&comment=%s", flagTypeID, comment);
return post(ipAddress, query);
}

/**
* Makes sure the flag can be sent in regards to the comment length
* @param comment The comment from the comment field
* @return True if the http request can be sent, false otherwise
*/
public static boolean assertCommentLength(int flagTypeID, String comment){
//"Other" flag
if(flagTypeID == FlagType.OTHER.flagTypeID){
String trimmedComment = comment.trim();
return trimmedComment.length()>=minumumOtherCommentLength;
}
return true;
}

/**
* Posts a http request to the server
* @param serverAddress The full address for the location where to send the request
* @param query The query to post in the body of the request
* @return The response code from the server, or -1 if the request couldn't be sent
*/
public int post(String serverAddress, String query) {
try {
//Get the url from the address
URL url = new URL(serverAddress);

//Convert the parameters to UTF-8
byte[] bodyPostData = query.getBytes(StandardCharsets.UTF_8);
int bodyPostDataLength = bodyPostData.length;

//Set up server request
HttpURLConnection serverConnection = (HttpURLConnection) url.openConnection();
serverConnection.setDoOutput(true);
serverConnection.setInstanceFollowRedirects(false);
serverConnection.setRequestMethod("POST");
serverConnection.setRequestProperty("Content-Type", contentType);
serverConnection.setRequestProperty("charset", charset);
serverConnection.setRequestProperty("Content-Length", Integer.toString(bodyPostDataLength));
serverConnection.setUseCaches(false);

//Send data
DataOutputStream serverOutput = new DataOutputStream(serverConnection.getOutputStream());
serverOutput.write(bodyPostData);

//Log response code
int status = serverConnection.getResponseCode();
Log.v(LOG_TAG, "Response " + status);

return status;
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Invalid URL. Current URL input was " + serverAddress +
". Error message: " + e);
} catch (IOException e) {
Log.e(LOG_TAG, "Server connection error. Error message: " + e);
}
return -1; //Could not send request
}
}
Loading

0 comments on commit 98bb644

Please sign in to comment.