Verwenden der JSON-Datei in Android App-Ressourcen

85

Angenommen, ich habe eine Datei mit JSON-Inhalten im Rohressourcenordner meiner App. Wie kann ich dies in die App einlesen, damit ich den JSON analysieren kann?

yydl
quelle

Antworten:

141

Siehe openRawResource . So etwas sollte funktionieren:

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
quelle
1
Was ist, wenn ich den String in eine String-Ressource in Android einfügen und ihn dynamisch mit getResources (). GetString (R.String.name) verwenden möchte?
Ankur Gautam
Für mich funktioniert es nicht wegen der Zitate, die beim Lesen ignoriert werden und die auch nicht zu entkommen scheinen
Marian Klühspies
1
Gibt es eine Möglichkeit, ButterKnife dazu zu bringen , die Rohstoffressource zu binden? Das Schreiben von mehr als 10 Codezeilen, nur um eine Zeichenfolge zu lesen, scheint ein wenig übertrieben zu sein.
Jezor
Wie wird der JSON in den Ressourcen gespeichert? Einfach im \res\json_file.jsonOrdner oder drinnen \res\raw\json_file.json?
Cliff Burton
Dieser Antwort fehlen wichtige Informationen. Wo kann getResources()man anrufen? Wohin soll die Rohressourcendatei gehen? Welche Konvention sollten Sie befolgen, um sicherzustellen, dass die Build-Tools erstellt werden R.raw.json_file?
NobodyMan
108

Kotlin ist jetzt die offizielle Sprache für Android, daher denke ich, dass dies für jemanden nützlich wäre

val text = resources.openRawResource(R.raw.your_text_file)
                                 .bufferedReader().use { it.readText() }
Dima Rostopira
quelle
24

Ich habe die Antwort von @ kabuko verwendet, um ein Objekt zu erstellen, das aus einer JSON-Datei mit Gson aus den Ressourcen geladen wird:

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

Um es zu verwenden, würden Sie Folgendes tun (das Beispiel befindet sich in einem 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
quelle
3
Vergessen Sie nicht, Abhängigkeiten {compile com.google.code.gson: gson: 2.8.2 '} zu Ihrer Gradle-Datei
hinzuzufügen
letzte Version von GSON istimplementation 'com.google.code.gson:gson:2.8.5'
Daniel
12

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

Raw /
Arbitrary-Dateien, die in ihrer Raw-Form gespeichert werden sollen. Um diese Ressourcen mit einem unformatierten InputStream zu öffnen, rufen Sie Resources.openRawResource () mit der Ressourcen-ID R.raw.filename auf.

Wenn Sie jedoch Zugriff auf die ursprünglichen Dateinamen und die Dateihierarchie benötigen, können Sie einige Ressourcen im Verzeichnis resources / (anstelle von res / raw /) speichern. Dateien in Assets / erhalten keine Ressourcen-ID, sodass Sie sie nur mit AssetManager lesen können.

mah
quelle
5
Wenn ich eine JSON-Datei in meine App einbetten möchte, wo soll ich sie ablegen? im Assets-Ordner oder Raw-Ordner? Vielen Dank!
Ricardo
11

Wie in @mah angegeben, heißt es in der Android-Dokumentation ( https://developer.android.com/guide/topics/resources/providing-resources.html ), dass JSON-Dateien möglicherweise im Verzeichnis / raw unter / res (resources) gespeichert werden. Verzeichnis in Ihrem Projekt, zum Beispiel:

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

Innerhalb von Activitykann auf die json-Datei über die RKlasse (Resources) zugegriffen und in einen String eingelesen werden:

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

Dies verwendet die Java-Klasse Scanner, was zu weniger Codezeilen führt als einige andere Methoden zum Lesen einer einfachen Text- / JSON-Datei. Das Begrenzungsmuster \Abedeutet "der Beginn der Eingabe". .next()liest das nächste Token, in diesem Fall die gesamte Datei.

Es gibt mehrere Möglichkeiten, die resultierende JSON-Zeichenfolge zu analysieren:

ʕ ᵔᴥᵔ ʔ
quelle
1
Dies sollte die akzeptierte Antwort sein, nur zwei Zeilen und fertig. Danke
Ashana.Jackol
brauchtimport 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
quelle
1

Verwenden von:

String json_string = readRawResource(R.raw.json)

Funktionen:

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
quelle
0

Fand diese Kotlin Snippet Antwort sehr hilfreich ♥ ️

Während die ursprüngliche Frage gestellt wurde, um einen JSON-String zu erhalten, denke ich, dass einige dies nützlich finden könnten. Ein weiterer Schritt mit Gsonführt zu dieser kleinen Funktion mit reifiziertem Typ:

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

Beachten Sie, dass Sie TypeTokennicht nur verwenden möchten, um beim T::classLesen von a List<YourType>die Löschung von Typ zu Typ nicht zu verlieren.

Mit der Typinferenz können Sie dann wie folgt verwenden:

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