Search code examples
phpandroidjsonwebviewandroid-webview

How to Parse Dynamic JSON in Android App?


So today I have got a dynamic JSON file "json.php" which changes it's content depending on if the user is logged in or not. I want to parse this JSON file in my android app.

My Problem: I am unable to parse the dynamic value of "id" within my JSON file. Current Problem: Does not really matter if the user is logged in or not, the output of json.php is always as of the logged out state. I want to add session support within my current JSON parsing method just like my Web View.

Have a look at json.php

json.php

<?php
session_start();
if (isset($_SESSION['access_token'])) {
    echo '{"userinfo": [{"status": "loggedin","id": "1"}]}';
} else {
    echo '{"userinfo": [{"status": "loggedout","id": "0"}]}';
}
?>

So, If the user is logged in the output of json.php will be this and vice versa:

{"userinfo": [{"status": "loggedin","id": "1"}]}

Coming to the Android part:

MainActivity.java

package com.example.app;
import ...

public class MainActivity extends AppCompatActivity {
private WebView MywebView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Firing up the fetchData.java process
        fetchData process = new fetchData();
        process.execute();

        MywebView = (WebView) findViewById(R.id.main); //Assigning WebView to WebView Frame "main".
        MywebView.loadUrl("https://example.com/"); //the url that app is going to open
        MywebView.setWebViewClient(new WebViewClient());

        //set and tweak webview settings from here
        WebSettings MywebSettings = MywebView.getSettings();
        MywebSettings.setJavaScriptEnabled(true);
        MywebSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
    }
}

fetchData.java

We parse the JSON here as a background process in this file. We convert the "id" into a string so that we can use it further. I took the help of this tutorial.

package com.example.app;
import ...

public class fetchData extends AsyncTask<Void, Void, Void> {
    @Override
     protected Void doInBackground(Void... voids) {
         HttpHandler sh = new HttpHandler();
         String url = "https://example.com/json.php";
         String jsonStr = sh.makeServiceCall(url);
         String webUserID;
         if (jsonStr != null) {
             try {
                 JSONObject jsonObj = new JSONObject(jsonStr);
                 JSONArray info = jsonObj.getJSONArray("userinfo");
                     JSONObject c = info.getJSONObject(0);
                     webUserID = c.getString("id");
             } catch (final JSONException e) {
                 Log.e("TAG", "Json parsing error: " + e.getMessage());
             }
         } else {
             Log.e("TAG", "Couldn't get JSON from server.");
         }
         //here I do whatever I want with the string webUserID
         //Generally used to set OneSignal External ID
         return null;
     }
}

HttpHandler.java

Additionally we have got a HTTP handler file handing all of our requests.

package com.example.app;
import ...

class HttpHandler {

    private static final String TAG = HttpHandler.class.getSimpleName();

    HttpHandler() {
    }

    String makeServiceCall(String reqUrl) {
        String response = null;
        try {
            URL url = new URL(reqUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            // read the response
            InputStream in = new BufferedInputStream(conn.getInputStream());
            response = convertStreamToString(in);
        } catch (MalformedURLException e) {
            Log.e(TAG, "MalformedURLException: " + e.getMessage());
        } catch (ProtocolException e) {
            Log.e(TAG, "ProtocolException: " + e.getMessage());
        } catch (IOException e) {
            Log.e(TAG, "IOException: " + e.getMessage());
        } catch (Exception e) {
            Log.e(TAG, "Exception: " + e.getMessage());
        }
        return response;
    }

    private String convertStreamToString(InputStream is) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();

        String line;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line).append('\n');
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return sb.toString();
    }
}

So, what are the possible ways of getting what I want? Your help is very much appreciated. Thanks.


Additionally, I am adding the index.php and home.php just in case it helps.

index.php

<?php
session_start();
if (isset($_SESSION['access_token'])) {
    header('Location: home.php');
    exit();
} elseif (!isset($_SESSION['access_token']) && isset($_COOKIE['access_token'])) {
    $_SESSION['access_token'] = $_COOKIE['access_token'];
    header('Location: home.php');
    exit();
}
if (isset($_POST['login'])) {
    setcookie("access_token", "123456", time()+60*60*24*30);
    $_SESSION['access_token'] = "123456";
    header("Location: home.php");
    exit;
}
?>
<html>
    <head>
        <title>Internal Testing Site</title>
    </head>
    <body>
        <h1>Internal cache testing website</h1>
        <hr>
        <p>You are currently logged out.</p>
        <form method="POST">
            <button name="login">Click me to login</button>
        </form>
    </body>
</html>

home.php

<?php
session_start();
if (!isset($_SESSION['access_token'])) {
    header('Location: index.php');
    exit();
}
?>
<html>
    <head>
        <title>Internal Testing Site</title>
    </head>
    <body>
        <h1>internal cache testing website</h1>
        <hr>
        <p><b>You are currently logged in.</b></p>
        <a href="json.php">See JSON</a>
    </body>
</html>

The Solution: Even if this answer solves the problem, it comes with it's own set of problems. Even if you choose to just take the Web View cookies and scrape the data from it, the app might crash when there is no internet connection. You can follow up this thread here for more information.


Solution

  • You store the infos about logged in or not in cookies or session via WebView but you want to access to that data from with a http client. I think it would be better you should sync cookies and session before access the json. To do this check this and this.