Added settings activity to android scanner; started refactoring scanner api

android-scanner
Tal Moran 2017-06-22 11:50:59 +03:00
parent 24e3556320
commit c7dd5bd663
15 changed files with 355 additions and 50 deletions

View File

@ -1,4 +1,3 @@
buildscript {
repositories {
jcenter()
@ -15,18 +14,19 @@ buildscript {
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.0"
compileSdkVersion 26
buildToolsVersion "26.0.0"
defaultConfig {
applicationId "com.meerkat.laura.fakescannerapp"
minSdkVersion 11
targetSdkVersion 25
minSdkVersion 14
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
// Enabling multidex support.
multiDexEnabled true
vectorDrawables.useSupportLibrary = true
}
@ -42,8 +42,10 @@ android {
}
}
configurations.all {
resolutionStrategy.dependencySubstitution {
// Avoid Android compilation error caused by two different javax.inject dependencies.
substitute module('org.glassfish.hk2.external:javax.inject:2.4.0-b34') with module('javax.inject:javax.inject:1')
}
}
@ -54,21 +56,23 @@ dependencies {
compile project(':meerkat-common')
compile project(':scanner-api-common')
compile 'com.android.support:appcompat-v7:25.0.1'
// compile 'com.android.support.constraint:constraint-layout:1.0.0-beta3'
// compile 'com.android.support.constraint:constraint-layout:1.0.0-beta3'
//compile 'com.android.support:appcompat-v7:23.1.0'
// Google protobufs
compile 'com.google.protobuf:protobuf-java:3.+'
// Retrofit
// compile 'com.squareup.retrofit2:retrofit:2.1.0'
// compile 'com.squareup.retrofit2:converter-protobuf:2.2.0'
testCompile 'junit:junit:4.12'
// androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
// androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
// exclude group: 'com.android.support', module: 'support-annotations'
// })
compile 'com.android.support:appcompat-v7:26.0.+'
compile 'com.google.protobuf:protobuf-java:3.+'
compile 'com.android.support:support-v4:26.0.+'
compile 'com.android.support:support-vector-drawable:26.0.+'
testCompile 'junit:junit:4.12'
}
repositories {

View File

@ -1,23 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.meerkat.laura.fakescannerapp" >
package="com.meerkat.laura.fakescannerapp">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<activity android:name=".MainActivity" >
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".SettingsActivity"
android:label="@string/title_activity_settings">
</activity>
</application>
</manifest>
</manifest>

View File

@ -0,0 +1,109 @@
package com.meerkat.laura.fakescannerapp;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.widget.Toolbar;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls
* to be used with AppCompat.
*/
public abstract class AppCompatPreferenceActivity extends PreferenceActivity {
private AppCompatDelegate mDelegate;
@Override
protected void onCreate(Bundle savedInstanceState) {
getDelegate().installViewFactory();
getDelegate().onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
getDelegate().onPostCreate(savedInstanceState);
}
public ActionBar getSupportActionBar() {
return getDelegate().getSupportActionBar();
}
public void setSupportActionBar(@Nullable Toolbar toolbar) {
getDelegate().setSupportActionBar(toolbar);
}
@Override
public MenuInflater getMenuInflater() {
return getDelegate().getMenuInflater();
}
@Override
public void setContentView(@LayoutRes int layoutResID) {
getDelegate().setContentView(layoutResID);
}
@Override
public void setContentView(View view) {
getDelegate().setContentView(view);
}
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
getDelegate().setContentView(view, params);
}
@Override
public void addContentView(View view, ViewGroup.LayoutParams params) {
getDelegate().addContentView(view, params);
}
@Override
protected void onPostResume() {
super.onPostResume();
getDelegate().onPostResume();
}
@Override
protected void onTitleChanged(CharSequence title, int color) {
super.onTitleChanged(title, color);
getDelegate().setTitle(title);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
getDelegate().onConfigurationChanged(newConfig);
}
@Override
protected void onStop() {
super.onStop();
getDelegate().onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
getDelegate().onDestroy();
}
public void invalidateOptionsMenu() {
getDelegate().invalidateOptionsMenu();
}
private AppCompatDelegate getDelegate() {
if (mDelegate == null) {
mDelegate = AppCompatDelegate.create(this, null);
}
return mDelegate;
}
}

View File

@ -2,10 +2,15 @@ package com.meerkat.laura.fakescannerapp;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.util.Base64;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
@ -16,30 +21,66 @@ import com.google.zxing.integration.android.IntentResult;
import meerkat.pollingstation.ScannerClientAPI;
import meerkat.protobuf.PollingStation;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLDecoder;
import static com.meerkat.laura.fakescannerapp.R.xml.preferences;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
SharedPreferences sharedPref;
// TODO: Make this configurable
private static final String PSC_ADDRESS = "http://127.0.0.1/";
private static final String PSC_SUB_ADDRESS = "";
private static final String PSC_PATH = "/";
private static final int PSC_PORT = 8880;
private Button scanBtn;
private TextView formatTxt, contentTxt, responseTxt;
Button scanBtn;
TextView formatTxt, contentTxt, responseTxt;
ScannerClientAPI scannerClientAPI;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.action_settings:
Intent i = new Intent(this, SettingsActivity.class);
startActivity(i);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
void setNewScannerClientAPI(SharedPreferences sharedPref) {
String pscUrlString = sharedPref.getString(SettingsActivity.PSC_URL, "");
scannerClientAPI = new ScannerClientAPI(pscUrlString);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PreferenceManager.setDefaultValues(this, preferences, false);
sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
sharedPref.registerOnSharedPreferenceChangeListener(new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
if (s.equals(SettingsActivity.PSC_URL))
setNewScannerClientAPI(sharedPreferences);
}
});
scanBtn = (Button)findViewById(R.id.scan_button);
formatTxt = (TextView)findViewById(R.id.scan_format);
contentTxt = (TextView)findViewById(R.id.scan_content);
responseTxt = (TextView)findViewById(R.id.server_response);
scannerClientAPI = new ScannerClientAPI(PSC_ADDRESS, PSC_SUB_ADDRESS, PSC_PORT, PSC_PATH);
setNewScannerClientAPI(sharedPref);
scanBtn.setOnClickListener(this);
}

View File

@ -0,0 +1,14 @@
package com.meerkat.laura.fakescannerapp;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class SettingsActivity extends PreferenceActivity {
public final static String PSC_URL = "psc_url";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zm1,15h-2v-6h2v6zm0,-8h-2V7h2v2z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M11.5,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.9,2 2,2zm6.5,-6v-5.5c0,-3.07 -2.13,-5.64 -5,-6.32V3.5c0,-0.83 -0.67,-1.5 -1.5,-1.5S10,2.67 10,3.5v0.68c-2.87,0.68 -5,3.25 -5,6.32V16l-2,2v1h17v-1l-2,-2z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01,-.25 1.97,-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0,-4.42,-3.58,-8,-8,-8zm0 14c-3.31 0,-6,-2.69,-6,-6 0,-1.01.25,-1.97.7,-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4,-4,-4,-4v3z"/>
</vector>

View File

@ -1,14 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<TextView android:text="@string/instructions" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView" />
android:layout_height="wrap_content"
android:id="@+id/textView" />
<Button
android:layout_width="wrap_content"

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- Settings, should always be in the overflow -->
<item android:id="@+id/action_settings"
android:title="@string/action_settings"
app:showAsAction="never"/>
</menu>

View File

@ -2,4 +2,79 @@
<string name="app_name">FakeScannerApp</string>
<string name="button_txt">SCAN</string>
<string name="instructions">Please, press the button below to scan the vote receipt.</string>
<string name="title_activity_settings">Settings</string>
<!-- Strings related to Settings -->
<string name="action_settings">Settings</string>
<!-- Example General settings -->
<string name="pref_header_general">General</string>
<string name="pref_title_social_recommendations">Enable social recommendations</string>
<string name="pref_description_social_recommendations">Recommendations for people to contact based on your message
history
</string>
<string name="pref_title_psc_url">Scanner Service URL</string>
<string name="pref_default_psc_url">http://192.168.70.10:8880/</string>
<string name="pref_title_add_friends_to_messages">Add friends to messages</string>
<string-array name="pref_example_list_titles">
<item>Always</item>
<item>When possible</item>
<item>Never</item>
</string-array>
<string-array name="pref_example_list_values">
<item>1</item>
<item>0</item>
<item>-1</item>
</string-array>
<!-- Example settings for Data & Sync -->
<string name="pref_header_data_sync">Data &amp; sync</string>
<string name="pref_title_sync_frequency">Sync frequency</string>
<string-array name="pref_sync_frequency_titles">
<item>15 minutes</item>
<item>30 minutes</item>
<item>1 hour</item>
<item>3 hours</item>
<item>6 hours</item>
<item>Never</item>
</string-array>
<string-array name="pref_sync_frequency_values">
<item>15</item>
<item>30</item>
<item>60</item>
<item>180</item>
<item>360</item>
<item>-1</item>
</string-array>
<string-array name="list_preference_entries">
<item>Entry 1</item>
<item>Entry 2</item>
<item>Entry 3</item>
</string-array>
<string-array name="list_preference_entry_values">
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
<string-array name="multi_select_list_preference_default_value"/>
<string name="pref_title_system_sync_settings">System sync settings</string>
<!-- Example settings for Notifications -->
<string name="pref_header_notifications">Notifications</string>
<string name="pref_title_new_message_notifications">New message notifications</string>
<string name="pref_title_ringtone">Ringtone</string>
<string name="pref_ringtone_silent">Silent</string>
<string name="pref_title_vibrate">Vibrate</string>
</resources>

View File

@ -0,0 +1,19 @@
<PreferenceScreen xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- NOTE: EditTextPreference accepts EditText attributes. -->
<!-- NOTE: EditTextPreference's summary should be set to its value by the activity code. -->
<EditTextPreference
android:key="psc_url"
android:title="@string/pref_title_psc_url"
android:defaultValue="@string/pref_default_psc_url"
android:selectAllOnFocus="true"
android:singleLine="true"
android:maxLines="1"
android:inputType="textUri" />
<!-- NOTE: Hide buttons to simplify the UI. Users can touch outside the dialog to
dismiss it. -->
<!-- NOTE: ListPreference's summary should be set to its value by the activity code. -->
</PreferenceScreen>

View File

@ -12,9 +12,7 @@ import static meerkat.pollingstation.PollingStationConstants.POLLING_STATION_WEB
*/
public class PollingStationClientToyRun {
private static final String ADDRESS = "http://192.168.43.79";
private static final String SUB_ADDRESS = "";
private static final int PORT = 8080;
private static final String PSC_URL = "http://192.168.70.10:8880/";
public static void main(String [] args) {
int channel = 10;
@ -31,7 +29,7 @@ public class PollingStationClientToyRun {
// System.out.println("Channel int initial:"+channel);
// System.out.println("Channel int retrieved:"+retrieved);
ScannerClientAPI scannerClient = new ScannerClientAPI(ADDRESS, SUB_ADDRESS, PORT, POLLING_STATION_WEB_SCANNER_SCAN_PATH);
ScannerClientAPI scannerClient = new ScannerClientAPI(PSC_URL);
boolean sent = scannerClient.sendScan(scannedData);
System.out.println("Message sent successfully: "+sent);

View File

@ -26,9 +26,11 @@ import static org.hamcrest.MatcherAssert.assertThat;
public class Receiver_ClientTest {
private PollingStationScanner.Consumer scanner;
private static final String ADDRESS = "http://localhost";
private static final String SUB_ADDRESS = "";
private static final int PORT = 8080;
private static final int PSC_PORT = 8880;
private static final String PSC_HOST = "localhost";
private static final String PSC_SCANNER_PATH = "";
private static final String PSC_URL = "http://" + PSC_HOST + ":" + PSC_PORT + PSC_SCANNER_PATH;
private Semaphore semaphore;
private Throwable thrown;
@ -82,7 +84,7 @@ public class Receiver_ClientTest {
System.err.println("Setting up Scanner WebApp!");
scanner = new ReceiverScanHandler(PORT, SUB_ADDRESS);
scanner = new ReceiverScanHandler(PSC_PORT, PSC_SCANNER_PATH);
semaphore = new Semaphore(0);
thrown = null;
@ -106,7 +108,7 @@ public class Receiver_ClientTest {
scanner.subscribe(new ScanHandler(scannedData));
ScannerClientAPI scannerClient = new ScannerClientAPI(ADDRESS, SUB_ADDRESS, PORT, POLLING_STATION_WEB_SCANNER_SCAN_PATH);
ScannerClientAPI scannerClient = new ScannerClientAPI(PSC_URL + POLLING_STATION_WEB_SCANNER_SCAN_PATH);
scannerClient.sendScan(scannedData);
semaphore.acquire();
@ -124,7 +126,7 @@ public class Receiver_ClientTest {
scanner.subscribe(new ErrorHandler(errorMsg.getMsg()));
ScannerClientAPI scannerClient = new ScannerClientAPI(ADDRESS, SUB_ADDRESS, PORT, POLLING_STATION_WEB_SCANNER_ERROR_PATH);
ScannerClientAPI scannerClient = new ScannerClientAPI(PSC_URL + POLLING_STATION_WEB_SCANNER_ERROR_PATH);
scannerClient.sendError(errorMsg);
semaphore.acquire();

View File

@ -23,12 +23,11 @@ public class ScannerClientAPI {
private Client client;
private WebTarget webTarget;
public ScannerClientAPI(String address, String sub_address, int port, String path) {
public ScannerClientAPI(String url) {
client = ClientBuilder.newClient();
client.register(ProtobufMessageBodyReader.class);
client.register(ProtobufMessageBodyWriter.class);
webTarget = client.target(address + ":" + port)
.path(sub_address).path(path);
webTarget = client.target(url);
}
/**