Po stworzeniu web service’u, którego proces tworzenia przedstawiłem w poprzednim poście, czas na zaimplementowanie go w aplikacji. Moim zadaniem będzie pobranie JSONa z danymi i przygotowanie ich do wyświetlenia w aktywności.
Pobieranie danych z web service
Aktualnie nasz web service nie wystawia jeszcze za wiele danych, ale sposób pobierania jest uniwersalny, więc dokładanie kolejnych funkcjonalności nie będzie problemem. Klasa WebServiceHandler będzie przyjmować jako parametr metody wykonującej zapytanie adres URL. Wynik będzie przekonwertowany do stringa. Kod klasy:
public class WebServiceHandler { private static final String TAG = WebServiceHandler.class.getSimpleName(); public WebServiceHandler() { } public String makeServiceCall(String reqURL) { String response = null; try { URL url = new URL(reqURL); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); InputStream inputStream = new BufferedInputStream(connection.getInputStream()); response = convertStreamToString(inputStream); } catch (MalformedURLException e) { Log.e(TAG, "MalformedURLException: " + e.getMessage()); } catch (IOException e ) { Log.e(TAG, "IOException: " + e.getMessage()); } catch (Exception e) { Log.e(TAG, "Exception: " + e.getMessage()); } return response; } private String convertStreamToString(InputStream inputStream) { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); StringBuilder stringBuilder = new StringBuilder(); String line; try { while ((line = reader.readLine()) != null) { stringBuilder.append(line).append('\n'); } } catch (IOException e) { e.printStackTrace(); } finally { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } return stringBuilder.toString(); } }
Klasa asynchroniczna
Jako, że odwoływanie do web service jest procesem, w którym procesor musi czekać na dane z zewnętrznego źródła, kod nie może być wykonywany synchronicznie – jeden za drugim. Czekając na dane procesor może wykonywać inne obliczenia. Musimy użyć klasy asynchronicznej, w Androidzie dostępna jest klasa AsyncTask, która dostarcza takie rozwiązanie. Klasa GetUser jest wewnętrzną klasą UserActivity. Pobrane w niej dane zostaną zapisane do tablicy, która jest zwracana do klasy głównej. Klasa UserActivity wyświetla zawartość tablicy w widoku. Cały kod tej klasy:
public class UserActivity extends AppCompatActivity { private int userID = 10; private String url = "http://chinet.cba.pl/meethere.php?user=" + userID; private String[] user; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_user); try { user = new GetUser(this).execute().get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } String name = user[1] + " " + user[2]; Integer age = calculateYears(user[5]); String city = "City: " + user[4]; String ageString = "Age: " + age; TextView nameText = (TextView) findViewById(R.id.nameText); nameText.setText(name); TextView ageText = (TextView) findViewById(R.id.ageText); ageText.setText(ageString); TextView cityText = (TextView) findViewById(R.id.cityText); cityText.setText(city); } public void goFriends(View view) { Intent intent = new Intent(this, FriendsActivity.class); intent.putExtra("userID", userID); startActivity(intent); } private Integer calculateYears(String dataFrom) { String[] parts = dataFrom.split(", "); LocalDate df = new LocalDate(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), Integer.parseInt(parts[2])); LocalDate now = new LocalDate(); Years yearsIns = Years.yearsBetween(df, now); Integer years = yearsIns.getYears(); return years; } private class GetUser extends AsyncTask<String, Void, String[]> { private static final String TAG = "GetUser"; private UserActivity userActivity; public GetUser(UserActivity userActivity){ this.userActivity = userActivity; } @Override protected String[] doInBackground(String... params) { WebServiceHandler webServiceHandler = new WebServiceHandler(); String jsonStr = webServiceHandler.makeServiceCall(url); Log.d(TAG, "Response form url: " + jsonStr); String[] user = new String[8]; if (jsonStr != null) { try { JSONObject jsonObject = new JSONObject(jsonStr); JSONObject u = jsonObject.getJSONObject("user"); user[0] = u.getString("ID"); user[1] = u.getString("name"); user[2] = u.getString("surname"); user[3] = u.getString("email"); user[4] = u.getString("city"); user[5] = u.getString("dayOfBirthday"); user[6] = u.getString("lastLocalization"); user[7] = u.getString("createdAt"); } catch (JSONException e) { Log.e(TAG, "Json parsing error: " + e.getMessage()); } } else { Log.e(TAG, "Couldn't get json from server."); } return user; } @Override protected void onPostExecute(String[] user) { } } }
Pierwsze kroki z web service poczynione. Teraz powoli będę rozbudowywał funkcjonalności tego systemu.