Skip to content

Commit

Permalink
Merge pull request #111 from digital-voting-pass/feature/check_networ…
Browse files Browse the repository at this point in the history
…k_state

Feature/check network state
  • Loading branch information
wkmeijer authored Jun 21, 2017
2 parents 1ee3adf + b25a5c4 commit 5fc0fe6
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 54 deletions.
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@
[![platform](https://img.shields.io/badge/platform-Android-green.svg)](https://www.android.com)
[![Build Status](https://travis-ci.org/digital-voting-pass/digital-voting-pass-app.svg?branch=develop)](https://travis-ci.org/digital-voting-pass/digital-voting-pass-app)

<img align="right" src="https://user-images.githubusercontent.com/2787511/27002571-8d902bb8-4de5-11e7-94d5-da48a4209fdc.gif" width="350" />

Part of a [Delft Unversity of Technology](https://www.tudelft.nl) bachelor's thesis about the digitalization of the voting pass for Dutch elections using **blockchain** and **machine readable travel documents**.

The scope of this project is limited to the [voting pass](https://nl.wikipedia.org/wiki/Stempas) only and forms one step towards the digitalization of the entire voting process.

This app is intended for use at the polling station. An official scans a voter's travel document to verify and redeem the suffrage, which process is stored on the blockchain and can be verifed by anyone. After the suffrage is verified, a ballot is handed out and the voting process continues in a traditional way (by pencil and paper).

[<img src="https://user-images.githubusercontent.com/2787511/27002571-8d902bb8-4de5-11e7-94d5-da48a4209fdc.gif" width="350" />]()


<a href="https://play.google.com/store/apps/details?id=com.digitalvotingpass.digitalvotingpass">
<img alt="Android app on Google Play" src="https://developer.android.com/images/brand/en_app_rgb_wo_45.png" />
</a>

## Getting Started

Expand Down Expand Up @@ -45,4 +50,4 @@ This project is licensed under the LGPL License - see the [LICENSE.md](LICENSE.m
We would like to give special thanks to:
* Johan Pouwelse ([synctext](https://github.com/synctext)) for his guidance and blockchain expertise
* Milvum ([milvum.com](https://www.milvum.com)) for the resources they provided
* Anyone who's code was used for those great building blocks
* Anyone who's code was used for those great building blocks
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.digitalvotingpass.blockchain;

import android.util.Log;

import org.bitcoinj.core.Peer;
import org.bitcoinj.core.listeners.DownloadProgressTracker;

import java.util.ArrayList;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,23 @@
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v13.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.digitalvotingpass.blockchain.BlockChain;
import com.digitalvotingpass.blockchain.BlockchainCallBackListener;
import com.digitalvotingpass.electionchoice.Election;
import com.digitalvotingpass.electionchoice.ElectionChoiceActivity;
import com.digitalvotingpass.utilities.Util;
import com.digitalvotingpass.utilities.ErrorDialog;
import com.google.gson.Gson;

Expand Down Expand Up @@ -89,10 +96,37 @@ public void onCreate(Bundle savedInstanceState) {
}
}

/**
* When the view is focused, check network state and display an error when network is unavailable.
* @param hasFocus
*/
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (!Util.isOnline(getApplicationContext()) && hasFocus) {
initTextHandler.removeCallbacks(initTextUpdater);
currentTask.setText(getString(R.string.no_connection));

if (!Util.isNetEnabled(getApplicationContext())) {
View.OnClickListener inputSnackbarListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
}
};

Snackbar snackbar = Snackbar.make(findViewById(R.id.splash_screen_layout), getString(R.string.please_enable_connect_message), Snackbar.LENGTH_INDEFINITE);
snackbar.getView().setBackgroundColor(ContextCompat.getColor(this, R.color.redFailed));
snackbar.setAction(R.string.go_network_settings, inputSnackbarListener);
snackbar.show();
}
}
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (requestCode == REQUEST_CODE_STORAGE) {
if (requestCode == REQUEST_CODE_STORAGE) {
if (grantResults.length != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
} else {
handler.post(startBlockChain);
Expand Down Expand Up @@ -136,7 +170,7 @@ public void onDownloadComplete() {
Intent intent;

// Check if the election exists in sharedpreferences and in the blockchain
if(json.equals("not found")){
if(json.equals("not found")) {
intent = new Intent(SplashActivity.this, ElectionChoiceActivity.class);
} else {
Gson gson = new Gson();
Expand Down
28 changes: 23 additions & 5 deletions app/src/main/java/com/digitalvotingpass/utilities/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v7.widget.Toolbar;
import android.util.Log;

Expand All @@ -26,6 +28,7 @@ public class Util {

/**
* Returns the height of the status bar in pixels
*
* @param resources Resources object required to get the height attribute.
* @return int
*/
Expand All @@ -42,7 +45,8 @@ public static int getStatusBarHeight(Resources resources) {
* Sets up a top-padding for the given app bar equal to the height of the status bar.
* This increases the length of the app bar so it fits nicely below the status bar.
* This method also sets the status bar transparency.
* @param appBar Toolbar to set padding to
*
* @param appBar Toolbar to set padding to
* @param activity Activity - current activity
*/
public static void setupAppBar(Toolbar appBar, Activity activity) {
Expand All @@ -58,8 +62,9 @@ public static void setupAppBar(Toolbar appBar, Activity activity) {
* Copies an InputStream into a File.
* This is used to copy an InputStream from the assets folder to a file in the FileSystem.
* Creates nay non-existant parent folders to f.
*
* @param is InputStream to be copied.
* @param f File to copy data to.
* @param f File to copy data to.
*/
public static void copyAssetsFile(InputStream is, File f) throws IOException {
if (!f.exists()) {
Expand All @@ -72,8 +77,7 @@ public static void copyAssetsFile(InputStream is, File f) throws IOException {
final int buffer_size = 1024 * 1024;
try {
byte[] bytes = new byte[buffer_size];
for (;;)
{
for (; ; ) {
int count = is.read(bytes, 0, buffer_size);
if (count == -1)
break;
Expand All @@ -91,7 +95,7 @@ public static void copyAssetsFile(InputStream is, File f) throws IOException {
* This method is used for signing transaction hashes (which are in hex).
*/
public static byte[] hexStringToByteArray(String hStr) {
if(hStr != null) {
if (hStr != null) {
int len = hStr.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
Expand Down Expand Up @@ -131,4 +135,18 @@ public static Map<String, String> getKeyValueFromStringArray(Context ctx) {
}
return result;
}

public static boolean isOnline(Context ctx) {
ConnectivityManager cm =
(ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnectedOrConnecting();
}

public static boolean isNetEnabled(Context ctx) {
ConnectivityManager cm =
(ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null;
}
}
92 changes: 49 additions & 43 deletions app/src/main/res/layout/activity_splash_screen.xml
Original file line number Diff line number Diff line change
@@ -1,52 +1,58 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/splash_screen_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:background="@color/govDarkBlue">

<TextView
android:id="@+id/text_splash_screen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
<LinearLayout
android:orientation="vertical"
android:gravity="center"
android:text="@string/app_name"
android:textColor="@color/govLightGray"
android:paddingBottom="10dp"
android:textSize="20sp"
/>
android:layout_width="match_parent"
android:layout_height="match_parent">

<ImageView
android:id="@+id/splash_screen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/voting_pass_icon"
android:contentDescription="@string/app_name"
android:gravity="center"
/>
<TextView
android:id="@+id/text_splash_screen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/app_name"
android:textColor="@color/govLightGray"
android:paddingBottom="10dp"
android:textSize="20sp"
/>

<TextView
android:id="@+id/progress_current_task"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="@color/govLightGray"
android:textSize="20sp"
android:text="@string/initializing_text" />
<ImageView
android:id="@+id/splash_screen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/app_name"
android:gravity="center"
android:src="@drawable/voting_pass_icon" />

<ProgressBar
android:id="@+id/download_progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:minHeight="30dp"
android:layout_width="match_parent"
android:gravity="center"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/progress_current_task"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="@color/govLightGray"
android:textSize="20sp"
android:text="@string/initializing_text" />

<TextView
android:id="@+id/download_progress_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="@color/govLightGray"
android:textSize="20sp" />
</LinearLayout>
<ProgressBar
android:id="@+id/download_progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:minHeight="30dp"
android:layout_width="match_parent"
android:gravity="center"
android:layout_height="wrap_content" />

<TextView
android:id="@+id/download_progress_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="@color/govLightGray"
android:textSize="20sp" />
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
3 changes: 3 additions & 0 deletions app/src/main/res/values-nl/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@
<!--Splash Activity-->
<string name="downloading_text">Downloaden...</string>
<string name="initializing_text">Initialiseren...</string>
<string name="please_enable_connect_message">Activeer de internet verbinding</string>
<string name="no_connection">Geen Internet</string>
<string name="go_network_settings">WIFI Instellingen</string>
<string-array name="init_array">
<item>Initialiseren</item>
<item>\u00A0Initialiseren.</item>
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@
<!--Splash Activity-->
<string name="downloading_text">Downloading...</string>
<string name="initializing_text">Initializing...</string>
<string name="please_enable_connect_message">Please enable network connection</string>
<string name="no_connection">No Network</string>
<string name="go_network_settings">WIFI Settings</string>
<string-array name="init_array">
<item>Initializing</item>
<item>\u00A0Initializing.</item>
Expand All @@ -119,7 +122,6 @@
<string name="transaction_received_item_format_detail">From %s</string>
<string name="transaction_sent_item_format_title">Sent %1$d vote \n%2$s %3$s</string>
<string name="transaction_sent_item_format_detail">To %s</string>

<string-array name="address_array">
<item>1GoqgbPZUV2yuPZXohtAvB2NZbjcew8Rk93mMn|Government</item>
</string-array>
Expand Down

0 comments on commit 5fc0fe6

Please sign in to comment.