Menggunakan File JSON di Sumber Daya Aplikasi Android

88

Misalkan saya memiliki file dengan konten JSON di folder sumber daya mentah di aplikasi saya. Bagaimana saya bisa membaca ini ke dalam aplikasi, sehingga saya bisa mengurai JSON?

yydl
sumber

Jawaban:

145

Lihat openRawResource . Sesuatu seperti ini seharusnya bekerja:

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();
kabuko
sumber
1
Bagaimana jika saya ingin meletakkan string dalam sumber daya String di android dan menggunakannya secara dinamis menggunakan getResources (). GetString (R.String.name)?
Ankur Gautam
Bagi saya itu tidak berhasil karena tanda kutip, yang diabaikan saat membaca dan yang juga tampaknya tidak bisa lepas
Marian Klühspies
1
Apakah ada cara untuk membuat ButterKnife mengikat sumber daya mentah? Menulis 10+ baris kode hanya untuk membaca sebuah string sepertinya terlalu berlebihan.
Jezor
Bagaimana json disimpan di dalam sumber daya? Cukup di dalam \res\json_file.jsonfolder atau di dalam \res\raw\json_file.json?
Cliff Burton
1
Jawaban ini kurang memiliki info kritis. Dimana bisa getResources()dipanggil? Di mana file sumber daya mentah harus disimpan? Konvensi apa yang harus Anda ikuti untuk memastikan alat build dibuat R.raw.json_file?
NobodyMan
114

Kotlin sekarang menjadi bahasa resmi untuk Android, jadi menurut saya ini akan berguna bagi seseorang

val text = resources.openRawResource(R.raw.your_text_file)
                                 .bufferedReader().use { it.readText() }
Dima Rostopira
sumber
Ini adalah operasi yang berpotensi berjalan lama, jadi pastikan ini dibatalkan dari utas utama!
Andrew Orobator
1
@AndrewOrobator Saya ragu seseorang akan menempatkan json besar di dalam sumber daya aplikasi, tapi ya, poin yang bagus
Dima Rostopira
24

Saya menggunakan jawaban @ kabuko untuk membuat objek yang dimuat dari file JSON, menggunakan Gson , dari Resources:

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

Untuk menggunakannya, Anda akan melakukan sesuatu seperti berikut (contohnya dalam 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);
   }
jwir3
sumber
3
Jangan lupa untuk menambahkan dependensi {compile com.google.code.gson: gson: 2.8.2 '} ke file gradle Anda
patrics
versi terakhir GSON adalahimplementation 'com.google.code.gson:gson:2.8.5'
Daniel
13

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


file mentah / sewenang-wenang untuk disimpan dalam bentuk mentahnya. Untuk membuka sumber daya ini dengan InputStream mentah, panggil Resources.openRawResource () dengan ID sumber daya, yaitu R.raw.filename.

Namun, jika Anda memerlukan akses ke nama file asli dan hierarki file, Anda dapat mempertimbangkan untuk menyimpan beberapa resource di direktori assets / (bukan res / raw /). File dalam assets / tidak diberi ID sumber daya, jadi Anda hanya bisa membacanya menggunakan AssetManager.

mah
sumber
5
Jika saya ingin menyematkan file JSON di aplikasi saya, di mana saya harus meletakkannya? di folder aset atau folder mentah? Terima kasih!
Ricardo
13

Seperti status @mah, dokumentasi Android ( https://developer.android.com/guide/topics/resources/providing-resources.html ) mengatakan bahwa file json dapat disimpan di direktori / raw di bawah / res (resources) direktori dalam proyek Anda, misalnya:

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

Di dalam Activity, file json dapat diakses melalui kelas R(Resources), dan dibaca ke String:

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

Ini menggunakan kelas Java Scanner, yang mengarah ke lebih sedikit baris kode daripada beberapa metode lain untuk membaca file teks / json sederhana. Pola pembatas \Aberarti 'awal masukan'. .next()membaca token berikutnya, yang merupakan keseluruhan file dalam kasus ini.

Ada beberapa cara untuk mengurai string json yang dihasilkan:

ʕ ᵔᴥᵔ ʔ
sumber
1
ini harus menjadi jawaban yang diterima, hanya dua baris dan selesai. Terima kasih
Ashana.Jackol
kebutuhanimport 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");
NickUnuchek
sumber
1

Menggunakan:

String json_string = readRawResource(R.raw.json)

Fungsi:

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() : "";
}
Mahdi Astanei
sumber
0

Menemukan jawaban cuplikan Kotlin ini sangat membantu ♥ ️

Sementara pertanyaan asli meminta untuk mendapatkan String JSON, saya pikir beberapa mungkin menganggap ini berguna. Selangkah lebih maju dengan Gsonmengarah ke fungsi kecil ini dengan tipe yang direifikasi:

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

Catatan Anda ingin menggunakan TypeTokentidak hanya T::classjadi jika Anda membaca List<YourType>Anda tidak akan kehilangan jenis demi jenis penghapusan.

Dengan jenis inferensi, Anda dapat menggunakan seperti ini:

fun pricingData(): List<PricingData> = readRawJson(R.raw.mock_pricing_data)
themightyjon
sumber