Kolejny tydzień konkursu przyniósł trochę usprawnień w kodzie aplikacji, web service i dodana została klasa pozwalająca pobierać aktualną lokalizację użytkownika w tle.
Co tam w Web Service piszczy?
Plik, którego dawno nie pokazywałem, nie ma go też na githubie, co zapewne w przyszłości zmienie, doczekał się wielu nowych linii kodu. Został też lekko zrefactorowany, może pamiętasz jak źle wyglądał ostatnio. Dodane zostały nowe operacje zgodnie z powstającymi potrzebami aplikacji. Nie był też niczym zabezpieczony – każdy mógł w przeglądarce wpisać link i coś pozmieniać. Kilku śmieszków skorzystało z tej okazji ( ͡° ͜ʖ ͡°). Od teraz każde zapytanie trzeba autoryzować kluczem. Kod Web Service prezentuję się następująco:
$key = SECRET; $meetHere = new MeetHere(); if (isset($_GET['key']) && $_GET['key'] == $key) { if (isset($_GET['user']) && intval($_GET['user'])) { $mysqli = $meetHere->newDbConnection(); $user_id = $_GET['user']; $user = $mysqli->query("SELECT * FROM `Users` WHERE `ID` = " . $user_id) or die("error while query"); $user_array = array(); while ($user_field = mysqli_fetch_row($user)) { $user_array['ID'] = $user_field[0]; $user_array['name'] = $user_field[1]; $user_array['surname'] = $user_field[2]; $user_array['email'] = $user_field[3]; $user_array['city'] = $user_field[4]; $user_array['dayOfBirthday'] = $user_field[5]; $user_array['lastLocalization'] = $user_field[6]; $user_array['createdAt'] = $user_field[7]; } $meetHere->encodeUserToJson($user_array); $meetHere->closeDbConnection($mysqli); } if (isset($_GET['saveLoc'])) { $mysqli = $meetHere->newDbConnection(); $user_id = $_GET['saveLoc']; $user_loc = $_GET['localization']; $mysqli->query('UPDATE `Users` SET `lastLocalization` = ' . '"' . $user_loc . '" WHERE `ID` = ' . $user_id); $meetHere->encodeJson("success", $user_id); $meetHere->closeDbConnection($mysqli); } if (isset($_GET['thatEmail'])) { $mysqli = $meetHere->newDbConnection(); $email = $_GET['thatEmail']; $result = $mysqli->query("SELECT * FROM `Users` WHERE `email` = '" . $email . "'"); if ($result->num_rows === 0) { $meetHere->encodeJson("success", 0); } else { while ($user_field = mysqli_fetch_row($result)) { $user_id = $user_field[0]; } $meetHere->encodeJson("fail", $user_id); } $meetHere->closeDbConnection($mysqli); } if (isset($_GET['addUser'])) { $mysqli = $meetHere->newDbConnection(); $user_name = $_GET['addUser']; $user_surname = $_GET['surname']; $user_email = $_GET['email']; $user_city = $_GET['city']; $user_dayOfBirthday = $_GET['dayOfBirthday']; $user_lastLocalization = $_GET['lastLocalization']; $mysqli->query('INSERT INTO `Users`(`name`, `surname`, `email`, `city`, `dayOfBirthday`, `lastLocalization`) VALUES ("' . $user_name . '", "' . $user_surname . '", "' . $user_email . '", "' . $user_city . '", "' . $user_dayOfBirthday . '", "' . $user_lastLocalization . '")'); $result = $mysqli->query("SELECT * FROM `Users` WHERE `email` = '" . $user_email . "'"); while ($user_field = mysqli_fetch_row($result)) { $user_id = $user_field[0]; } $meetHere->encodeJson("added", $user_id); $meetHere->closeDbConnection($mysqli); } if (isset($_GET['addFriend'])) { $mysqli = $meetHere->newDbConnection(); $user_id = $_GET['addFriend']; $friend_id = $_GET['friend']; $mysqli->query('INSERT INTO `Friends` (`friend1`, `friend2`) VALUES ("' . $user_id . '", "' . $friend_id . '")'); $mysqli->query('INSERT INTO `Friends` (`friend2`, `friend1`) VALUES ("' . $user_id . '", "' . $friend_id . '")'); $meetHere->encodeJson("success", $user_id); $meetHere->closeDbConnection($mysqli); } if (isset($_GET['getFriends'])) { $mysqli = $meetHere->newDbConnection(); $user_id = $_GET['getFriends']; $result = $mysqli->query('SELECT u.* FROM `Users` u LEFT JOIN `Friends` f ON f.friend2 = u.ID WHERE f.friend1 = "' . $user_id . '"'); $users = array(); $users_line = array(); $user_array = array(); $i = 0; while ($user_line = mysqli_fetch_assoc($result)) { $users_line = $user_line; while ($user_field = mysqli_fetch_row($user_line)) { $user_array['ID'] = $user_field[0]; $user_array['name'] = $user_field[1]; $user_array['surname'] = $user_field[2]; $user_array['email'] = $user_field[3]; $user_array['city'] = $user_field[4]; $user_array['dayOfBirthday'] = $user_field[5]; $user_array['lastLocalization'] = $user_field[6]; $user_array['createdAt'] = $user_field[7]; } $users[$i] = $user_line; $i++; } $meetHere->encodeUserToJson($users); $meetHere->closeDbConnection($mysqli); } if (isset($_GET['search'])) { $mysqli = $meetHere->newDbConnection(); $name = $_GET['search']; $surname = $_GET['surname']; $result = $mysqli->query('SELECT `ID`, `name`, `surname` FROM `Users` WHERE `name` LIKE "%' . $name . '%" OR `surname` LIKE "%' . $surname . '%"'); $users = array(); $users_line = array(); $user_array = array(); $i = 0; while ($user_line = mysqli_fetch_assoc($result)) { $users_line = $user_line; while ($user_field = mysqli_fetch_row($user_line)) { $user_array['ID'] = $user_field[0]; $user_array['name'] = $user_field[1]; $user_array['surname'] = $user_field[2]; } $users[$i] = $user_line; $i++; } $meetHere->encodeUserToJson($users); $meetHere->closeDbConnection($mysqli); } if (isset($_GET['idToCheck'])) { $mysqli = $meetHere->newDbConnection(); $user_friend = $_GET['idToCheck']; $user_id = $_GET['userId']; $result = $mysqli->query("SELECT * FROM `Friends` WHERE `friend1` = '" . $user_id . "'AND `friend2` = '" . $user_friend . "'"); if ($result->num_rows == 1) { $meetHere->encodeJson("success", 0); } else { while ($user_field = mysqli_fetch_row($result)) { $user_id = $user_field[0]; } $meetHere->encodeJson("fail", $user_id); } $meetHere->closeDbConnection($mysqli); } if (isset($_GET['delFriend'])) { $mysqli = $meetHere->newDbConnection(); $user_friend = $_GET['delFriend']; $user_id = $_GET['userId']; $mysqli->query("DELETE FROM `Friends` WHERE `friend1` = '" . $user_id . "' AND `friend2` = '" . $user_friend . "'"); $mysqli->query("DELETE FROM `Friends` WHERE `friend1` = '" . $user_friend . "' AND `friend2` = '" . $user_id . "'"); $meetHere->encodeJson("success", $user_id); $meetHere->closeDbConnection($mysqli); } } else { $meetHere->encodeJson("fail", 0); } class MeetHere { public function newDbConnection() { $mysqli = new mysqli("mysql.cba.pl", "chinet1", "kolejde30012", "chinet"); if ($mysqli == false) { die("ERROR: Could not connect. " . $mysqli->connect_error); } return $mysqli; } private function setContentTypeJSON() { header('Content-type: application/json'); } public function encodeUserToJson($user) { $this->setContentTypeJSON(); echo json_encode(array('user'=>$user)); } public function encodeJson($msg, $user_id) { $this->setContentTypeJSON(); echo json_encode(array('operation'=> $msg, 'id' => $user_id)); } public function closeDbConnection($connection) { $connection->close(); } }</pre> <pre>$key = mh74568797845; $meetHere = new MeetHere(); if (isset($_GET['key']) && $_GET['key'] == $key) { if (isset($_GET['user']) && intval($_GET['user'])) { $mysqli = $meetHere->newDbConnection(); $user_id = $_GET['user']; $user = $mysqli->query("SELECT * FROM `Users` WHERE `ID` = " . $user_id) or die("error while query"); $user_array = array(); while ($user_field = mysqli_fetch_row($user)) { $user_array['ID'] = $user_field[0]; $user_array['name'] = $user_field[1]; $user_array['surname'] = $user_field[2]; $user_array['email'] = $user_field[3]; $user_array['city'] = $user_field[4]; $user_array['dayOfBirthday'] = $user_field[5]; $user_array['lastLocalization'] = $user_field[6]; $user_array['createdAt'] = $user_field[7]; } $meetHere->encodeUserToJson($user_array); $meetHere->closeDbConnection($mysqli); } if (isset($_GET['saveLoc'])) { $mysqli = $meetHere->newDbConnection(); $user_id = $_GET['saveLoc']; $user_loc = $_GET['localization']; $mysqli->query('UPDATE `Users` SET `lastLocalization` = ' . '"' . $user_loc . '" WHERE `ID` = ' . $user_id); $meetHere->encodeJson("success", $user_id); $meetHere->closeDbConnection($mysqli); } if (isset($_GET['thatEmail'])) { $mysqli = $meetHere->newDbConnection(); $email = $_GET['thatEmail']; $result = $mysqli->query("SELECT * FROM `Users` WHERE `email` = '" . $email . "'"); if ($result->num_rows === 0) { $meetHere->encodeJson("success", 0); } else { while ($user_field = mysqli_fetch_row($result)) { $user_id = $user_field[0]; } $meetHere->encodeJson("fail", $user_id); } $meetHere->closeDbConnection($mysqli); } if (isset($_GET['addUser'])) { $mysqli = $meetHere->newDbConnection(); $user_name = $_GET['addUser']; $user_surname = $_GET['surname']; $user_email = $_GET['email']; $user_city = $_GET['city']; $user_dayOfBirthday = $_GET['dayOfBirthday']; $user_lastLocalization = $_GET['lastLocalization']; $mysqli->query('INSERT INTO `Users`(`name`, `surname`, `email`, `city`, `dayOfBirthday`, `lastLocalization`) VALUES ("' . $user_name . '", "' . $user_surname . '", "' . $user_email . '", "' . $user_city . '", "' . $user_dayOfBirthday . '", "' . $user_lastLocalization . '")'); $result = $mysqli->query("SELECT * FROM `Users` WHERE `email` = '" . $user_email . "'"); while ($user_field = mysqli_fetch_row($result)) { $user_id = $user_field[0]; } $meetHere->encodeJson("added", $user_id); $meetHere->closeDbConnection($mysqli); } if (isset($_GET['addFriend'])) { $mysqli = $meetHere->newDbConnection(); $user_id = $_GET['addFriend']; $friend_id = $_GET['friend']; $mysqli->query('INSERT INTO `Friends` (`friend1`, `friend2`) VALUES ("' . $user_id . '", "' . $friend_id . '")'); $mysqli->query('INSERT INTO `Friends` (`friend2`, `friend1`) VALUES ("' . $user_id . '", "' . $friend_id . '")'); $meetHere->encodeJson("success", $user_id); $meetHere->closeDbConnection($mysqli); } if (isset($_GET['getFriends'])) { $mysqli = $meetHere->newDbConnection(); $user_id = $_GET['getFriends']; $result = $mysqli->query('SELECT u.* FROM `Users` u LEFT JOIN `Friends` f ON f.friend2 = u.ID WHERE f.friend1 = "' . $user_id . '"'); $users = array(); $users_line = array(); $user_array = array(); $i = 0; while ($user_line = mysqli_fetch_assoc($result)) { $users_line = $user_line; while ($user_field = mysqli_fetch_row($user_line)) { $user_array['ID'] = $user_field[0]; $user_array['name'] = $user_field[1]; $user_array['surname'] = $user_field[2]; $user_array['email'] = $user_field[3]; $user_array['city'] = $user_field[4]; $user_array['dayOfBirthday'] = $user_field[5]; $user_array['lastLocalization'] = $user_field[6]; $user_array['createdAt'] = $user_field[7]; } $users[$i] = $user_line; $i++; } $meetHere->encodeUserToJson($users); $meetHere->closeDbConnection($mysqli); } if (isset($_GET['search'])) { $mysqli = $meetHere->newDbConnection(); $name = $_GET['search']; $surname = $_GET['surname']; $result = $mysqli->query('SELECT `ID`, `name`, `surname` FROM `Users` WHERE `name` LIKE "%' . $name . '%" OR `surname` LIKE "%' . $surname . '%"'); $users = array(); $users_line = array(); $user_array = array(); $i = 0; while ($user_line = mysqli_fetch_assoc($result)) { $users_line = $user_line; while ($user_field = mysqli_fetch_row($user_line)) { $user_array['ID'] = $user_field[0]; $user_array['name'] = $user_field[1]; $user_array['surname'] = $user_field[2]; } $users[$i] = $user_line; $i++; } $meetHere->encodeUserToJson($users); $meetHere->closeDbConnection($mysqli); } if (isset($_GET['idToCheck'])) { $mysqli = $meetHere->newDbConnection(); $user_friend = $_GET['idToCheck']; $user_id = $_GET['userId']; $result = $mysqli->query("SELECT * FROM `Friends` WHERE `friend1` = '" . $user_id . "'AND `friend2` = '" . $user_friend . "'"); if ($result->num_rows == 1) { $meetHere->encodeJson("success", 0); } else { while ($user_field = mysqli_fetch_row($result)) { $user_id = $user_field[0]; } $meetHere->encodeJson("fail", $user_id); } $meetHere->closeDbConnection($mysqli); } if (isset($_GET['delFriend'])) { $mysqli = $meetHere->newDbConnection(); $user_friend = $_GET['delFriend']; $user_id = $_GET['userId']; $mysqli->query("DELETE FROM `Friends` WHERE `friend1` = '" . $user_id . "' AND `friend2` = '" . $user_friend . "'"); $mysqli->query("DELETE FROM `Friends` WHERE `friend1` = '" . $user_friend . "' AND `friend2` = '" . $user_id . "'"); $meetHere->encodeJson("success", $user_id); $meetHere->closeDbConnection($mysqli); } } else { $meetHere->encodeJson("fail", 0); } class MeetHere { public function newDbConnection() { $mysqli = new mysqli("mysql.cba.pl", "chinet1", "kolejde30012", "chinet"); if ($mysqli == false) { die("ERROR: Could not connect. " . $mysqli->connect_error); } return $mysqli; } private function setContentTypeJSON() { header('Content-type: application/json'); } public function encodeUserToJson($user) { $this->setContentTypeJSON(); echo json_encode(array('user'=>$user)); } public function encodeJson($msg, $user_id) { $this->setContentTypeJSON(); echo json_encode(array('operation'=> $msg, 'id' => $user_id)); } public function closeDbConnection($connection) { $connection->close(); } }
Kilka poprawek i niedociągnięć
W kodzie modułu znajomych, wprowadziłem kilka zmian i dodałem kod, o którym zapomniałem ostatnio. Na pierwszy ogień idzie klasa SearchFriendAcitivity, która szukając znajomych wyszukiwała również użytkownika aktualnie zalogowanego, co było błędem. Poprawiłem to dokładając if to pętli for:
for (int i=0; i <list.length; i++) { if (Integer.parseInt(list[i][0]) != userId) { friends.add(list[i][1] + " " + list[i][2]); } }
Do FriendsActivity został dodany kod pozwalający na przeniesienie się do profilu znajomego po kliknięciu na rekord ListView, to ten sam kod, który pracuje w SearchFriendAcitivity.
private AdapterView.OnItemClickListener itemClicked = new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView adapterView, View view, int position, long id) { Intent intent = new Intent(FriendsActivity.this, FriendProfileActivity.class); intent.putExtra("friendId", list[position][0]); startActivity(intent); Log.d("ItemClick", list[position][0]); } };
Od teraz w profilu znajomego przycisk dodania znajomego, ma tekst dodania i usunięcia znajomego, w zależności czy mamy go już w znajomych czy nie. Po kliknięciu przycisku wykonuje się kod dodający lub usuwający znajomego. Podmiana nazwy przycisku:
webServiceHelper = new WebServiceHelper(); buttonAddUser = (Button) findViewById(R.id.add_user_button); url = "http://chinet.cba.pl/meethere.php?idToCheck=" + friendId +"&userId=" + userId + "&key=" + getString(R.string.key_web_service); response = webServiceHelper.makeDBOperation(url); if (response == "success") { buttonAddUser.setText("Delete friend"); } else { buttonAddUser.setText("Add friend"); }
Funkcja wywoływana po kliknięciu przycisku:
public void addFriend(View view) { url = "http://chinet.cba.pl/meethere.php?idToCheck=" + friendId +"&userId=" + userId + "&key=" + getString(R.string.key_web_service); response = webServiceHelper.makeDBOperation(url); if (response == "success") { url = "http://chinet.cba.pl/meethere.php?delFriend=" + userId + "&userId=" + friendId + "&key=" + getString(R.string.key_web_service); webServiceHelper.makeDBOperation(url); buttonAddUser.setText("Add friend"); Toast.makeText(this, "User delete from friend list!", Toast.LENGTH_LONG).show(); } else if (userId == Integer.parseInt(response)) { url = "http://chinet.cba.pl/meethere.php?addFriend=" + userId + "&friend=" + friendId + "&key=" + getString(R.string.key_web_service); webServiceHelper.makeDBOperation(url); buttonAddUser.setText("Delete friend"); Toast.makeText(this, "Added new friend!", Toast.LENGTH_LONG).show(); } else { Log.d("FPA", "fail in addUser"); } }
Zadania w tle
Aby dalsze funkcje aplikacji mogły działać poprawnie, potrzebujemy aktualnych informacji o lokalizacji. Musimy więc sprawdzać ją nawet kiedy użytkownik nie używa telefonu. Przyjąłem, że dobrze będzie sprawdzać lokalizację co godzinę. Możemy nie mieć aktualnej lokalizacji przez kilkanaście minut, ale trzeba zadbać też o baterię naszego użytkownika. Do wykonywania takich zadań przystosowana jest klasa JobScheduler. Napisałem więc service rozszerzający klasę JobService. Tutaj znajdzie się całe zadanie jakie aplikacja będzie wykonywać w tle. Klasa JobSchedulerService:
public class JobSchedulerService extends JobService { private String lastLocalization; private Handler jobHandler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message message) { LocationTracker locationTracker = LocationTracker.getInstance(); if (locationTracker.canGetLocation()) { lastLocalization = locationTracker.getLatitude() + ", " + locationTracker.getLongitude(); } locationTracker.stopUsingGPS(); int user_id = SaveSharedPreference.getId(getApplicationContext()); String url = "http://chinet.cba.pl/meethere.php?saveLoc=" + user_id + "&localization=" + lastLocalization + "&key=" + getString(R.string.key_web_service); WebServiceHelper webServiceHelper = new WebServiceHelper(); webServiceHelper.makeDBOperation(url); Log.d(JobSchedulerService.class.getSimpleName(), "JobService task running"); jobFinished((JobParameters) message.obj, false); return true; } }); @Override public boolean onStartJob(JobParameters jobParameters) { jobHandler.sendMessage(Message.obtain(jobHandler, 1, jobParameters)); return true; } @Override public boolean onStopJob(JobParameters jobParameters) { jobHandler.removeMessages(1); return false; } }
Wywołanie tej klasy znajduje się w MainActivity:
int user_id = SaveSharedPreference.getId(getApplicationContext()); jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); if (user_id != 0) { JobInfo.Builder builder = new JobInfo.Builder( 1, new ComponentName(getPackageName(), JobSchedulerService.class.getName())); builder.setPeriodic(1000 * 3600); if(jobScheduler.schedule(builder.build())<=0) { Log.d("LocationUpdater", "Something was wrong"); } } else { jobScheduler.cancelAll(); }
To wszystko co powstało w tym tygodniu, jak widzisz aplikacja prężnie się rozwija. Aktualny kod znajdziesz na GitHubie.