BÀI 57 - SỬ DỤNG FILE JSON TRONG ANDROID

JSON Object

JSON Object

Code đọc JSON thành phố Việt Nam mà Hama chia sẻ:

  • Tạo 3 class để đọc JSON như sau:

JSON thành phố

@SuppressLint("StaticFieldLeak")

private class readJSONCity extends AsyncTask<String, Void, String>{


@Override

protected String doInBackground(String... strings) {

StringBuilder chuaDuLieu = new StringBuilder();

try {

URL url = new URL(strings[0]);

InputStreamReader inputStreamReader = new InputStreamReader(url.openConnection().getInputStream());

BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

String line;

while ((line = bufferedReader.readLine()) != null){

chuaDuLieu.append(line);

}

bufferedReader.close();

} catch (IOException e) {

e.printStackTrace();

}

return chuaDuLieu.toString();

}


@Override

protected void onPostExecute(String s) {

super.onPostExecute(s);

try {

JSONObject jsonObject = new JSONObject(s);

JSONArray jsonArray = jsonObject.getJSONArray("thanhpho");

arrayListNameCity.clear();

arrayListCity.clear();

for (int i=0; i<jsonArray.length(); i++){

JSONObject getData = jsonArray.getJSONObject(i);

String idCity = getData.getString("province_id");

String nameCity = getData.getString("province_name");

String typeCity = getData.getString("province_type");

arrayListCity.add(new classThanhPho(idCity, nameCity, typeCity));

arrayListNameCity.add(nameCity);

}

// showToast(arrayListNameCity.get(1));

} catch (JSONException e) {

e.printStackTrace();

}

}

}

JSON quận huyện

@SuppressLint("StaticFieldLeak")

private class readJSONQuanHuyen extends AsyncTask<String, Void, String>{

@Override

protected String doInBackground(String... strings) {

StringBuilder dulieuQuanHuyen = new StringBuilder();

try {

URL url = new URL(strings[0]);

InputStreamReader inputStreamReader = new InputStreamReader(url.openConnection().getInputStream());

BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

String line;

while ((line = bufferedReader.readLine()) != null){

dulieuQuanHuyen.append(line);

}

bufferedReader.close();

} catch (IOException e) {

e.printStackTrace();

}


return dulieuQuanHuyen.toString();

}


@Override

protected void onPostExecute(String s) {

super.onPostExecute(s);

try {

JSONObject jsonObject = new JSONObject(s);

JSONArray jsonArray = jsonObject.getJSONArray("quanhuyen");

for (int i=0; i<jsonArray.length(); i++){

JSONObject getData = jsonArray.getJSONObject(i);

String idCity = getData.getString("province_id");

String idquanhuyen, tenquanhuyen;

if (idCity.equals(idthanhpho)){

idquanhuyen = getData.getString("district_id");

tenquanhuyen = getData.getString("district_name");

arrayListQuanHuyen.add(new classQuanHuyen(idCity, idquanhuyen, tenquanhuyen));

arrayNameQuanHuyen.add(tenquanhuyen);

}

}

// showToast(arrayNameQuanHuyen.get(4));

} catch (JSONException e) {

e.printStackTrace();

}

}

}

JSON xã phường

@SuppressLint("StaticFieldLeak")

private class readJSONXaPhuong extends AsyncTask<String, Void, String>{

@Override

protected String doInBackground(String... strings) {

StringBuilder dataXaPhuong = new StringBuilder();

try {

URL url = new URL(strings[0]);

InputStreamReader inputStreamReader = new InputStreamReader(url.openConnection().getInputStream());

BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

String line;

while ((line = bufferedReader.readLine()) != null){

dataXaPhuong.append(line);

}

bufferedReader.close();

} catch (IOException e) {

e.printStackTrace();

}

return dataXaPhuong.toString();

}


@Override

protected void onPostExecute(String s) {

super.onPostExecute(s);

try {

JSONObject jsonObject = new JSONObject(s);

JSONArray jsonArray = jsonObject.getJSONArray("xaphuong");

for (int i=0; i<jsonArray.length(); i++){

JSONObject getData = jsonArray.getJSONObject(i);

String idQH = getData.getString("district_id");

String idXaPhuong, tenXaPhuong;

if (idQH.equals(idQuanHuyen)){

idXaPhuong = getData.getString("ward_id");

tenXaPhuong = getData.getString("ward_name");

arrayListXaPhuong.add(new classXaPhuong(idthanhpho, idQuanHuyen, idXaPhuong, tenXaPhuong));

arrayNameXaPhuong.add(tenXaPhuong);

}

}

} catch (JSONException e) {

e.printStackTrace();

}

}

}

Để sử dụng trước tiên gọi hàm đếm ngược thời gian để load dữ liệu trước khi cho người dùng sử dụng

new CountDownTimer(2000,1000){

@Override

public void onTick(long millisUntilFinished) {

new readJSONCity().execute("https://robotquantrac.web.app/thanhpho.json"); // Bắt đầu nhào vô đọc nè

}

@Override

public void onFinish() {

actionCity(); // Bắt sự kiện người dùng nhập tên thành phố

}

}.start();

Tạo các biến toàn cục sau:

String thanhPho, quanHuyen, xaPhuong;

public static ArrayList<classThanhPho> arrayListCity;

public static ArrayList<classQuanHuyen> arrayListQuanHuyen;

public static ArrayList<classXaPhuong> arrayListXaPhuong;

ArrayList<String> arrayListNameCity;

ArrayList<String> arrayNameQuanHuyen;

ArrayList<String> arrayNameXaPhuong;

Object[] mangthanhpho;

String idthanhpho, idQuanHuyen;

boolean findQuanHuyen = false, findXaPhuong = false;

int bamQuanHuyen = 0, bamXaPhuong = 0;

Đối với các class cho mảng các bạn chỉ cần tạo các biến cần dùng trong JSON thôi. Tất cả các biến trong JSON đều là kiểu String nhé!
  • Mình sử dụng autocomplete textView cho editText nhập thành phố nên mình sẽ đổ toàn bộ tên thành phố vào mảng và truyền cho editText. Khi người dùng nhập tên tương ứng editText sẽ hiển thị tên tương ứng.

  • Ngoài ra, nếu người dùng cố ý hoặc vô tình nhập sai tên thì sẽ trả về lỗi nhập tào lao. Hoặc khi không tìm thấy tên tỉnh nào giống trong dữ liệu cũng sẽ thông báo tỉnh không tồn tại.

  • Dưới đây là code để đổ dữ liệu cho editText thành phố.

mangthanhpho = arrayListNameCity.toArray();

ArrayAdapter<Object> arrayAdapter = new ArrayAdapter<>(this

, support_simple_spinner_dropdown_item ,mangthanhpho);

edtThanhPho.setAdapter(arrayAdapter);

  • Khi có tên thành phố rồi, người dùng sẽ nhập tên quận huyện. Nếu người dùng cố tình bỏ qua mà nhập xã phường thì cũng sẽ báo chưa nhập quận huyện.

  • Thuật toán của mình là sẽ lấy tên thành phố vừa nhập đem so sánh với mảng thành phố chứa thông tin tên thành phố và id của thành phố đó. Nếu kết quả so sánh tên trùng khớp thì sẽ lưu id của thành phố lại.

  • Chuyển qua một vòng lặp for khác để quét toàn bộ quận huyện trong JSON lọc ra các quận huyện có id trùng khớp. Xã phường mình cũng làm tương tự vậy. Cách này nhược điểm là người dùng phải có mạng internet.

  • Dưới đây là code cho quận huyện.

edtQuanHuyen.setOnClickListener(v -> {

boolean daNhapQuanHuyen = false;

bamQuanHuyen++;

thanhPho = edtThanhPho.getText().toString();

if (bamQuanHuyen == 1) {

if (thanhPho.isEmpty()) {

tilThanhPho.setError(getString(R.string.nhap_thanh_pho_da));

tilQuanHuyen.setError(null);

edtQuanHuyen.setText(null);

findQuanHuyen = false;

} else {

tilThanhPho.setError(null);

daNhapQuanHuyen = true;

for (int i = 0; i < arrayListCity.size(); i++) {

if (thanhPho.equals(arrayListCity.get(i).getNameCity())) {

idthanhpho = arrayListCity.get(i).getIdCity();

findQuanHuyen = true;

new readJSONQuanHuyen().execute("https://robotquantrac.web.app/quanhuyen.json");

break;

}

}

}

}


if (findQuanHuyen){

tilThanhPho.setError(null);

ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(this

, support_simple_spinner_dropdown_item, arrayNameQuanHuyen);

arrayAdapter.notifyDataSetChanged();

edtQuanHuyen.setAdapter(arrayAdapter);

} else {

if (daNhapQuanHuyen){

tilThanhPho.setError(getString(R.string.ten_thanh_pho_sai));

}

}

});

  • Dưới đây là code xã phường.

edtXaPhuong.setOnClickListener(v -> {

bamXaPhuong++;

thanhPho = edtThanhPho.getText().toString();

quanHuyen = edtQuanHuyen.getText().toString();

if (bamXaPhuong == 1) {

if (thanhPho.isEmpty()) {

tilThanhPho.setError(getString(R.string.nhap_thanh_pho_da));

tilXaPhuong.setError(null);

tilQuanHuyen.setError(null);

edtXaPhuong.setText(null);

findXaPhuong = false;

} else if (quanHuyen.isEmpty()) {

tilQuanHuyen.setError(getString(R.string.nhap_quan_huyen_da));

tilThanhPho.setError(null);

tilXaPhuong.setError(null);

edtXaPhuong.setText(null);

findXaPhuong = false;

} else {

tilThanhPho.setError(null);

tilQuanHuyen.setError(null);

tilXaPhuong.setError(null);


for (int i = 0; i < arrayListQuanHuyen.size(); i++) {

if (quanHuyen.equals(arrayListQuanHuyen.get(i).getTenQuanHuyen())) {

idQuanHuyen = arrayListQuanHuyen.get(i).getIdQuanHuyen();

findXaPhuong = true;

new readJSONXaPhuong().execute("https://robotquantrac.web.app/xaphuong.json");

break;

}

}

}

}


if (findXaPhuong){

tilQuanHuyen.setError(null);

tilThanhPho.setError(null);

ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(xacNhanMuaHangActivity.this,

support_simple_spinner_dropdown_item, arrayNameXaPhuong);

arrayAdapter.notifyDataSetChanged();

edtXaPhuong.setAdapter(arrayAdapter);

}

});

  • Khi người dùng cố tình thay đổi địa điểm khác thì code sẽ reset tương ứng như sau:

edtThanhPho.addTextChangedListener(new TextWatcher() {

@Override

public void beforeTextChanged(CharSequence s, int start, int count, int after) {


}


@Override

public void onTextChanged(CharSequence s, int start, int before, int count) {

bamQuanHuyen = 0;

bamXaPhuong = 0;

arrayNameXaPhuong.clear();

arrayListXaPhuong.clear();

arrayNameQuanHuyen.clear();

arrayListQuanHuyen.clear();

edtQuanHuyen.setText(null);

edtXaPhuong.setText(null);

}


@Override

public void afterTextChanged(Editable s) {

bamQuanHuyen = 0;

bamXaPhuong = 0;

arrayNameXaPhuong.clear();

arrayListXaPhuong.clear();

arrayNameQuanHuyen.clear();

arrayListQuanHuyen.clear();

edtQuanHuyen.setText(null);

edtXaPhuong.setText(null);

}

});


edtQuanHuyen.addTextChangedListener(new TextWatcher() {

@Override

public void beforeTextChanged(CharSequence s, int start, int count, int after) {


}


@Override

public void onTextChanged(CharSequence s, int start, int before, int count) {

bamXaPhuong = 0;

arrayNameXaPhuong.clear();

arrayListXaPhuong.clear();

edtXaPhuong.setText(null);

}


@Override

public void afterTextChanged(Editable s) {

bamXaPhuong = 0;

arrayNameXaPhuong.clear();

arrayListXaPhuong.clear();

edtXaPhuong.setText(null);

}

});