techno techno - 23 days ago 5
Android Question

How to return JSON Object from PHP to read from Android App

I have the following

MySQL
table.

enter image description here

I need to send the dealer name from
android
app and send all matching rows to the app.I dont know how to set the
php
output.I know i should encode using
json_encode(array('stuff'));


But i dont know how to format the data.Been checking http://www.w3schools.com/json/ It shows an example

{"employees":[
{"firstName":"John", "lastName":"Doe"},
{"firstName":"Anna", "lastName":"Smith"},
{"firstName":"Peter", "lastName":"Jones"}
]}


Should i use the same format?How to read this from android ?Im referring http://www.codeproject.com/Articles/267023/Send-and-receive-json-between-android-and-php

EDIT:

<?php

//$con goes here
$result=$conn->query("SELECT pname FROM products");
$response["stuff"] = array();

while($row = $result->fetch_assoc()) {

$stuff= array();

/* ADD THE TABLE COLUMNS TO THE JSON OBJECT CONTENTS */
$stuff["pname"] = $row['pname'];
array_push($response["stuff"], $stuff);

// $response[] = $row;
}
// success
$response["success"] = 1;
echo(json_encode($response));


/* CLOSE THE CONNECTION */
mysqli_close($conn );
?>


JAVA Code:

package com.example.testing;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.json.JSONArray;
import org.json.JSONObject;

import android.os.AsyncTask;
import android.util.Log;

class testing extends AsyncTask<Void, Void, Void> {
JSONParser jParser;
String URL_TO_PHP = "http://coolsite.com/dashboard/test.php";
String TAG_SUCCESS = "success";
String TAG_STUFF = "stuff";

protected Void doInBackground(Void... args) {

/* Building Parameters */
List <NameValuePair> params = new ArrayList<NameValuePair>();

/* getting JSON string from URL */
JSONObject json = jParser.makeHttpRequest(URL_TO_PHP, "GET", params);

try {
/* Checking for SUCCESS TAG */
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
JSONArray JAStuff = json.getJSONArray(TAG_STUFF);

/** CHECK THE NUMBER OF RECORDS **/
int intStuff = JAStuff.length();

if (intStuff != 0) {

for (int i = 0; i < JAStuff.length(); i++) {
JSONObject JOStuff = JAStuff.getJSONObject(i);
Log.e("ALL THE STUFF", JOStuff.toString());

}
}
}
} catch (Exception e) {
e.printStackTrace();
}

return null;
}
}


Main activity

package com.example.testing;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

public class MainActivity extends Activity {

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

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);

}
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
new testing().execute();
break;
default:
break;
}

}


}


Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testing"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="21" />

<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>


JSON Response in PHP

{"stuff":[{"pname":"Advocates"},{"pname":"Notaries"},{"pname":"Agriculture \/ Fertilizer"},{"pname":"Airconditioners"},{"pname":"Animation"},{"pname":"Airline Companies"},{"pname":"Aluminium Fabricators"},{"pname":"Amusement Parks"},{"pname":"Pets shop"},{"pname":"Association \/ Societies"},{"pname":"Astrology"},{"pname":"Attestation Service"},{"pname":"Auditorium"},{"pname":"Automobiles Accessories"},{"pname":"Automobile Dealers"},{"pname":"Ayurveda"},{"pname":"Gifts Articles"},{"pname":"Bags"},{"pname":"Batteries"},{"pname":"Bearings"},{"pname":"Beauty Parlours \/ Spa"},{"pname":"Magazine Dealers"},{"pname":"Building Contractors"},{"pname":"Building Materials"},{"pname":"Cameras"},{"pname":"Cast Iron Products"},{"pname":"Home Delivery"},{"pname":"Cements Wholesale \/ Retail"},{"pname":"Chemicals"},{"pname":"Contractors"},{"pname":"Consultants"},{"pname":"Parcel Services"},{"pname":"Crockery"},{"pname":"Dental Clinics"},{"pname":"Cyber Parks"},{"pname":"Dance School\/Costumes"},{"pname":"Diagnostics Labs& X-Rays"},{"pname":"Distance Education"},{"pname":"Driving Schools"},{"pname":"Dry Cleaners"},{"pname":"DTH Services"},{"pname":"DTP Centers"},{"pname":"Electrical Contractors \/ Services"},{"pname":"Electronics Equipment \/ Servicing"},{"pname":"Coaching Centre"},{"pname":"Event Management"},{"pname":"Fancy \/ Stationery"},{"pname":"Pooja stores"},{"pname":"Food Products"},{"pname":"Foot Wear"},{"pname":"Foreign Exchange"},{"pname":"Furniture shop"},{"pname":"Granites \/ Marbles"},{"pname":"Hospitals \/ Clinics"},{"pname":"Computer Accessories"},{"pname":"Kitchen Cabinets"},{"pname":"Library"},{"pname":"Lights \/ Fittings"},{"pname":"Mobile Phone Accesseries"},{"pname":"Machinery \/ Tools"},{"pname":"Timber Manufacturer"},{"pname":"Real Estate Agents"},{"pname":"Security Services"},{"pname":"Solar Products"},{"pname":"Health & Fitness"},{"pname":"Travel Agencies"},{"pname":"Used Car \/ Bikes"},{"pname":"Waste Management"},{"pname":"Watches & Clocks"},{"pname":"Handicrafts"},{"pname":"Doors & Windows"}],"success":1}

Answer

Since you post does not mention a working PHP file, I will include it for the sake of completeness. This could be a long (long) post....

So, first. This is an example of a PHP file that is stored with the name my_test.php in at this location: c:\wamp\www\some_folder_name\my_test.php (Please see the edit history for the code)

Now, let me explain the important portions of this PHP. These parameters should be configured to use your settings:

$DB_HOST = 'YOUR_IP_ADDRESS';
$DB_UNAME = 'MYSQL_USERNAME';
$DB_PWD = 'MYSQL_USER'S_PASSWORD';
$DB_DATABASE = 'DATABASE_NAME';

The IP Address should be either localhost or the IP address of the computer hosting the MySQL database. Preferably an IP address so you can test on physical devices. using localhost would work only on Virtual Devices.

Next up is adding the columns to an array that will construct a single record (row) in the JSON response. Take a look at this line for example:

$stuff["id"] = $row['id'];

The $stuff["id"] will basically become the tag in the resulting JSON Object whereas the $row['id'] is what indicates the column name from your DB's table. So the $row["...."] has to be identical to the column names in the DB table. While the $stuff["...."] can be just about anything. As long as it makes sense to you.

This line echo(json_encode($response)); will convert the response into a JSON format.

Now lets look at the Java code. First up in this is a class that will help you parse through the result. It was taken off a tutorial off a website (I don't remember which). Just copy an paste the following code in a Java class. No need to change anything in this file. Do give it a good read to understand how it works. I have it named JSONParser (Please see the edit history for the code):

Finally, how would to actually get the resulting JSON and parse it in an Activity / Fragment.

I parse the data in an AsyncTask, which is required anyway considering you will be performing a network operation. (Please see the edit history for the code)

Points to note in this Java:

  1. This String URL_TO_PHP = "http://IP_ADDRESS/some_folder_name/my_test.php"; needs to have either an IP address such as 192.168.0.x or if you are testing on a virtual device, it should be 10.0.2.2. The earlier (192..) won't work on an emulator and the later (10.0...) won't work on a physical device.
  2. In this: String TAG_STUFF = "stuff";, the "stuff" corresponds with this from the PHP file: $response["stuff"] = array();. The TAG_STUFF should basically use whats in $response["stuff"].

Hope all the above makes sense. Comment if you need help. ;-)

UPDATED WITH WORKING SOLUTION:

This is very weird indeed. But, I have a working solution. When using the OP's code, the application indeed crashes. For lack of time to test why it crashes, I am instead posting a solution directly.

First, instead of keeping testing as an independent class, create it as an inner class back in the MainActivity.

class testing extends AsyncTask<Void, Void, Void>   {
....
}

Second, declare the variables globally (the jParser, URL_TO_PHP, etc), as against the current declarations before the onPreExecute(). See the complete solution below for clarity...

public class MainActivity extends Activity {

    JSONParser jParser;
    String URL_TO_PHP = "http://testbox.site50.net/test.php";
    String TAG_SUCCESS = "success";
    String TAG_STUFF = "stuff";

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

    ....

    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button1:
                new testing().execute();
                break;
            default:
                break;
        }

    }

    private class testing extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected Void doInBackground(Void... args) {

            /* Building Parameters */
            List<NameValuePair> params = new ArrayList<>();

            /* getting JSON string from URL */
            JSONObject json = jParser.makeHttpRequest(URL_TO_PHP, "GET", params);

            try {
                /* Checking for SUCCESS TAG */
                int success = json.getInt(TAG_SUCCESS);
                if (success == 1) {
                    JSONArray JAStuff = json.getJSONArray(TAG_STUFF);

                    /** CHECK THE NUMBER OF RECORDS **/
                    int intStuff = JAStuff.length();

                    if (intStuff != 0) {

                        for (int i = 0; i < JAStuff.length(); i++) {
                            JSONObject JOStuff = JAStuff.getJSONObject(i);
                            Log.e("ALL THE STUFF", JOStuff.toString());
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
        }
    }
}

While testing, I also took a screengrab of the results. Here it is: enter image description here

Again, because I am stretched a little thin at the moment, I won't be able to go find out what really is causing the crash in the OP's code. But it's intriguing enough to find out..