diff --git a/app/build.gradle b/app/build.gradle
index 897d30f..c8a9f62 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -6,7 +6,7 @@ android {
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.example.applogin"
- minSdkVersion 15
+ minSdkVersion 16
targetSdkVersion 29
versionCode 1
versionName "1.0"
@@ -22,14 +22,13 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
+ implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.0.0'
- implementation 'androidx.annotation:annotation:1.0.2'
+ implementation 'androidx.annotation:annotation:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
- implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
- implementation 'com.google.firebase:firebase-messaging:17.3.4'
+ implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
+ implementation 'com.google.firebase:firebase-messaging:20.1.0'
testImplementation 'junit:junit:4.12'
- androidTestImplementation 'androidx.test.ext:junit:1.1.0'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
- implementation 'com.android.volley:volley:1.1.1'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
diff --git a/app/google-services.json b/app/google-services.json
index 21b99d7..6b13d26 100644
--- a/app/google-services.json
+++ b/app/google-services.json
@@ -14,6 +14,14 @@
}
},
"oauth_client": [
+ {
+ "client_id": "151349644451-8jsl5et8sopsa1l4tmnak31cumrr9u3b.apps.googleusercontent.com",
+ "client_type": 1,
+ "android_info": {
+ "package_name": "com.example.applogin",
+ "certificate_hash": "e1a0e69f1e3d968c6e4de49ee01928f235a6801d"
+ }
+ },
{
"client_id": "151349644451-mnpur4ea4fv7g18h6uu9p8o5b00bs5jb.apps.googleusercontent.com",
"client_type": 1,
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a792adc..30e03d4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -26,10 +26,11 @@
+
+ android:exported="false" >
diff --git a/app/src/main/java/com/example/applogin/ChargingActivity.java b/app/src/main/java/com/example/applogin/ChargingActivity.java
index d455129..f394d77 100644
--- a/app/src/main/java/com/example/applogin/ChargingActivity.java
+++ b/app/src/main/java/com/example/applogin/ChargingActivity.java
@@ -2,17 +2,24 @@ package com.example.applogin;
import androidx.appcompat.app.AppCompatActivity;
+import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.widget.TextView;
-import java.util.Timer;
+import com.example.applogin.model.User;
+import com.example.applogin.network.GetUserTask;
+import com.example.applogin.ui.login.ConfirmationActivity;
+
+import java.util.concurrent.ExecutionException;
public class ChargingActivity extends AppCompatActivity {
TextView coundownTime;
TextView chargeState;
+ Thread pollingThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -30,14 +37,78 @@ public class ChargingActivity extends AppCompatActivity {
int minutesLeft = (secondsLeft % 3600)/60;
secondsLeft %= 60;
- coundownTime.setText("Time remaining: " + String.format("%d:%d:%02d", hoursLeft, minutesLeft,secondsLeft));
+ coundownTime.setText("Time remaining: " + String.format("%d:%d:%02d", hoursLeft, minutesLeft, secondsLeft));
}
public void onFinish() {
End_criteria();
}
}.start();
+
+ final SharedPreferences preferences = getApplicationContext().getSharedPreferences("scheduler_preferences", Context.MODE_PRIVATE);
+ final long timeInterval = 2000;
+ Runnable runnable = new Runnable() {
+
+ public void run() {
+ boolean changed = false;
+ while (!changed) {
+
+ GetUserTask task = new GetUserTask(preferences.getString("api_key", null));
+ task.execute();
+ try {
+ User user = task.get();
+
+ Intent intent;
+ switch(user.getState()){
+ case inactive:
+ intent = new Intent(ChargingActivity.this, JoinQueueActivity.class);
+ startActivity(intent);
+ changed = true;
+ break;
+ case in_queue:
+ intent = new Intent(ChargingActivity.this, WaitingActivity.class);
+ startActivity(intent);
+ changed = true;
+ break;
+ case assigned:
+ intent = new Intent(ChargingActivity.this, ConfirmationActivity.class);
+ startActivity(intent);
+ changed = true;
+ break;
+ case connected_full:
+ intent = new Intent(ChargingActivity.this, FullActivity.class);
+ startActivity(intent);
+ changed = true;
+ break;
+ }
+
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ try {
+ Thread.sleep(timeInterval);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ };
+
+ pollingThread = new Thread(runnable);
+ pollingThread.start();
}
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if(pollingThread.isAlive()){
+ pollingThread.interrupt();
+ }
+ }
+
//Move vehicle if timer runs out or the car is full (need to add the car full situation)
private void End_criteria()
{
diff --git a/app/src/main/java/com/example/applogin/EVFirebase.java b/app/src/main/java/com/example/applogin/EVFirebase.java
index 910e3ba..9b983aa 100644
--- a/app/src/main/java/com/example/applogin/EVFirebase.java
+++ b/app/src/main/java/com/example/applogin/EVFirebase.java
@@ -1,28 +1,27 @@
package com.example.applogin;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.content.Context;
+import android.content.Intent;
import android.content.SharedPreferences;
+import android.os.Build;
import android.widget.Toast;
-import com.android.volley.AuthFailureError;
-import com.android.volley.Request;
-import com.android.volley.RequestQueue;
-import com.android.volley.Response;
-import com.android.volley.VolleyError;
-import com.android.volley.toolbox.JsonObjectRequest;
-import com.android.volley.toolbox.Volley;
+import androidx.annotation.NonNull;
+import androidx.core.app.NotificationCompat;
+
+import com.example.applogin.network.UpdateNotificationTask;
import com.google.firebase.messaging.FirebaseMessagingService;
+import com.google.firebase.messaging.RemoteMessage;
-import org.json.JSONObject;
-
-import java.util.HashMap;
-import java.util.Map;
+import java.util.concurrent.ExecutionException;
public class EVFirebase extends FirebaseMessagingService {
@Override
public void onNewToken(String token) {
-
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
@@ -32,41 +31,43 @@ public class EVFirebase extends FirebaseMessagingService {
public void sendRegistrationToServer(String token){
- // Instantiate the RequestQueue.
- RequestQueue queue = Volley.newRequestQueue(this);
- String url ="https://ev-scheduler.appspot.com/api/user";
+ SharedPreferences preferences = getApplicationContext().getSharedPreferences("scheduler_preferences", Context.MODE_PRIVATE);
- HashMap dict = new HashMap<>();
- dict.put("notification_token", token);
- JSONObject json = new JSONObject(dict);
+ UpdateNotificationTask task = new UpdateNotificationTask(token, preferences.getString("api_key", null));
- // Request a string response from the provided URL.
- final JsonObjectRequest stringRequest = new JsonObjectRequest(Request.Method.PUT, url, json,
- new Response.Listener() {
- @Override
- public void onResponse(JSONObject response) {
-
- }
- }, new Response.ErrorListener() {
- @Override
- public void onErrorResponse(VolleyError error) {
- Toast.makeText(EVFirebase.this, Integer.toString(error.networkResponse.statusCode), Toast.LENGTH_SHORT).show();
+ task.execute();
+ try {
+ if(!task.get()){
+ Toast.makeText(EVFirebase.this, "error sending notification token", Toast.LENGTH_SHORT).show();
+ }else{
+ Toast.makeText(EVFirebase.this, "notification sent", Toast.LENGTH_SHORT).show();
}
- }){
-
- @Override
- public Map getHeaders() throws AuthFailureError {
-
- HashMap headers = new HashMap<>();
- SharedPreferences context = getApplicationContext().getSharedPreferences("scheduler_preferences", Context.MODE_PRIVATE);
- headers.put("Authorization", "Bearer " + context.getString("api_key", ""));
- return headers;
-
- }
-
- };
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
}
+ @Override
+ public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
+ super.onMessageReceived(remoteMessage);
+ Intent intent = new Intent(this, JoinQueueActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
+ String channelId = "Default";
+ NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId)
+ .setSmallIcon(R.mipmap.ic_launcher)
+ .setContentTitle(remoteMessage.getNotification().getTitle())
+ .setContentText(remoteMessage.getNotification().getBody()).setAutoCancel(true).setContentIntent(pendingIntent);;
+ NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ NotificationChannel channel = new NotificationChannel(channelId, "Scheduler", NotificationManager.IMPORTANCE_DEFAULT);
+ manager.createNotificationChannel(channel);
+ }
+ manager.notify(0, builder.build());
+ }
+
}
diff --git a/app/src/main/java/com/example/applogin/FullActivity.java b/app/src/main/java/com/example/applogin/FullActivity.java
new file mode 100644
index 0000000..3645f62
--- /dev/null
+++ b/app/src/main/java/com/example/applogin/FullActivity.java
@@ -0,0 +1,90 @@
+package com.example.applogin;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.os.CountDownTimer;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.example.applogin.model.User;
+import com.example.applogin.network.GetUserTask;
+
+import java.util.concurrent.ExecutionException;
+
+public class FullActivity extends AppCompatActivity {
+
+ Thread pollingThread;
+ CountDownTimer timer;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_full);
+
+ final SharedPreferences preferences = getApplicationContext().getSharedPreferences("scheduler_preferences", Context.MODE_PRIVATE);
+ final long timeInterval = 2000;
+ Runnable runnable = new Runnable() {
+
+ public void run() {
+ boolean changed = false;
+ while (!changed) {
+
+ GetUserTask task = new GetUserTask(preferences.getString("api_key", null));
+ task.execute();
+ try {
+ User user = task.get();
+
+ Intent intent;
+ switch(user.getState()){
+ case inactive:
+ intent = new Intent(FullActivity.this, JoinQueueActivity.class);
+ startActivity(intent);
+ changed = true;
+ break;
+ case in_queue:
+ intent = new Intent(FullActivity.this, WaitingActivity.class);
+ startActivity(intent);
+ changed = true;
+ break;
+ case assigned:
+ intent = new Intent(FullActivity.this, PluginWait_Activity.class);
+ startActivity(intent);
+ changed = true;
+ break;
+ case connected_charging:
+ intent = new Intent(FullActivity.this, ChargingActivity.class);
+ startActivity(intent);
+ changed = true;
+ break;
+ }
+
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ try {
+ Thread.sleep(timeInterval);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ };
+
+ pollingThread = new Thread(runnable);
+ pollingThread.start();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if(pollingThread.isAlive()){
+ pollingThread.interrupt();
+ }
+ timer.cancel();
+ }
+}
diff --git a/app/src/main/java/com/example/applogin/JoinQueueActivity.java b/app/src/main/java/com/example/applogin/JoinQueueActivity.java
index 11b2e00..df4a0f5 100644
--- a/app/src/main/java/com/example/applogin/JoinQueueActivity.java
+++ b/app/src/main/java/com/example/applogin/JoinQueueActivity.java
@@ -1,6 +1,5 @@
package com.example.applogin;
-import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
@@ -11,24 +10,10 @@ import android.view.View;
import android.widget.Button;
import android.widget.Toast;
-import com.android.volley.AuthFailureError;
-import com.android.volley.Request;
-import com.android.volley.RequestQueue;
-import com.android.volley.Response;
-import com.android.volley.VolleyError;
-import com.android.volley.toolbox.JsonObjectRequest;
-import com.android.volley.toolbox.Volley;
-import com.example.applogin.ui.login.LoginActivity;
-import com.google.android.gms.tasks.OnCompleteListener;
-import com.google.android.gms.tasks.Task;
-import com.google.firebase.iid.FirebaseInstanceId;
-import com.google.firebase.iid.InstanceIdResult;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.util.HashMap;
-import java.util.Map;
+import com.example.applogin.model.User;
+import com.example.applogin.network.GetUserTask;
+import com.example.applogin.network.QueueTask;
+import java.util.concurrent.ExecutionException;
public class JoinQueueActivity extends AppCompatActivity {
@@ -37,69 +22,48 @@ public class JoinQueueActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_join_queue);
- FirebaseInstanceId.getInstance().getInstanceId()
- .addOnCompleteListener(new OnCompleteListener() {
- @Override
- public void onComplete(@NonNull Task task) {
- if (!task.isSuccessful()) {
- return;
- }
-
- // Get new Instance ID token
- String token = task.getResult().getToken();
-
- // Instantiate the RequestQueue.
- RequestQueue network_queue = Volley.newRequestQueue(JoinQueueActivity.this);
- String url ="https://ev-scheduler.appspot.com/api/user";
-
- HashMap dict = new HashMap<>();
- dict.put("notification_token", token);
- JSONObject json = new JSONObject(dict);
-
- // Request a string response from the provided URL.
- final JsonObjectRequest stringRequest = new JsonObjectRequest(Request.Method.PUT, url, json,
- new Response.Listener() {
- @Override
- public void onResponse(JSONObject response) {
- Toast.makeText(JoinQueueActivity.this, "token sent", Toast.LENGTH_SHORT).show();
- }
- },
- new Response.ErrorListener() {
- @Override
- public void onErrorResponse(VolleyError error) {
- Toast.makeText(JoinQueueActivity.this, Integer.toString(error.networkResponse.statusCode), Toast.LENGTH_SHORT).show();
- //Put error message (failed login, 3 different messages)
- //if error.networkResponse.statusCode == 401 , message wrong password (auth_blueprint.py)
- }
- }){
-
- @Override
- public Map getHeaders() throws AuthFailureError {
-
- HashMap headers = new HashMap<>();
- SharedPreferences context = getApplicationContext().getSharedPreferences("scheduler_preferences", Context.MODE_PRIVATE);
- headers.put("Authorization", "Bearer " + context.getString("api_key", ""));
- return headers;
-
- }
-
- };
- network_queue.add(stringRequest);
-
- }
- });
-
-
-
final Button joinButton = findViewById(R.id.join_queue);
joinButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- //Toast.makeText(JoinQueueActivity.this, "testtttt", Toast.LENGTH_SHORT).show();
- Intent myIntent = new Intent(JoinQueueActivity.this, WaitingActivity.class);
- startActivity(myIntent);
+ SharedPreferences preferences = getApplicationContext().getSharedPreferences("scheduler_preferences", Context.MODE_PRIVATE);
+ QueueTask task = new QueueTask("location1", preferences.getString("api_key", null));
+
+ task.execute();
+
+ try {
+ if (task.get()){
+ Intent myIntent = new Intent(JoinQueueActivity.this, WaitingActivity.class);
+ startActivity(myIntent);
+ }
+ else{
+ Toast.makeText(JoinQueueActivity.this, "error queueing", Toast.LENGTH_SHORT).show();
+ }
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
}
});
+
+ SharedPreferences preferences = getApplicationContext().getSharedPreferences("scheduler_preferences", Context.MODE_PRIVATE);
+ GetUserTask task = new GetUserTask(preferences.getString("api_key", null));
+
+ task.execute();
+ try {
+ User user = task.get();
+
+ if(user.getState() != User.State.inactive){
+ joinButton.setEnabled(false);
+ }
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
}
}
diff --git a/app/src/main/java/com/example/applogin/Login2Activity.java b/app/src/main/java/com/example/applogin/Login2Activity.java
index 9c3b3a9..06feb2b 100644
--- a/app/src/main/java/com/example/applogin/Login2Activity.java
+++ b/app/src/main/java/com/example/applogin/Login2Activity.java
@@ -1,5 +1,6 @@
package com.example.applogin;
+import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
@@ -13,13 +14,25 @@ import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
+import android.widget.ProgressBar;
import android.widget.Toast;
+import com.example.applogin.model.User;
+import com.example.applogin.network.GetUserTask;
import com.example.applogin.network.LoginTask;
+import com.example.applogin.network.UpdateNotificationTask;
+import com.example.applogin.ui.login.ConfirmationActivity;
+import com.google.android.gms.tasks.OnCompleteListener;
+import com.google.android.gms.tasks.Task;
+import com.google.firebase.iid.FirebaseInstanceId;
+import com.google.firebase.iid.InstanceIdResult;
+
import java.util.concurrent.ExecutionException;
public class Login2Activity extends AppCompatActivity {
+ ProgressBar loading;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -45,6 +58,7 @@ public class Login2Activity extends AppCompatActivity {
final Button signInButton = findViewById(R.id.login);
final EditText usernameEditText = findViewById(R.id.username);
final EditText passwordEditText = findViewById(R.id.password);
+ loading = findViewById(R.id.loading);
signInButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -78,11 +92,12 @@ public class Login2Activity extends AppCompatActivity {
private void tryLogin(String username, String password) {
- LoginTask task = new LoginTask(username, password);
+ NativeLoginTask task = new NativeLoginTask(username, password);
+
task.execute();
try {
- String result = task.get();
+ final String result = task.get();
if (result == null) {
@@ -94,8 +109,60 @@ public class Login2Activity extends AppCompatActivity {
SharedPreferences.Editor editor = context.edit();
editor.putString("api_key", result);
editor.apply();
- Intent myIntent = new Intent(Login2Activity.this, JoinQueueActivity.class);
- startActivity(myIntent);
+
+ FirebaseInstanceId.getInstance().getInstanceId()
+ .addOnCompleteListener(new OnCompleteListener() {
+ @Override
+ public void onComplete(@NonNull Task task) {
+ if (!task.isSuccessful()) {
+ return;
+ }
+
+ // Get new Instance ID token
+ String token = task.getResult().getToken();
+
+ UpdateNotificationTask sendToken = new UpdateNotificationTask(token, result);
+ sendToken.execute();
+ try {
+ if(!sendToken.get()){
+ Toast.makeText(Login2Activity.this, "error sending token", Toast.LENGTH_SHORT).show();
+ }
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ }
+ });
+
+ GetUserTask userTask = new GetUserTask(result);
+ userTask.execute();
+
+ User user = userTask.get();
+ Intent intent;
+ switch(user.getState()){
+ case inactive:
+ intent = new Intent(Login2Activity.this, JoinQueueActivity.class);
+ startActivity(intent);
+ break;
+ case in_queue:
+ intent = new Intent(Login2Activity.this, WaitingActivity.class);
+ startActivity(intent);
+ break;
+ case assigned:
+ intent = new Intent(Login2Activity.this, ConfirmationActivity.class);
+ startActivity(intent);
+ break;
+ case connected_charging:
+ intent = new Intent(Login2Activity.this, ChargingActivity.class);
+ startActivity(intent);
+ break;
+ case connected_full:
+ intent = new Intent(Login2Activity.this, FullActivity.class);
+ startActivity(intent);
+ break;
+ }
}
} catch (ExecutionException e) {
@@ -106,5 +173,24 @@ public class Login2Activity extends AppCompatActivity {
}
+ class NativeLoginTask extends LoginTask {
+
+ public NativeLoginTask(String username, String password){
+ super(username, password);
+ }
+
+ @Override
+ protected void onPreExecute(){
+ loading.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ protected void onPostExecute(String result){
+ loading.setVisibility(View.INVISIBLE);
+ }
+ }
+
}
+
+
diff --git a/app/src/main/java/com/example/applogin/PluginWait_Activity.java b/app/src/main/java/com/example/applogin/PluginWait_Activity.java
index 79548ed..d871122 100644
--- a/app/src/main/java/com/example/applogin/PluginWait_Activity.java
+++ b/app/src/main/java/com/example/applogin/PluginWait_Activity.java
@@ -2,36 +2,128 @@ package com.example.applogin;
import androidx.appcompat.app.AppCompatActivity;
+import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.widget.TextView;
+import android.widget.Toast;
+import com.example.applogin.model.User;
+import com.example.applogin.network.GetUserTask;
+import com.example.applogin.network.KillSessionTask;
import com.example.applogin.ui.login.ConfirmationActivity;
+import java.util.concurrent.ExecutionException;
+
public class PluginWait_Activity extends AppCompatActivity {
+ Thread pollingThread;
+ CountDownTimer timer;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_plugin_wait_);
- final TextView acceptCoundown = findViewById(R.id.accept_timer);
+ final TextView acceptCoundown = findViewById(R.id.plugin_countdown);
- new CountDownTimer(900000, 1000) {
+ timer = new CountDownTimer(900000, 1000) {
public void onTick(long millisUntilFinished) {
int secondsLeft = (int) millisUntilFinished / 1000;
int minutesLeft = secondsLeft / 60;
secondsLeft %= 60;
- acceptCoundown.setText("Time remaining: " + String.format("%d:%02d", minutesLeft,secondsLeft));
+ acceptCoundown.setText("Time remaining: " + String.format("%d:%02d", minutesLeft, secondsLeft));
}
public void onFinish() {
- Intent myIntent = new Intent(PluginWait_Activity.this, JoinQueueActivity.class);
- startActivity(myIntent);
+
+ SharedPreferences preferences = getApplicationContext().getSharedPreferences("scheduler_preferences", Context.MODE_PRIVATE);
+ KillSessionTask task = new KillSessionTask("location1", "charger1", preferences.getString("api_key", null));
+
+ task.execute();
+
+ try {
+ if(task.get()){
+ Intent myIntent = new Intent(PluginWait_Activity.this, JoinQueueActivity.class);
+ startActivity(myIntent);
+ }else{
+ Toast.makeText(PluginWait_Activity.this, "error killing session", Toast.LENGTH_SHORT).show();
+ }
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
}
}.start();
+
+
+ final SharedPreferences preferences = getApplicationContext().getSharedPreferences("scheduler_preferences", Context.MODE_PRIVATE);
+ final long timeInterval = 2000;
+ Runnable runnable = new Runnable() {
+
+ public void run() {
+ boolean changed = false;
+ while (!changed) {
+
+ GetUserTask task = new GetUserTask(preferences.getString("api_key", null));
+ task.execute();
+ try {
+ User user = task.get();
+
+ Intent intent;
+ switch(user.getState()){
+ case inactive:
+ intent = new Intent(PluginWait_Activity.this, JoinQueueActivity.class);
+ startActivity(intent);
+ changed = true;
+ break;
+ case in_queue:
+ intent = new Intent(PluginWait_Activity.this, WaitingActivity.class);
+ startActivity(intent);
+ changed = true;
+ break;
+ case connected_charging:
+ intent = new Intent(PluginWait_Activity.this, ChargingActivity.class);
+ startActivity(intent);
+ changed = true;
+ break;
+ case connected_full:
+ intent = new Intent(PluginWait_Activity.this, FullActivity.class);
+ startActivity(intent);
+ changed = true;
+ break;
+ }
+
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ try {
+ Thread.sleep(timeInterval);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ };
+
+ pollingThread = new Thread(runnable);
+ pollingThread.start();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if(pollingThread.isAlive()){
+ pollingThread.interrupt();
+ }
+ timer.cancel();
}
}
diff --git a/app/src/main/java/com/example/applogin/WaitingActivity.java b/app/src/main/java/com/example/applogin/WaitingActivity.java
index 1ccec3a..0108a65 100644
--- a/app/src/main/java/com/example/applogin/WaitingActivity.java
+++ b/app/src/main/java/com/example/applogin/WaitingActivity.java
@@ -2,20 +2,26 @@ package com.example.applogin;
import androidx.appcompat.app.AppCompatActivity;
+import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
+import com.example.applogin.model.User;
+import com.example.applogin.network.GetUserTask;
import com.example.applogin.ui.login.ConfirmationActivity;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.ExecutionException;
public class WaitingActivity extends AppCompatActivity {
List queue;
TextView queuePosition;
+ Thread pollingThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -28,6 +34,61 @@ public class WaitingActivity extends AppCompatActivity {
//do initial update
UpdateQueue();
+
+ final SharedPreferences preferences = getApplicationContext().getSharedPreferences("scheduler_preferences", Context.MODE_PRIVATE);
+ final long timeInterval = 2000;
+ Runnable runnable = new Runnable() {
+
+ public void run() {
+ boolean changed = false;
+ while (!changed) {
+
+ GetUserTask task = new GetUserTask(preferences.getString("api_key", null));
+ task.execute();
+ try {
+ User user = task.get();
+
+ Intent intent;
+ switch(user.getState()){
+ case inactive:
+ intent = new Intent(WaitingActivity.this, JoinQueueActivity.class);
+ startActivity(intent);
+ changed = true;
+ break;
+ case assigned:
+ intent = new Intent(WaitingActivity.this, ConfirmationActivity.class);
+ startActivity(intent);
+ changed = true;
+ break;
+ case connected_charging:
+ intent = new Intent(WaitingActivity.this, ChargingActivity.class);
+ startActivity(intent);
+ changed = true;
+ break;
+ case connected_full:
+ intent = new Intent(WaitingActivity.this, FullActivity.class);
+ startActivity(intent);
+ changed = true;
+ break;
+ }
+
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ try {
+ Thread.sleep(timeInterval);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ };
+
+ pollingThread = new Thread(runnable);
+ pollingThread.start();
}
//Need to fill in queue data, currently assuming we are first position in queue
private void UpdateQueue() {
@@ -42,4 +103,12 @@ public class WaitingActivity extends AppCompatActivity {
startActivity(myIntent);
}
}
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if(pollingThread.isAlive()){
+ pollingThread.interrupt();
+ }
+ }
}
diff --git a/app/src/main/java/com/example/applogin/network/KillSessionTask.java b/app/src/main/java/com/example/applogin/network/KillSessionTask.java
new file mode 100644
index 0000000..806eef2
--- /dev/null
+++ b/app/src/main/java/com/example/applogin/network/KillSessionTask.java
@@ -0,0 +1,28 @@
+package com.example.applogin.network;
+
+import java.util.HashMap;
+
+public class KillSessionTask extends AbstractNetworkTask {
+
+ private String api_key;
+ private String location_id;
+ private String charger_id;
+
+ public KillSessionTask(String location_id, String charger_id, String api_key){
+ super();
+ this.api_key = api_key;
+ this.location_id = location_id;
+ this.charger_id = charger_id;
+ }
+
+ @Override
+ protected Boolean doInBackground(Void... params) {
+
+ HashMap body = new HashMap<>();
+ body.put("state", "available");
+
+ Result result = makeAuthenticatedRequest(getAPIUrl(String.format("api/location/%s/charger/%s", location_id, charger_id)), HTTPMethod.PUT, body, null, api_key);
+ return 200 <= result.statusCode && result.statusCode < 300;
+
+ }
+}
diff --git a/app/src/main/java/com/example/applogin/network/LoginTask.java b/app/src/main/java/com/example/applogin/network/LoginTask.java
index 037bdf7..ba94239 100644
--- a/app/src/main/java/com/example/applogin/network/LoginTask.java
+++ b/app/src/main/java/com/example/applogin/network/LoginTask.java
@@ -6,8 +6,8 @@ import java.util.HashMap;
public class LoginTask extends AbstractNetworkTask {
- private String username;
- private String password;
+ protected String username;
+ protected String password;
public LoginTask(String username, String password){
super();
diff --git a/app/src/main/java/com/example/applogin/network/UpdateNotificationTask.java b/app/src/main/java/com/example/applogin/network/UpdateNotificationTask.java
new file mode 100644
index 0000000..3bdba18
--- /dev/null
+++ b/app/src/main/java/com/example/applogin/network/UpdateNotificationTask.java
@@ -0,0 +1,27 @@
+package com.example.applogin.network;
+
+import java.util.HashMap;
+
+public class UpdateNotificationTask extends AbstractNetworkTask {
+
+ private String api_key;
+ private String notification_key;
+
+ public UpdateNotificationTask(String notification_key, String api_key){
+ super();
+ this.notification_key = notification_key;
+ this.api_key = api_key;
+ }
+
+
+ @Override
+ protected Boolean doInBackground(Void... params) {
+
+ HashMap body = new HashMap<>();
+ body.put("notification_token", notification_key);
+
+ Result result = makeAuthenticatedRequest(getAPIUrl("api/user"), HTTPMethod.PUT, body, null, api_key);
+
+ return 200 <= result.statusCode && result.statusCode < 300;
+ }
+}
diff --git a/app/src/main/java/com/example/applogin/ui/login/ConfirmationActivity.java b/app/src/main/java/com/example/applogin/ui/login/ConfirmationActivity.java
index cb90606..dcccbb9 100644
--- a/app/src/main/java/com/example/applogin/ui/login/ConfirmationActivity.java
+++ b/app/src/main/java/com/example/applogin/ui/login/ConfirmationActivity.java
@@ -2,7 +2,9 @@ package com.example.applogin.ui.login;
import androidx.appcompat.app.AppCompatActivity;
+import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.View;
@@ -10,10 +12,12 @@ import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
-import com.example.applogin.ChargingActivity;
import com.example.applogin.JoinQueueActivity;
+import com.example.applogin.PluginWait_Activity;
import com.example.applogin.R;
-import com.example.applogin.WaitingActivity;
+import com.example.applogin.network.KillSessionTask;
+
+import java.util.concurrent.ExecutionException;
public class ConfirmationActivity extends AppCompatActivity {
@@ -33,7 +37,7 @@ public class ConfirmationActivity extends AppCompatActivity {
int minutesLeft = secondsLeft / 60;
secondsLeft %= 60;
- acceptCountdown.setText("Time Remaining: " + minutesLeft + ":" + secondsLeft);
+ acceptCountdown.setText(minutesLeft + ":" + secondsLeft);
}
public void onFinish() {
@@ -47,7 +51,7 @@ public class ConfirmationActivity extends AppCompatActivity {
@Override
public void onClick(View v) {
countdownTimer.cancel();
- Intent myIntent = new Intent(ConfirmationActivity.this, ChargingActivity.class);
+ Intent myIntent = new Intent(ConfirmationActivity.this, PluginWait_Activity.class);
startActivity(myIntent);
}
});
@@ -57,8 +61,25 @@ public class ConfirmationActivity extends AppCompatActivity {
@Override
public void onClick(View v) {
countdownTimer.cancel();
- Intent myIntent = new Intent(ConfirmationActivity.this, JoinQueueActivity.class);
- startActivity(myIntent);
+
+ SharedPreferences preferences = getApplicationContext().getSharedPreferences("scheduler_preferences", Context.MODE_PRIVATE);
+
+ KillSessionTask task = new KillSessionTask("location1", "charger1", preferences.getString("api_key", null));
+ task.execute();
+ try {
+ if(task.get()){
+ Intent myIntent = new Intent(ConfirmationActivity.this, JoinQueueActivity.class);
+ startActivity(myIntent);
+
+ }else{
+ Toast.makeText(ConfirmationActivity.this, "error cancelling session", Toast.LENGTH_SHORT).show();
+ }
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
}
});
}
diff --git a/app/src/main/res/drawable/greenbutton.xml b/app/src/main/res/drawable/greenbutton.xml
new file mode 100644
index 0000000..6ea88a2
--- /dev/null
+++ b/app/src/main/res/drawable/greenbutton.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/redbutton.xml b/app/src/main/res/drawable/redbutton.xml
new file mode 100644
index 0000000..2bb0eb8
--- /dev/null
+++ b/app/src/main/res/drawable/redbutton.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_charging.xml b/app/src/main/res/layout/activity_charging.xml
index 7a597c2..cfad557 100644
--- a/app/src/main/res/layout/activity_charging.xml
+++ b/app/src/main/res/layout/activity_charging.xml
@@ -18,12 +18,14 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Car charging"
+ android:textAlignment="center"
android:textSize="32dp">
diff --git a/app/src/main/res/layout/activity_confirmation.xml b/app/src/main/res/layout/activity_confirmation.xml
index 799031f..0b66585 100644
--- a/app/src/main/res/layout/activity_confirmation.xml
+++ b/app/src/main/res/layout/activity_confirmation.xml
@@ -10,24 +10,29 @@
+ android:padding="50dp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent">
-
+ android:text="Charging station available, accept within: "
+ android:textAlignment="center"
+ android:textSize="32dp">
-
+ android:text="time"
+ android:textAlignment="center"
+ android:textSize="32dp">
-
+ android:text="Accept"
+ android:textSize="30dp">
+
diff --git a/app/src/main/res/layout/activity_full.xml b/app/src/main/res/layout/activity_full.xml
new file mode 100644
index 0000000..97602a3
--- /dev/null
+++ b/app/src/main/res/layout/activity_full.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_join_queue.xml b/app/src/main/res/layout/activity_join_queue.xml
index 0e97dbd..8e72a4d 100644
--- a/app/src/main/res/layout/activity_join_queue.xml
+++ b/app/src/main/res/layout/activity_join_queue.xml
@@ -14,16 +14,18 @@
android:orientation="vertical">
diff --git a/app/src/main/res/layout/activity_login2.xml b/app/src/main/res/layout/activity_login2.xml
index 5c5da93..5749453 100644
--- a/app/src/main/res/layout/activity_login2.xml
+++ b/app/src/main/res/layout/activity_login2.xml
@@ -69,6 +69,7 @@
+ android:orientation="vertical"
+ android:padding="32dp">
+ android:textAlignment="center"
+ android:text="You have accepted a session waiting for plug-in">
+ android:textAlignment="center"
+ android:text="time">
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 7831a57..e49595d 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -4,4 +4,6 @@
#00574B
#D81B60
#3aa8c1
+ #C91900
+ #00D007
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 4e1ba15..9a18a72 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,5 +1,5 @@
- AppLogin
+ Smart Charger
Email
Password
diff --git a/build.gradle b/build.gradle
index f10a55f..63bc63e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,8 +7,8 @@ buildscript {
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.5.2'
- classpath 'com.google.gms:google-services:4.2.0'
+ classpath 'com.android.tools.build:gradle:3.5.3'
+ classpath 'com.google.gms:google-services:4.3.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files