Всем привет и это уже третья статья и видео, посвященные работе в Android Studio с json файлами.

Из этой статьи вы узнаете как в android studio получать данные из JSON в ListView с сервера на хостинге.

Мы всё ближе и ближе подходим к тому, чтобы наконец-то начать получать данные с сервера на хостинге, а вот сейчас мы займемся как раз разбором данного примера.

Мы загрузим наш тестовый json файл с пользователями на хостинг и будем получать данные уже непосредственно из интернета.

Надеюсь видео вам понравится, можете пока создается новый проект поставить пальцы вверх, подписаться на канал, и мы приступаем.

Смотрите видео: Android Studio: получение JSON в ListView с сервера на хостинге. Урок № 3

Создаем новый проект, выбираем emptyActivity, традиционно жмем Next, назовём новый проект Load json from url -01, финиш.

Пока подготавливается проект, хочу сказать, что я выложил наш тестовый json файл на хостинг и буду использовать его в качестве примера. Вы можете выложить свой файл, как Вам будет удобно с вашим содержимым. Замечу, что заходить по ftp на сервер, создавать домены, поддомены, создавать директории на хостинге вы обязаны уметь.

Если мы перейдём по ссылке m1.maxfad.ru/api/users.json, то мы можем увидеть структуру файла, перечень пользователей, электронные адреса. Сейчас это всё находится уже на хостинге в интернете.

Давайте поработаем над нашим проектом, кое-что будем использовать из второго урока, код будет немного совпадать, кто не смотрел предыдущие примеры, обязательно посмотрите.

Давайте сразу через New Resource File снова сделаем row.xml, для вывода пунктов нашего списка, чуть позже вернемся к нему.

Откроем AndroidManifest.xml, в нем нужно будет указать разрешение для работы с интернетом.

Также нам понадобится gradle файл, и в него мы вставим имплементацию библиотеки, которую Вы наверное, уже знаете, может кто-то уже слышал, это volley, по крайней мере так я её произношу.

implementation 'com.android.volley:volley:1.1.0'

Синхронизируем gradle, произошло добавление, будем работать с этой библиотекой, она как раз используется для сетевых запросов, для получения данных с сайтов и тому подобного.

В AndroidManifest добавим пользовательское разрешение для работы с интернетом.

< uses-permission android:name="android.permission.INTERNET" />

Хочу сделать маленькое замечание, пока мы не начали всё писать, поскольку у меня, а возможно такое будет и у вас, сертификат не распространяется на поддомены, то для того чтобы не выдавались сообщения об ошибке, Вам нужно будет включить в блок application следующюю запись.

android:usesCleartextTraffic="true"

Это вроде как позволяет работать с недостоверными, скажем так с точки зрения Google, сайтами это требование корпорации добра, для вашей безопасности. С манифестом и с gradle закончили.

Слой listview

Теперь перейдем в activity_main, по традиции мы снова будем делать listview, заменим на RelativeLayout, textview меняем на listview, убираем отсюда опять всё ненужное.

Так значит для listview добавим android:id listView, ширина и высота - wrap_content.

android:id="@+id/listView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

Добавим еще один элемент для отображения сетевой активности, ProgressBar ширина wrap_content, высота тоже wrap_content.

Сделаем видимость ProgressBar в

android:visibility="gone"
, то есть невидимый, добавим ему id.
android:id="@+id/progressBar"

Вот теперь важное: для ProgressBar добавить нужно центрирование по горизонтали и по вертикали, чтобы элемент был по центру экрана.

android:layout_centerHorizontal="true"
android:layout_centerVertical="true"

Так он пока где-то находится, его не видно, можно посмотреть. он находится по центру и будет крутиться.

Перейдём в row.xml для вывода пунктов, сделаем здесь LinearLayout, ширина match_parent , а высота wrap_content, ориентация вертикальная, отступы – 16dp.

Слой row

Так теперь добавим два textview, вы уже знаете какие, это у нас будут для name и email.

android:id="@+id/textViewName"

Добавим для видимости текст,

android:text="Name",
размер текста сделаем равным 20sp. Можно было не писать, можно было скопировать с предыдущего примерно, но напишу. То же самое и для поля email.

< TextView
        android:id="@+id/textViewName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Name"
        android:textSize="20sp"/>

    < TextView
        android:id="@+id/textViewEmail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Email"
        android:textSize="20sp"/>

Так значит нам нужно будет создать новый класс для обработки. Наш класс мы назовём ListViewAdapter.

И теперь я буду вставлять куски кода, потому как мы его писали в прошлый раз, но для тех, кто не смотрел, кое-что расскажу, буду уже всё равно блоками вставать, поскольку он практически готов.

Снова напишем конструктор, в котором будем вызываться контекст, слой, которые у нас row, будем вызывать поля, в принципе можно там первое вызвать name и уже будет работать и список который будет передавать данные.

Метод super это всё вызывает, здесь присвоение переменных.

Ну и опять без изменений практически из второго видео, с некоторыми оговорками получается вот такая функция.

В getView определяем слой для вывода данных, обращаемся к элементам пункта name, email. В блоке обработки исключений try/catch циклично присваиваем текст, получая его из списка userlist.

Кто смотрел мое второе видео по json, тот знает, что это такое, в принципе больше на этом останавливаться не будем.

Теперь переходим в mainactivity и поработаем в ней. Итак, нам нужно будет объявить несколько переменных, переменная JSON_URL в которой мы будем хранить наш адрес, по которому будет лежать наш файл на сайте.

private static final String JSON_URL = "http://m1.maxfad.ru/api/users.json";

и ListView listView для списка.

Я надеюсь вы знаете как заливать файлы на хостинг, поэтому я не буду рассказывать, как мне удалось создать папку api в поддомене и положить туда файл, думаю это вам уже известно, если вы занимаетесь и обучайтесь разработке Android приложений для себя, либо по учёбе, по работе.

Сразу же мы получаем наш listView, наш список через findViewById

  listView = (ListView) findViewById(R.id.listView);

А вот теперь мы напишем вот такую строчку,

loadJSONFromURL(JSON_URL);

это по сути в onCreate больше ничего не будет. Дальше будет несколько функций, которые мы напишем в рукопашную.

И эта функция loadJSONFromURL будет вызывать наш адрес, и будем получать данные.

Далее напишем ручками Private void loadJSONFromURL, в качестве параметра Stirling передаём url.

Нужно будет обратиться к нашему элементу ProgressBar, который у нас указан в activity_main progressBar

final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);

ProgressBar надо будет сделать видимым

progressBar.setVisibility(View.VISIBLE);

Теперь пишем StringRequest, обратите внимание это мы работаем с библиотекой volley,

StringRequest stringRequest = new StringRequest(Request.Method.GET,

передаём наш url, пишем new Response.Listener

Открываем скобки пишем @Override,

Нам нужно добавить метод onResponse, подключить сюда onResponse.

Далее делаем ProgressBar не видимым.

progressBar.setVisibility(View.INVISIBLE);

Всё мы его скрыли, теперь у нас идёт обработчик исключений try, пишем

JSONObject object = new JSONObject(response);
JSONArray jsonArray = object.getJSONArray("users");

и указываем нашу таблицу users, которая у нас внутри файла users.json.

Объявляем ArrayList JSONObject

ArrayList< JSONObject> listItems = getArrayListFromJSONArray(jsonArray);

и вот здесь мы напишем ту функцию, которую мы писали в прошлый раз.

В прошлый раз, я хочу напомнить, мы её вставим вне функций, мы её Встаём целиком и полностью, можете скопировать её из второго примера. Поскольку будем выполнять то же самое действие здесь.

private ArrayList< JSONObject> getArrayListFromJSONArray(JSONArray jsonArray){
        ArrayList< JSONObject> aList = new ArrayList< JSONObject>();
        try {
            if(jsonArray!= null){
                for(int i = 0; i< jsonArray.length();i++){
                    aList.add(jsonArray.getJSONObject(i));
                }
            }
        }catch (JSONException js){
            js.printStackTrace();
        }
        return aList;
    }

Не буду останавливаться, но тут происходит наполнение данными из массива. Передаём jsonArray, далее пишем ListAdapter adapter

ListAdapter adapter = new ListViewAdapter(getApplicationContext(),R.layout.row,R.id.textViewName,listItems);

И теперь для списка установим адаптер

listView.setAdapter(adapter);

Блок исключений catch

catch (JSONException e){
                    e.printStackTrace();

Далее идет Response.ErrorListener

@Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(getApplicationContext(),error.getMessage(),Toast.LENGTH_SHORT).show();
            }

В нем Toast выводит ошибки. Что такое тосты уже знаете, последние две строчки данной функции

RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);

Вот теперь только вызываться наша библиотека, которая в конце концов вызовет наконец-то запрос и сформирует нужный результат.

Так, здесь я пропустил запятую после переменной url, и в принципе больше у нас ни каких нюансов быть не должно… А они будут…)

Сохраняем, запускаем… Эмулятор запустился, и мы получили данные…

Ошибка в кодировке при получении данных с JSON

Поскольку наш файл вряд ли был в кодировке UTF-8, но здесь должен быть четко UTF-8. Напишу для себя UTF-8, должна быть такая кодировка, тогда у нас будут русские буквы, русский текст нормально выглядить.

Сложно догадаться, что это Коля, Вася, Федя, и тому подобное, хотя email отобразился нормально.

Значит нам нужно будет написать ещё одну небольшую функция, которая превратит наш ответ – response, превратит эту кашу в кодировку UTF-8.

Итак давайте исправим это недоразумение, написав еще одну функцию EncodingToUTF8

public  static  String EncodingToUTF8(String response){
        try {
            byte[] code = response.toString().getBytes("ISO-8859-1");
            response = new String(code, "UTF-8");
        }catch (UnsupportedEncodingException e){
            e.printStackTrace();
            return null;
        }
        return response;
    }

В качестве параметра передаём string response, сразу try обработчик, пишем массив байт, code

Ответ в строку, получим байты в кодировке ISO-8859-1, западноевропейская кодировка, и конвертируем в UTF-8, перегоним нашу абракадабру в понятный вид.

После обработки ошибок Catch вернем строковое значение response.

Вот такая получилась небольшая функция в принципе когда мы перейдём наконец-то в четвёртый урок, в четвёртом занятие, мы будем получать данные уже непосредственно из PHP с базы данных на хостинге, и этот костыль не понадобится, поскольку мы обойдемся без неё, там уже будем конвертировать текст, можно в базе указать.

И давайте её вызовем EncodingToUTF8 наш response, сохраним и перезапустим.

Вот так, всего лишь одна небольшая функция и мы превратили абракадабру во вполне понятной вид.

UTF-8 кодировка при получении данных с JSON

Cкачать архив для ознакомления - Android Studio: получение JSON в ListView с сервера на хостинге. Урок № 3:


ZIP архив с проектом


Полный текст AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
< manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="ru.maxfad.loadjsonfronurl_01">

    < uses-permission android:name="android.permission.INTERNET" />

    < application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:usesCleartextTraffic="true"
        android:theme="@style/Theme.LoadJsonFronUrl01">
        < activity android:name=".MainActivity">
            < intent-filter>
                < action android:name="android.intent.action.MAIN" />

                < category android:name="android.intent.category.LAUNCHER" />
            < /intent-filter>
        < /activity>
    < /application>
< /manifest>

Полный текст activity_main.xml

< ?xml version="1.0" encoding="utf-8"?>
< RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    < ListView
        android:id="@+id/listView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    < ProgressBar
        android:visibility="gone"
        android:id="@+id/progressBar"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

< /RelativeLayout>

Полный текст row.xml

< ?xml version="1.0" encoding="utf-8"?>
< LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="16dp">

    < TextView
        android:id="@+id/textViewName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Name"
        android:textSize="20sp"/>

    < TextView
        android:id="@+id/textViewEmail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Email"
        android:textSize="20sp"/>

< /LinearLayout>

Полный текст MainActivity.java

package ru.maxfad.loadjsonfronurl_01;

import android.os.Bundle;
import android.view.View;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
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.StringRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    private static final String JSON_URL = "http://m1.maxfad.ru/api/users.json";// UTF-8
    ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = (ListView) findViewById(R.id.listView);
        loadJSONFromURL(JSON_URL);
    }

    private void  loadJSONFromURL(String url){
        final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
        progressBar.setVisibility(ListView.VISIBLE);
        StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
        new Response.Listener< String>(){
            @Override
            public void onResponse(String response) {
                progressBar.setVisibility(View.INVISIBLE);
                try {
                    JSONObject object = new JSONObject(EncodingToUTF8(response));
                    JSONArray jsonArray = object.getJSONArray("users");
                    ArrayList< JSONObject> listItems = getArrayListFromJSONArray(jsonArray);
                    ListAdapter adapter = new ListViewAdapter(getApplicationContext(),R.layout.row,R.id.textViewName,listItems);
                    listView.setAdapter(adapter);
                }catch (JSONException e){
                    e.printStackTrace();
                }
            }
        },
        new Response.ErrorListener(){
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(getApplicationContext(),error.getMessage(),Toast.LENGTH_SHORT).show();
            }
        });
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        requestQueue.add(stringRequest);
    }

    private ArrayList< JSONObject> getArrayListFromJSONArray(JSONArray jsonArray){
        ArrayList< JSONObject> aList = new ArrayList< JSONObject>();
        try {
            if(jsonArray!= null){
                for(int i = 0; i< jsonArray.length();i++){
                    aList.add(jsonArray.getJSONObject(i));
                }
            }
        }catch (JSONException js){
            js.printStackTrace();
        }
        return aList;
    }

    public  static  String EncodingToUTF8(String response){
        try {
            byte[] code = response.toString().getBytes("ISO-8859-1");
            response = new String(code, "UTF-8");
        }catch (UnsupportedEncodingException e){
            e.printStackTrace();
            return null;
        }
        return response;
    }


}

Полный текст ListViewAdapter.java

package ru.maxfad.loadjsonfronurl_01;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;

public class ListViewAdapter  extends ArrayAdapter< JSONObject> {
    int listLayout;
    ArrayList< JSONObject> usersList;
    Context context;

    public ListViewAdapter(Context context, int listLayout , int field, ArrayList< JSONObject> usersList) {
        super(context, listLayout, field, usersList);
        this.context = context;
        this.listLayout=listLayout;
        this.usersList = usersList;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View listViewItem = inflater.inflate(listLayout, null, false);
        TextView name = listViewItem.findViewById(R.id.textViewName);
        TextView email = listViewItem.findViewById(R.id.textViewEmail);
        try{
            name.setText(usersList.get(position).getString("name"));
            email.setText(usersList.get(position).getString("email"));
        }catch (JSONException je){
            je.printStackTrace();
        }
        return listViewItem;
    }

}

Смотрите видео: Android Studio: получение JSON в ListView с сервера на хостинге. Урок № 3

 С уважением, авторы сайта Компьютерапия




Понравилась статья? Поделитесь ею с друзьями и напишите отзыв в комментариях!

Связанные статьи

Предыдущие статьи

We use cookies on our website. Some of them are essential for the operation of the site, while others help us to improve this site and the user experience (tracking cookies). You can decide for yourself whether you want to allow cookies or not. Please note that if you reject them, you may not be able to use all the functionalities of the site.

Ok