diff --git a/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/ScoreHistory.java b/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/ScoreHistory.java index 6ebf418..fbb3748 100644 --- a/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/ScoreHistory.java +++ b/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/ScoreHistory.java @@ -12,6 +12,7 @@ import android.widget.Button; import android.widget.ListView; import android.widget.TextView; +import android.widget.Toast; import org.json.JSONException; import org.json.JSONObject; @@ -179,9 +180,11 @@ protected Void doInBackground(Void... params) { json = new JSONObject(); json.put(REQUEST_TYPE, ADD_POINTS); - json.put(CLIENT_POINTS, ADD_POINTS_TEST_125); - json.put(POINTS_ORIGIN, ADD_POINTS_TEST_125_ORIGIN); + json.put(POINTS_TO_ADD, ADD_POINTS_TEST_10); + json.put(POINTS_ORIGIN, ADD_POINTS_TEST_10_ORIGIN); json.put(CLIENT_NAME, bikerName); + // TODO: 27-Apr-16 so funciona quando é a joana a querer adicionar + json.put(USER_WIFI, "joao"); dataOutputStream = new DataOutputStream( @@ -194,12 +197,14 @@ protected Void doInBackground(Void... params) { dataOutputStream.writeUTF(json.toString()); // Thread will wait till server replies - String response = dataInputStream.readUTF(); - -// Toast.makeText(ScoreHistory.this, response, -// Toast.LENGTH_LONG).show(); + final String response = dataInputStream.readUTF(); + ScoreHistory.this.runOnUiThread(new Runnable() { + public void run() { + Toast.makeText(ScoreHistory.this, response, Toast.LENGTH_SHORT).show(); + } + }); // new BufferedWriter(new OutputStreamWriter(mySocketOutputStream, "UTF-8"))); diff --git a/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/UbiBikeApplication.java b/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/UbiBikeApplication.java index 2df13c9..79e6103 100644 --- a/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/UbiBikeApplication.java +++ b/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/UbiBikeApplication.java @@ -4,11 +4,30 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; - +import android.os.AsyncTask; +import android.os.Messenger; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; +import java.util.concurrent.ExecutionException; + +import pt.inesc.termite.wifidirect.SimWifiP2pManager; +import pt.inesc.termite.wifidirect.sockets.SimWifiP2pSocket; +import pt.inesc.termite.wifidirect.sockets.SimWifiP2pSocketServer; +import pt.ulisboa.tecnico.cmu.ubibike.domain.PointsTransfer; import static com.ubibike.Constants.*; @@ -21,6 +40,107 @@ public class UbiBikeApplication extends Application { private SharedPreferences prefs; private Editor editor; + /** + * + * WIFI DIRECT + */ + + + public SharedPreferences getPrefs() { + return prefs; + } + + public void setPrefs(SharedPreferences prefs) { + this.prefs = prefs; + } + + public Editor getEditor() { + return editor; + } + + public void setEditor(Editor editor) { + this.editor = editor; + } + + public SimWifiP2pManager getmManager() { + return mManager; + } + + public void setmManager(SimWifiP2pManager mManager) { + this.mManager = mManager; + } + + public SimWifiP2pManager.Channel getmChannel() { + return mChannel; + } + + public void setmChannel(SimWifiP2pManager.Channel mChannel) { + this.mChannel = mChannel; + } + + public Messenger getmService() { + return mService; + } + + public void setmService(Messenger mService) { + this.mService = mService; + } + + public SimWifiP2pSocketServer getmSrvSocket() { + return mSrvSocket; + } + + public void setmSrvSocket(SimWifiP2pSocketServer mSrvSocket) { + this.mSrvSocket = mSrvSocket; + } + + public SimWifiP2pSocket getmCliSocket() { + return mCliSocket; + } + + public void setmCliSocket(SimWifiP2pSocket mCliSocket) { + this.mCliSocket = mCliSocket; + } + + public UbiconnectActivity.ReceiveCommTask getmComm() { + return mComm; + } + + public void setmComm(UbiconnectActivity.ReceiveCommTask mComm) { + this.mComm = mComm; + } + + private SimWifiP2pManager mManager = null; + private SimWifiP2pManager.Channel mChannel = null; + private Messenger mService = null; + private boolean mBound = false; + private SimWifiP2pSocketServer mSrvSocket = null; + private SimWifiP2pSocket mCliSocket = null; + private UbiconnectActivity.ReceiveCommTask mComm = null; + + /** + * + * + * @return + */ + + + public boolean isContinueIncommingTask() { + return continueIncommingTask; + } + + public void setContinueIncommingTask(boolean continueIncommingTask) { + this.continueIncommingTask = continueIncommingTask; + } + + private boolean continueIncommingTask = true; + + public boolean ismBound() {return mBound;} + + public void setmBound(boolean mBound) {this.mBound = mBound;} + + private ArrayList pointsExchange = new ArrayList<>(); + // private HashMap coordinatesPerRide = new HashMap<>(); @@ -103,6 +223,15 @@ public void sendTrajectory(long distance, String date, long duration) { } + + public ArrayList getPointsExchange() { + return pointsExchange; + } + + public void setPointsExchange(ArrayList pointsExchange) { + this.pointsExchange = pointsExchange; + } + public void logout() { SharedPreferences pref = getSharedPreferences(SHARED_PREFERENCE_FILENAME, MODE_PRIVATE); SharedPreferences.Editor editor = pref.edit(); @@ -172,12 +301,23 @@ public String getBikerScore(boolean fromSharedPreferences) { prefs = getApplicationContext().getSharedPreferences(SHARED_PREFERENCE_FILENAME, MODE_PRIVATE); - String bikerScore = prefs.getString(PREF_BIKER_SCORE, PREF_BIKER_SCORE_DEFAULT); + String bikerScore = prefs.getString(PREF_BIKER_SCORE, _bikerScore); return bikerScore; } else { + + GetPoints getPointsTask = new GetPoints(); + // task.execute().get() is used to wait for the task to be executed + // so we can update the user score and score history + try { + getPointsTask.execute().get(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } return _bikerScore; } } @@ -222,51 +362,143 @@ public void cleanBikerScoreHistory() { editor.commit(); } -/* - /** - * Gets username of logged user from Shared Preferences - * @return username - */ -/* - public String getUsernameFromSP(){ - // creating an shared Preference file for the information to be stored - prefs = getApplicationContext().getSharedPreferences(SHARED_PREFERENCE_FILENAME, MODE_PRIVATE); - String username = prefs.getString(SP_USERNAME, null); - return username; - } -*/ -/* - public void bottomMenuClickAction(Activity activity){ - if(!(activity.getClass().isInstance(UserDashboard.class))){ - Button homeBtn = (Button) activity.findViewById(R.id.menu_bottom_home); - homeBtn.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - Intent intent = new Intent(getApplicationContext(), UserDashboard.class); - startActivity(intent); - } - }); - } + private class GetPoints extends AsyncTask { + private DataOutputStream dataOutputStream; + private DataInputStream dataInputStream; + private JSONObject json; + private Socket socket; + + @Override + protected Void doInBackground(Void... params) { + + + try { + socket = new Socket(); + InetAddress[] iNetAddress = InetAddress.getAllByName(SERVER_IP); + SocketAddress address = new InetSocketAddress(iNetAddress[0], SERVER_PORT); - if(!(activity.getClass().isInstance(Chat.class))){ - Button chatBtn = (Button) activity.findViewById(R.id.menu_bottom_messenger); - chatBtn.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - Intent intent = new Intent(getApplicationContext(), Chat.class); - startActivity(intent); + socket.setSoTimeout(5000); //timeout for all other I/O operations, 10s for example + socket.connect(address, 10000); //timeout for attempting connection, 20 s + +// socket = new Socket(SERVER_IP, SERVER_PORT); + } catch (IOException e) { + return null; } - }); - } - if(!(activity.getClass().isInstance(OptionsMenu.class))){ - Button optionsBtn = (Button) activity.findViewById(R.id.menu_bottom_options); - optionsBtn.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - Intent intent = new Intent(getApplicationContext(), OptionsMenu.class); - startActivity(intent); + try { + json = new JSONObject(); + json.put(REQUEST_TYPE, GET_POINTS); + json.put(CLIENT_NAME, _username); + + + dataOutputStream = new DataOutputStream( + socket.getOutputStream()); + + dataInputStream = new DataInputStream( + socket.getInputStream()); + + // transfer JSONObject as String to the server + dataOutputStream.writeUTF(json.toString()); + + // Thread will wait till server replies + String response = dataInputStream.readUTF(); + + + final JSONObject jsondata; + jsondata = new JSONObject(response); + + _bikerScore = jsondata.getString(POINTS); + + + + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } finally { + + // close socket + if (socket != null) { + try { + System.out.print("closing the socket"); + socket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + // close input stream + if (dataInputStream != null) { + try { + dataInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + // close output stream + if (dataOutputStream != null) { + try { + dataOutputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } } - }); + + return null; } - }*/ + } + + + +///* +// /** +// * Gets username of logged user from Shared Preferences +// * @return username +// */ +///* +// public String getUsernameFromSP(){ +// // creating an shared Preference file for the information to be stored +// prefs = getApplicationContext().getSharedPreferences(SHARED_PREFERENCE_FILENAME, MODE_PRIVATE); +// String username = prefs.getString(SP_USERNAME, null); +// return username; +// } +//*/ +///* +// public void bottomMenuClickAction(Activity activity){ +// if(!(activity.getClass().isInstance(UserDashboard.class))){ +// Button homeBtn = (Button) activity.findViewById(R.id.menu_bottom_home); +// homeBtn.setOnClickListener(new View.OnClickListener() { +// public void onClick(View v) { +// Intent intent = new Intent(getApplicationContext(), UserDashboard.class); +// startActivity(intent); +// } +// }); +// } +// +// if(!(activity.getClass().isInstance(Chat.class))){ +// Button chatBtn = (Button) activity.findViewById(R.id.menu_bottom_messenger); +// chatBtn.setOnClickListener(new View.OnClickListener() { +// public void onClick(View v) { +// Intent intent = new Intent(getApplicationContext(), Chat.class); +// startActivity(intent); +// } +// }); +// } +// +// if(!(activity.getClass().isInstance(OptionsMenu.class))){ +// Button optionsBtn = (Button) activity.findViewById(R.id.menu_bottom_options); +// optionsBtn.setOnClickListener(new View.OnClickListener() { +// public void onClick(View v) { +// Intent intent = new Intent(getApplicationContext(), OptionsMenu.class); +// startActivity(intent); +// } +// }); +// } +// }*/ } diff --git a/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/UbiRideMapsActivity.java b/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/UbiRideMapsActivity.java index d11294c..c452757 100644 --- a/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/UbiRideMapsActivity.java +++ b/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/UbiRideMapsActivity.java @@ -25,7 +25,7 @@ public class UbiRideMapsActivity extends CommonWithButtons implements OnMapReady private GoogleMap mMap; // - HashMap coordinatesPerRide = ((UbiBikeApplication) getApplication()).getCoordinatesPerRide(); + HashMap coordinatesPerRide = null; @Override protected void onCreate(Bundle savedInstanceState) { @@ -36,6 +36,8 @@ protected void onCreate(Bundle savedInstanceState) { TextView bikerNameTextView = (TextView) findViewById(R.id.biker_name); bikerNameTextView.setText(bikerName); + coordinatesPerRide = ((UbiBikeApplication) getApplication()).getCoordinatesPerRide(); + // Obtain the SupportMapFragment and get notified when the map is ready to be used. SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); @@ -68,15 +70,18 @@ public void onMyLocationChange(Location location) { CameraUpdate zoom=CameraUpdateFactory.zoomTo(17); mMap.moveCamera(center); mMap.animateCamera(zoom); - coordinatesPerRide.put(String.valueOf(location.getLatitude()), // latitude - String.valueOf(location.getLongitude())); // longitude - Log.d("latitude maps ", location.getLatitude()+""); - Log.d("longitude maps ", location.getLongitude()+""); - - // FIXME: 26-Apr-16 not sure if we can directly change coordinatesPerRide whitout a set - ((UbiBikeApplication) getApplication()).setCoordinatesPerRide(coordinatesPerRide); - // TODO: 26-Apr-16 tratar das verificações dos beacons aqui - // TODO: 26-Apr-16 por agora temos que criar uma ligação WIFI-DIRECT por activity + /** + * moved to CommonWithButtons + */ +// coordinatesPerRide.put(String.valueOf(location.getLatitude()), // latitude +// String.valueOf(location.getLongitude())); // longitude +// Log.d("latitude maps ", location.getLatitude()+""); +// Log.d("longitude maps ", location.getLongitude()+""); +// +// // FIXME: 26-Apr-16 not sure if we can directly change coordinatesPerRide without a set +// ((UbiBikeApplication) getApplication()).setCoordinatesPerRide(coordinatesPerRide); +// // TODO: 26-Apr-16 tratar das verificações dos beacons aqui +// // TODO: 26-Apr-16 por agora temos que criar uma ligação WIFI-DIRECT por activity } }); diff --git a/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/UbiconnectActivity.java b/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/UbiconnectActivity.java index 0dbfaac..3b7d927 100644 --- a/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/UbiconnectActivity.java +++ b/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/UbiconnectActivity.java @@ -1,6 +1,5 @@ package pt.ulisboa.tecnico.cmu.ubibike; -import android.app.Activity; import android.app.AlertDialog; import android.content.ComponentName; import android.content.Context; @@ -26,12 +25,19 @@ import org.json.JSONObject; import java.io.BufferedReader; +import java.io.DataInputStream; +import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.concurrent.ExecutionException; import pt.inesc.termite.wifidirect.SimWifiP2pBroadcast; import pt.inesc.termite.wifidirect.SimWifiP2pDevice; @@ -43,6 +49,7 @@ import pt.inesc.termite.wifidirect.sockets.SimWifiP2pSocketManager; import pt.inesc.termite.wifidirect.sockets.SimWifiP2pSocketServer; import pt.ulisboa.tecnico.cmu.ubibike.common.CommonWithButtons; +import pt.ulisboa.tecnico.cmu.ubibike.domain.PointsTransfer; import static com.ubibike.Constants.*; @@ -80,13 +87,17 @@ public class UbiconnectActivity extends CommonWithButtons implements // clientID, messages private HashMap> exchangedMessagesPerClient = new HashMap<>(); - // TODO: 24-Apr-16 get personName from Wifi-Direct private String personName; - // TODO: 24-Apr-16 get myName from Wifi-Direct private String myName; private Handler handler = new Handler(); + private String connectedUser; + private boolean decreasePointsResult; + private boolean addPointsResult; + private ArrayList pointsExchange = new ArrayList<>(); + private boolean continueIncommingTask = true; + public SimWifiP2pManager getManager() { return mManager; } @@ -106,6 +117,30 @@ public void onCreate(Bundle savedInstanceState) { guiSetButtonListeners(); guiUpdateInitState(); + app = ((UbiBikeApplication) getApplication()); + + mBound = app.ismBound(); + continueIncommingTask = app.isContinueIncommingTask(); + + + /** + * get common variables WIFI DIRECT + * + */ + + mManager = app.getmManager(); + mChannel = app.getmChannel(); + mService = app.getmService(); + mBound = app.ismBound(); + mSrvSocket = app.getmSrvSocket(); + mCliSocket = app.getmCliSocket(); + mComm = app.getmComm(); + + /** + * + * + */ + // Change color to current menu Button messengerBtn = (Button) findViewById(R.id.menu_bottom_ubiconnect); @@ -138,7 +173,7 @@ public void onCreate(Bundle savedInstanceState) { registerReceiver(mReceiver, filter); personView = (TextView)findViewById(R.id.person_name); - + personView.setText(""); peersList.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, @@ -156,11 +191,16 @@ public void onItemClick(AdapterView parent, View view, int position, AsyncTask.THREAD_POOL_EXECUTOR, personIp); + // disable clickability for the list + peersList.setClickable(false); + // person name - String displayMessage = personName + " - " + personIp; +// String displayMessage = personName + " - " + personIp; + String displayMessage = personName; - personView.setText(displayMessage); + personView.setText("Connected to - " + displayMessage); + connectedUser = personName; // if person exists on chat history, get exchanged messages if (exchangedMessagesPerClient.containsKey(personName) ){ // get all the messages exhanged with client personName @@ -177,6 +217,11 @@ public void onItemClick(AdapterView parent, View view, int position, } peersAdapter.notifyDataSetChanged(); + // activate text input + mTextInput.setEnabled(true); + mTextInput.setHint("Type a message.."); + findViewById(R.id.idSendPointsButton).setEnabled(true); + } }); @@ -190,8 +235,12 @@ public void onItemClick(AdapterView parent, View view, int position, public void run() { Intent intent = new Intent(UbiconnectActivity.this, SimWifiP2pService.class); - bindService(intent, mConnection, Context.BIND_AUTO_CREATE); - mBound = true; + if(!app.ismBound()) { + bindService(intent, mConnection, Context.BIND_AUTO_CREATE); + mBound = true; + app.setmBound(mBound); + + } // spawn the chat server background task new IncommingCommTask().executeOnExecutor( @@ -206,7 +255,47 @@ public void run() { @Override public void onPause() { super.onPause(); + + // TODO: 27-Apr-16 quando o WIFI-DIRECT estiver em todas as actividades, nao queremos fazer unbind + + if (mCliSocket != null) { + try { + mCliSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + mCliSocket = null; + + if (mSrvSocket != null) { + try { + mSrvSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + mSrvSocket = null; + + continueIncommingTask = false; + app.setContinueIncommingTask(continueIncommingTask); + + app.setmManager(mManager); + app.setmChannel(mChannel); + app.setmService(mService); + app.setmBound(mBound); + app.setmSrvSocket(mSrvSocket); + app.setmCliSocket(mCliSocket); + app.setmComm(mComm); + + + + } + @Override + public void onDestroy(){ + super.onDestroy(); + unregisterReceiver(mReceiver); + } @@ -238,7 +327,12 @@ public void onClick(View v){ unbindService(mConnection); mBound = false; guiUpdateInitState(); + + // clear list + allPeersArray.clear(); + peersAdapter.notifyDataSetChanged(); } + } }; @@ -265,21 +359,36 @@ public void onClick(View v){ String points = mTextInput.getText().toString(); try { - Log.d("sent points ", points); - // get text user wrote in the text box + + // check if the user can send the points (checks with the server (if it's online)) if (!checkPoints(points)) { return; } + String pointsOriginMessageToReceiver = "received " + points + " points from " + myName; + String pointsOriginMessageToMe = "sent " + points + " points to " + connectedUser; + // invoke the async task that connects to the server and decreases the points + + // TODO: 27-Apr-16 move this code to after the server lost connection +// decreasePoints(Integer.parseInt(points),pointsOriginMessageToMe); + + JSONObject json = new JSONObject(); // indicate that the user is sending a message (and it is not giving points) json.put(COMMUNICATION_TYPE_WIFI, GIVE_POINTS_WIFI); json.put(POINTS_WIFI, points); - json.put(USER_WIFI, "Ze To"); + json.put(USER_WIFI, myName); + json.put(POINTS_ORIGIN, pointsOriginMessageToReceiver); + + // create an PointsTransfer object that contains the transaction + PointsTransfer pts = new PointsTransfer(PointsTransfer.SENT_TO_A_PEER, Integer.parseInt(points), connectedUser, json); + // add the transaction to the pointsExchange log + pointsExchange.add(pts); // set as text the json created mCliSocket.getOutputStream().write((json.toString()+"\n").getBytes()); + Log.d("sent points ", points); } catch (JSONException e) { e.printStackTrace(); } catch (IOException e) { @@ -294,6 +403,13 @@ public void onClick(View v){ } }; + private boolean checkAvailablePoints(int pointsToGive) { + // assim ele vai perguntar ao server pelos pontos, se o server estiver offline, usa a "cache" +// int points = Integer.parseInt(app.getBikerScore(false)); + int points = Integer.parseInt(bikerScore); + + return (points - pointsToGive) >= 0; + } private View.OnClickListener listenerSendButton = new View.OnClickListener() { @@ -392,7 +508,7 @@ protected Void doInBackground(Void... params) { } catch (IOException e) { e.printStackTrace(); } - while (!Thread.currentThread().isInterrupted()) { + while ((!Thread.currentThread().isInterrupted()) && continueIncommingTask) { try { SimWifiP2pSocket sock = mSrvSocket.accept(); if (mCliSocket != null && mCliSocket.isClosed()) { @@ -416,6 +532,8 @@ protected Void doInBackground(Void... params) { @Override protected void onProgressUpdate(SimWifiP2pSocket... values) { mCliSocket = values[0]; + + // TODO: 27-Apr-16 ANOTHER USER HAS STARTED A CONVERSATION WITH YOU (ISABEL, vê isto) mComm = new ReceiveCommTask(); mComm.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, mCliSocket); @@ -508,9 +626,15 @@ protected void onPreExecute() { findViewById(R.id.idSendButton).setEnabled(true); findViewById(R.id.idDisconnectButton).setEnabled(true); // findViewById(R.id.idConnectButton).setEnabled(false); - mTextInput.setHint(""); - mTextInput.setText(""); + // activate text input + mTextInput.setEnabled(true); + mTextInput.setHint("Type a message.."); + findViewById(R.id.idSendPointsButton).setEnabled(true); + + // clear list + allPeersArray.clear(); + peersAdapter.notifyDataSetChanged(); } @Override @@ -525,6 +649,7 @@ protected void onProgressUpdate(String... values) { exchangedMessagesPerClient.get(personName).add(mMessage); peersAdapter.notifyDataSetChanged(); } + Log.d("esta no prog ", "progress"); } @@ -628,9 +753,16 @@ private void guiSetButtonListeners() { private void guiUpdateInitState() { mTextInput = (TextView) findViewById(R.id.editText1); - mTextInput.setHint("Type a message.."); + mTextInput.setHint(""); mTextInput.setEnabled(false); + bikerName = app.getUsername(); + pointsButton = (Button) findViewById(R.id.biker_score); + + + bikersNameTextView = (TextView) findViewById(R.id.biker_name); + bikersNameTextView.setText(bikerName); + // mTextOutput = (TextView) findViewById(R.id.editText2); // mTextOutput.setEnabled(false); // mTextOutput.setText(""); @@ -646,10 +778,10 @@ private void guiUpdateInitState() { private void guiUpdateDisconnectedState() { - mTextInput.setEnabled(true); - mTextInput.setHint("Type a message.."); // mTextOutput.setEnabled(true); // mTextOutput.setText(""); + mTextInput.setHint(""); + mTextInput.setEnabled(false); findViewById(R.id.idSendButton).setEnabled(false); // findViewById(R.id.idConnectButton).setEnabled(true); @@ -665,6 +797,9 @@ private void guiUpdateDisconnectedState() { peersAdapter.notifyDataSetChanged(); // remove connected user name personView.setText(""); + + peersList.setClickable(false); + } /** @@ -690,21 +825,22 @@ private boolean isMessageExchange(String receivedMessage) { // if the type is a give points, connect to the server and update my points } else if (type.equals(GIVE_POINTS_WIFI)) { // TODO: 22-Apr-16 implement this with chains - // get the points received + // get the points received String points = jsondata.getString(POINTS_WIFI); - // get the user that send the points - String origin = jsondata.getString(USER_WIFI); - // put the pair on the mPoints that keeps the history of the score - mPoints.put(points,origin); + // TODO: 27-Apr-16 user points sender when using digital signatures + // get the user that send the points + String pointsSender = jsondata.getString(USER_WIFI); + // get the origin of the received points + String origin = jsondata.getString(POINTS_ORIGIN); + // put the pair on the mPoints that keeps the history of the score + + applyReceivedPoints(points, origin, pointsSender, jsondata); Log.d("received pts ", points); - // // TODO: 24-Apr-16 change applyReceivedPoints - applyReceivedPoints(points); return false; } else if (type.equals(SEND_INFO_WIFI)) { personName = jsondata.getString(NAME_WIFI); - // TODO: 24-Apr-16 show messages only when user A chooses to see messages from B if (exchangedMessagesPerClient.containsKey(personName) ){ // get all the messages exhanged with client personName for (String msg : @@ -731,8 +867,14 @@ private boolean isMessageExchange(String receivedMessage) { } - private void applyReceivedPoints(String points) { - personView.setText(points); + private void applyReceivedPoints(String points, String pointsOrigin, String pointsSender, JSONObject json) { + // TODO: 27-Apr-16 move this line to after the connection with the peer is terminated +// addPoints(Integer.parseInt(points), pointsOrigin, pointsSender); + + // create an PointsTransfer object that contains the transaction + PointsTransfer pts = new PointsTransfer(PointsTransfer.EARNED_FROM_A_PEER, Integer.parseInt(points), connectedUser, json); + // add the transaction to the pointsExchange log + pointsExchange.add(pts); } @@ -745,16 +887,288 @@ private boolean checkPoints(String points) { Toast.LENGTH_SHORT).show(); return false; } - // TODO: 24-Apr-16 check user's points - boolean hasPoints = true; + // check if the user has enough points to give + boolean hasPoints = checkAvailablePoints(pointsInt); - if (pointsInt > 100) { + if (!hasPoints) { Toast.makeText(UbiconnectActivity.this, "Not enough points available!!", Toast.LENGTH_SHORT).show(); return false; } + Toast.makeText(UbiconnectActivity.this, "Seems to have enough points..", + Toast.LENGTH_SHORT).show(); + return true; } + private void decreasePoints(int points, String pointsOrigin) { + + DecreasePoints decreasePointsTask = new DecreasePoints(points, pointsOrigin); + // task.execute().get() is used to wait for the task to be executed + // so we can update the user score and score history + try { +// decreasePointsTask.execute().get(); + decreasePointsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR).get(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + } + + private class DecreasePoints extends AsyncTask { + private DataOutputStream dataOutputStream; + private DataInputStream dataInputStream; + private JSONObject json; + private Socket socket; + private int points; + private String pointsOrigin; + + public DecreasePoints(int points, String pointsOrigin) { + this.points = points; + this.pointsOrigin = pointsOrigin; + } + + @Override + protected Void doInBackground(Void... params) { + + + try { + Log.d("cheio disto", "cheio disto"); + socket = new Socket(); + InetAddress[] iNetAddress = InetAddress.getAllByName(SERVER_IP); + SocketAddress address = new InetSocketAddress(iNetAddress[0], SERVER_PORT); + + socket.setSoTimeout(5000); //timeout for all other I/O operations, 10s for example + Log.d("cheio disto", "cheio disto2"); + socket.connect(address, 10000); //timeout for attempting connection, 20 s + Log.d("cheio disto", "cheio disto3"); + +// socket = new Socket(SERVER_IP, SERVER_PORT); + } catch (IOException e) { + return null; + } + + try { + json = new JSONObject(); + json.put(REQUEST_TYPE, REMOVE_POINTS); + json.put(CLIENT_NAME, myName); + json.put(POINTS_TO_DECREASE, String.valueOf(points)); + json.put(POINTS_ORIGIN, pointsOrigin); + + dataOutputStream = new DataOutputStream( + socket.getOutputStream()); + + dataInputStream = new DataInputStream( + socket.getInputStream()); + + // transfer JSONObject as String to the server + dataOutputStream.writeUTF(json.toString()); + + // Thread will wait till server replies + String response = dataInputStream.readUTF(); + + if (!response.equals(POINTS_REMOVED)) { + decreasePointsResult = false; + } else { + decreasePointsResult = true; + } + + // TODO: 27-Apr-16 should we waint for the server response? + + + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } finally { + + // close socket + if (socket != null) { + try { + System.out.print("closing the socket"); + socket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + // close input stream + if (dataInputStream != null) { + try { + dataInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + // close output stream + if (dataOutputStream != null) { + try { + dataOutputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + return null; + } + @Override + protected void onPostExecute(Void result) { + super.onPostExecute(result); + + if(decreasePointsResult) { + pointsButton.setText(app.getBikerScore(false)); + + Toast.makeText(UbiconnectActivity.this, "Points decreased", + Toast.LENGTH_SHORT).show(); + } else + { + Toast.makeText(UbiconnectActivity.this, "Could NOT decrease the points", + Toast.LENGTH_SHORT).show(); + } + + } + + } + + +private void addPoints(int points, String pointsOrigin, String senderOfPoints) { + + AddPoints addPointsTask = new AddPoints(points, pointsOrigin, senderOfPoints); + // task.execute().get() is used to wait for the task to be executed + // so we can update the user score and score history + try { + addPointsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR).get(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + } + + private class AddPoints extends AsyncTask { + private DataOutputStream dataOutputStream; + private DataInputStream dataInputStream; + private JSONObject json; + private Socket socket; + private int points; + private String pointsOrigin; + private String senderOfPoints; + + public AddPoints(int points, String pointsOrigin, String senderOfPoints) { + this.points = points; + this.pointsOrigin = pointsOrigin; + this.senderOfPoints = senderOfPoints; + } + + @Override + protected Void doInBackground(Void... params) { + + + try { + socket = new Socket(); + InetAddress[] iNetAddress = InetAddress.getAllByName(SERVER_IP); + SocketAddress address = new InetSocketAddress(iNetAddress[0], SERVER_PORT); + + socket.setSoTimeout(5000); //timeout for all other I/O operations, 10s for example + socket.connect(address, 10000); //timeout for attempting connection, 20 s + +// socket = new Socket(SERVER_IP, SERVER_PORT); + } catch (IOException e) { + return null; + } + + try { + json = new JSONObject(); + json.put(REQUEST_TYPE, ADD_POINTS); + json.put(CLIENT_NAME, myName); + json.put(POINTS_TO_ADD, points); + json.put(POINTS_ORIGIN, pointsOrigin); + json.put(USER_WIFI, senderOfPoints); + + dataOutputStream = new DataOutputStream( + socket.getOutputStream()); + + dataInputStream = new DataInputStream( + socket.getInputStream()); + + // transfer JSONObject as String to the server + dataOutputStream.writeUTF(json.toString()); + + // Thread will wait till server replies + String response = dataInputStream.readUTF(); + if (!response.equals(POINTS_ADDED)) { + addPointsResult = false; + } else { + mPoints.put(String.valueOf(points), pointsOrigin); + + addPointsResult = true; + } + // TODO: 27-Apr-16 should we waint for the server response? + + + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } finally { + + // close socket + if (socket != null) { + try { + System.out.print("closing the socket"); + socket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + // close input stream + if (dataInputStream != null) { + try { + dataInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + // close output stream + if (dataOutputStream != null) { + try { + dataOutputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + return null; + } + + @Override + protected void onPostExecute(Void result) { + super.onPostExecute(result); + + if(addPointsResult) { + pointsButton.setText(app.getBikerScore(false)); + + Toast.makeText(UbiconnectActivity.this, "Points added", + Toast.LENGTH_SHORT).show(); + } else + { + Toast.makeText(UbiconnectActivity.this, "Could NOT add the points", + Toast.LENGTH_SHORT).show(); + } + + } + + } + } \ No newline at end of file diff --git a/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/UserDashboard.java b/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/UserDashboard.java index 0f3b0b9..1a0c656 100644 --- a/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/UserDashboard.java +++ b/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/UserDashboard.java @@ -33,6 +33,14 @@ protected void onCreate(Bundle savedInstanceState) { // getSupportActionBar().setDisplayHomeAsUpEnabled(true); } + @Override + public void onDestroy(){ + super.onDestroy(); + +// unregisterReceiver(mReceiver); + + } + @Override public void launchClick(View v) { diff --git a/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/common/CommonWithButtons.java b/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/common/CommonWithButtons.java index 0fb0d92..ef0b29c 100644 --- a/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/common/CommonWithButtons.java +++ b/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/common/CommonWithButtons.java @@ -1,24 +1,24 @@ package pt.ulisboa.tecnico.cmu.ubibike.common; +import android.Manifest; +import android.content.Context; import android.content.Intent; -import android.os.AsyncTask; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; import android.os.Bundle; import android.os.Handler; import android.os.SystemClock; +import android.support.v4.app.ActivityCompat; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; -import org.json.JSONException; -import org.json.JSONObject; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.net.Socket; -import java.net.UnknownHostException; +import java.util.HashMap; import pt.ulisboa.tecnico.cmu.ubibike.UbiconnectActivity; import pt.ulisboa.tecnico.cmu.ubibike.OptionsMenu; @@ -39,31 +39,30 @@ public class CommonWithButtons extends AppCompatActivity { protected Button pointsButton; protected TextView bikersNameTextView; protected Handler handler = new Handler(); - private Socket socket; + HashMap coordinatesPerRide = null; + protected MyLocationListener locationListener; + protected LocationManager lm; + protected UbiBikeApplication app; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_score_history); + app = ((UbiBikeApplication) getApplication()); // HEADER // biker name - bikerName = ((UbiBikeApplication) getApplication()).getUsername(); + bikerName = app.getUsername(); // Restore preferences - - UbiBikeApplication app = ((UbiBikeApplication) getApplication()); bikerScore = app.getBikerScore(true); - - + coordinatesPerRide = app.getCoordinatesPerRide(); // Views - pointsButton = (Button) findViewById(R.id.biker_score); - bikersNameTextView = (TextView)findViewById(R.id.biker_name); - + bikersNameTextView = (TextView) findViewById(R.id.biker_name); // Sets @@ -72,35 +71,28 @@ protected void onCreate(Bundle savedInstanceState) { // Get user current points and refresh Views - // TODO: 09-Apr-16 make UbiBikeApplication check score periodically - handler.postAtTime(timeTask, SystemClock.uptimeMillis() + 100); + // TODO: 09-Apr-16 make UbiBikeApplication check score + handler.postAtTime(requestScoreTask, SystemClock.uptimeMillis() + 100); + + + // get location updates + getLocationUpdates(); } - private Runnable timeTask = new Runnable() { + private Runnable requestScoreTask = new Runnable() { public void run() { - /* GetPoints getClientsTask = new GetPoints(); - // task.execute().get() is used to wait for the task to be executed - // so we can update the user score and score history - try { - getClientsTask.execute().get(); - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (ExecutionException e) { - e.printStackTrace(); - }*/ -// UbiBikeApplication app = ((UbiBikeApplication) getApplication()); -// bikerScore = app.getBikerScore(false); + bikerScore = app.getBikerScore(false); pointsButton = (Button) findViewById(R.id.biker_score); pointsButton.setText(bikerScore); // every 5 minutes calls the server to check for updates - // todo perguntar ao prof opiniao sobre isto (se ha maneira/vantagem em ser o server a iniciar a comunicacao -// handler.postAtTime(timeTask, SystemClock.uptimeMillis() + 300000 ); + // todo perguntar ao prof opiniao sobre isto (se ha maneira/vantagem em ser o server a iniciar a comunicacao) +// handler.postAtTime(requestScoreTask, SystemClock.uptimeMillis() + 18000 ); } @@ -237,5 +229,54 @@ public void launchClick(View v) { startActivityForResult(intent, 0); } } + private final class MyLocationListener implements LocationListener { + + @Override + public void onLocationChanged(Location location) { + // called when the listener is notified with a location update from the GPS + String lat = String.valueOf(location.getLatitude()); // latitude + String lng = String.valueOf(location.getLongitude()); // longitude + + coordinatesPerRide.put(lat, lng); + Log.d("latitude maps ", lat); + Log.d("longitude maps ", lng); + + // FIXME: 26-Apr-16 not sure if we can directly change coordinatesPerRide without a set + app.setCoordinatesPerRide(coordinatesPerRide); + + } + + @Override + public void onProviderDisabled(String provider) { + // called when the GPS provider is turned off (user turning off the GPS on the phone) + } + + @Override + public void onProviderEnabled(String provider) { + // called when the GPS provider is turned on (user turning on the GPS on the phone) + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + // called when the status of the GPS provider changes + } + } + + private void getLocationUpdates() { + locationListener = new MyLocationListener(); + lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); + // check permissions + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + // TODO: Consider calling + // ActivityCompat#requestPermissions + // here to request the missing permissions, and then overriding + // public void onRequestPermissionsResult(int requestCode, String[] permissions, + // int[] grantResults) + // to handle the case where the user grants the permission. See the documentation + // for ActivityCompat#requestPermissions for more details. + return; + } + lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_CHECKING_PERIOD, GPS_CHECKING_DISTANCE, locationListener); + } } diff --git a/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/domain/PointsTranfer.java b/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/domain/PointsTransfer.java similarity index 64% rename from app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/domain/PointsTranfer.java rename to app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/domain/PointsTransfer.java index b516359..41ff7aa 100644 --- a/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/domain/PointsTranfer.java +++ b/app/src/main/java/pt/ulisboa/tecnico/cmu/ubibike/domain/PointsTransfer.java @@ -1,25 +1,29 @@ package pt.ulisboa.tecnico.cmu.ubibike.domain; +import org.json.JSONObject; + /** * This class represents all the data related to points lost and earned */ -public class PointsTranfer { +public class PointsTransfer { private int mode; private int points; private String peerUsername; - private String date; + + + private JSONObject json; //Constants - private static final int EARNED_FROM_A_PEER = 1; - private static final int EARNED_FROM_A_RIDE = 2; - private static final int SENT_TO_A_PEER = 3; + public static final int EARNED_FROM_A_PEER = 1; + public static final int EARNED_FROM_A_RIDE = 2; + public static final int SENT_TO_A_PEER = 3; - public PointsTranfer (int mode, int points, String peerUsername, String date) { + public PointsTransfer(int mode, int points, String peerUsername, JSONObject json) { this.mode = mode; this.points = points; this.peerUsername = peerUsername; - this.date = date; + this.json = json; } public int getMode() { @@ -46,11 +50,13 @@ public void setPeerUsername(String peerUsername) { this.peerUsername = peerUsername; } - public String getDate() { - return date; + + public JSONObject getJson() { + return json; } - public void setDate(String date) { - this.date = date; + public void setJson(JSONObject json) { + this.json = json; } + } diff --git a/app/src/main/res/layout/activity_list_users.xml b/app/src/main/res/layout/activity_list_users.xml index 431804e..ff48656 100644 --- a/app/src/main/res/layout/activity_list_users.xml +++ b/app/src/main/res/layout/activity_list_users.xml @@ -11,6 +11,35 @@ android:orientation="vertical" > + + + + + + + + + + android:layout_height="wrap_content" + android:gravity="center">