Использование файла JSON в ресурсах приложения Android

87

Предположим, у меня есть файл с содержимым JSON в папке сырых ресурсов в моем приложении. Как я могу прочитать это в приложении, чтобы разобрать JSON?

yydl
источник

Ответы:

143

См. OpenRawResource . Примерно так должно работать:

InputStream is = getResources().openRawResource(R.raw.json_file);
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
    Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
    int n;
    while ((n = reader.read(buffer)) != -1) {
        writer.write(buffer, 0, n);
    }
} finally {
    is.close();
}

String jsonString = writer.toString();
Кабуко
источник
1
Что, если я хочу поместить строку в ресурс String в Android и использовать ее динамически с помощью getResources (). GetString (R.String.name)?
Анкур Гаутам
Для меня это не работает из-за цитат, которые игнорируются при чтении и которых, кажется, невозможно избежать,
Мариан Клюспис
1
Есть ли способ заставить ButterKnife привязать необработанный ресурс? Написание 10+ строк кода только для чтения строки кажется излишним.
Джезор,
Как json хранится внутри ресурсов? Просто внутри \res\json_file.jsonпапки или внутри \res\raw\json_file.json?
Клифф Бертон
В этом ответе отсутствует важная информация. Куда можно getResources()позвонить? Куда должен идти файл сырых ресурсов? Какое соглашение вы должны соблюдать, чтобы гарантировать создание инструментов сборки R.raw.json_file?
NobodyMan 08
112

Kotlin теперь является официальным языком для Android, поэтому я думаю, что это будет полезно для кого-то

val text = resources.openRawResource(R.raw.your_text_file)
                                 .bufferedReader().use { it.readText() }
Дима Ростопира
источник
Это потенциально длительная операция, поэтому убедитесь, что она вызывается из основного потока!
Эндрю Оробатор,
@AndrewOrobator Я сомневаюсь, что кто-то поместит большой json в ресурсы приложения, но да, хороший момент
Дима Ростопира
24

Я использовал ответ @ kabuko для создания объекта, который загружается из файла JSON, используя Gson , из ресурсов:

package com.jingit.mobile.testsupport;

import java.io.*;

import android.content.res.Resources;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;


/**
 * An object for reading from a JSON resource file and constructing an object from that resource file using Gson.
 */
public class JSONResourceReader {

    // === [ Private Data Members ] ============================================

    // Our JSON, in string form.
    private String jsonString;
    private static final String LOGTAG = JSONResourceReader.class.getSimpleName();

    // === [ Public API ] ======================================================

    /**
     * Read from a resources file and create a {@link JSONResourceReader} object that will allow the creation of other
     * objects from this resource.
     *
     * @param resources An application {@link Resources} object.
     * @param id The id for the resource to load, typically held in the raw/ folder.
     */
    public JSONResourceReader(Resources resources, int id) {
        InputStream resourceReader = resources.openRawResource(id);
        Writer writer = new StringWriter();
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(resourceReader, "UTF-8"));
            String line = reader.readLine();
            while (line != null) {
                writer.write(line);
                line = reader.readLine();
            }
        } catch (Exception e) {
            Log.e(LOGTAG, "Unhandled exception while using JSONResourceReader", e);
        } finally {
            try {
                resourceReader.close();
            } catch (Exception e) {
                Log.e(LOGTAG, "Unhandled exception while using JSONResourceReader", e);
            }
        }

        jsonString = writer.toString();
    }

    /**
     * Build an object from the specified JSON resource using Gson.
     *
     * @param type The type of the object to build.
     *
     * @return An object of type T, with member fields populated using Gson.
     */
    public <T> T constructUsingGson(Class<T> type) {
        Gson gson = new GsonBuilder().create();
        return gson.fromJson(jsonString, type);
    }
}

Чтобы использовать его, вы должны сделать что-то вроде следующего (пример находится в файле InstrumentationTestCase):

   @Override
    public void setUp() {
        // Load our JSON file.
        JSONResourceReader reader = new JSONResourceReader(getInstrumentation().getContext().getResources(), R.raw.jsonfile);
        MyJsonObject jsonObj = reader.constructUsingGson(MyJsonObject.class);
   }
jwir3
источник
3
Не забудьте добавить зависимости {compile com.google.code.gson: gson: 2.8.2 '} к вашему файлу
gradle
последняя версия GSONimplementation 'com.google.code.gson:gson:2.8.5'
Даниэль
12

Из http://developer.android.com/guide/topics/resources/providing-resources.html :

сырые /
произвольные файлы для сохранения в необработанном виде. Чтобы открыть эти ресурсы с помощью необработанного InputStream, вызовите Resources.openRawResource () с идентификатором ресурса, которым является R.raw.filename.

Однако, если вам нужен доступ к исходным именам файлов и иерархии файлов, вы можете подумать о сохранении некоторых ресурсов в каталоге assets / (вместо res / raw /). Файлы в assets / не имеют идентификатора ресурса, поэтому вы можете читать их только с помощью AssetManager.

мах
источник
5
Если я хочу встроить файл JSON в свое приложение, где мне его разместить? в папке с ресурсами или в необработанной папке? Благодарность!
Рикардо
12

Как и в @mah, в документации Android ( https://developer.android.com/guide/topics/resources/providing-resources.html ) говорится, что файлы json могут быть сохранены в каталоге / raw в каталоге / res (resources). каталог в вашем проекте, например:

MyProject/
  src/ 
    MyActivity.java
  res/
    drawable/ 
        graphic.png
    layout/ 
        main.xml
        info.xml
    mipmap/ 
        icon.png
    values/ 
        strings.xml
    raw/
        myjsonfile.json

Внутри Activityjson-файла можно получить доступ через Rкласс (Resources) и прочитать его в String:

Context context = this;
Inputstream inputStream = context.getResources().openRawResource(R.raw.myjsonfile);
String jsonString = new Scanner(inputStream).useDelimiter("\\A").next();

При этом используется класс Java Scanner, что приводит к меньшему количеству строк кода, чем некоторые другие методы чтения простого текстового / json-файла. Образец разделителя \Aозначает «начало ввода». .next()читает следующий токен, которым в данном случае является весь файл.

Есть несколько способов проанализировать полученную строку json:

  • Используйте Java / Android, встроенные в объекты JSONObject и JSONArray , как здесь: Итерация массива JSON в Android / Java . Это может быть удобно , чтобы получить строки, числа и т.д. , используя optString(String name), и optInt(String name)т.д. методы, а не getString(String name), getInt(String name)методы, потому что optметоды возвращают нуль вместо исключения в случае неудачи.
  • Используйте библиотеку сериализации / десериализации Java / Android json, подобную той, которая указана здесь: https://medium.com/@IlyaEremin/android-json-parsers-comparison-2017-8b5221721e31
ʕ ᵔᴥᵔ ʔ
источник
1
это должен быть принятый ответ, всего две строчки и готово.Спасибо
Ashana.Jackol
потребностиimport java.util.Scanner; import java.io.InputStream; import android.content.Context;
Эндрю Харви
4
InputStream is = mContext.getResources().openRawResource(R.raw.json_regions);
                            int size = is.available();
                            byte[] buffer = new byte[size];
                            is.read(buffer);
                            is.close();
                           String json = new String(buffer, "UTF-8");
NickUnuchek
источник
1

С помощью:

String json_string = readRawResource(R.raw.json)

Функции:

public String readRawResource(@RawRes int res) {
    return readStream(context.getResources().openRawResource(res));
}

private String readStream(InputStream is) {
    Scanner s = new Scanner(is).useDelimiter("\\A");
    return s.hasNext() ? s.next() : "";
}
Махди Астаней
источник
0

Нашел этот ответ на фрагмент Kotlin очень полезным ♥ ️

Хотя исходный вопрос был задан для получения строки JSON, я полагаю, что некоторые могут найти это полезным. Следующий шаг Gsonведет к этой маленькой функции с овеществленным типом:

private inline fun <reified T> readRawJson(@RawRes rawResId: Int): T {
    resources.openRawResource(rawResId).bufferedReader().use {
        return gson.fromJson<T>(it, object: TypeToken<T>() {}.type)
    }
}

Обратите внимание, что вы хотите использовать TypeTokenне просто T::classтак, если вы прочтете, List<YourType>вы не потеряете тип за стиранием типа.

Затем вы можете использовать вывод типа следующим образом:

fun pricingData(): List<PricingData> = readRawJson(R.raw.mock_pricing_data)
Mightyjon
источник