Використання файлу JSON у ресурсах додатків Android


87

Припустимо, у мене є файл із вмістом JSON у папці необроблених ресурсів у моєму додатку. Як я можу прочитати це в додатку, щоб я міг проаналізувати JSON?

Відповіді:


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)?
Ankur Gautam

Для мене це не працює через цитати, які ігноруються під час читання і яких також, здається, неможливо уникнути
Маріан Клуспіс,

1
Чи є спосіб зробити так, щоб ButterKnife зв’язував вихідний ресурс? Написати 10+ рядків коду, щоб просто прочитати рядок, здається трохи надмірним.
Єзор

Як json зберігається всередині ресурсів? Просто всередині \res\json_file.jsonпапки або всередині \res\raw\json_file.json?
Кліфф Бертон,

У цій відповіді бракує критичної інформації. Куди можна getResources()подзвонити? Куди слід подати файл вихідного ресурсу? Якої конвенції слід дотримуватися, щоб забезпечити створення інструментів складання R.raw.json_file?
Nobody, людина

112

Котлін зараз є офіційною мовою для 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);
    }
}

Щоб використовувати його, ви зробите щось на зразок наступного (приклад наведено в an 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);
   }

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 /). Файлам у ресурсах / не надається ідентифікатор ресурсу, тому читати їх можна лише за допомогою AssetManager.


5
Якщо я хочу вбудувати файл JSON у свою програму, куди його слід помістити? в папці активів чи папці raw? Дякую!
Рікардо

12

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

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

Усередині Activityфайлу json можна отримати доступ через Rклас (Ресурси) і прочитати його в рядку:

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:

  • Використовуйте вбудовані в JSONObject та JSONArray об’єкти Java / Android , як тут: ітерація масиву 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
це повинна бути прийнята відповідь, лише два рядки і готово. Дякую
Ашана. Яколь

потребиimport java.util.Scanner; import java.io.InputStream; import android.content.Context;
AndrewHarvey

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");

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

Знайдено цього Котлин SNIPPET відповідь дуже корисно ♥ ️

Хоча в оригінальному запитанні було задано рядок 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так, якщо ви прочитаєте a, List<YourType>ви не втратите тип за стиранням стирання.

З висновком типу ви можете використовувати наступне:

fun pricingData(): List<PricingData> = readRawJson(R.raw.mock_pricing_data)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.