Aborroum Aborroum - 7 months ago 22
PHP Question

Android is not Reading JSON Array with name

it seems that my Activity is having problem with the JSON array name

here is my activity :

package com.example.raamzz.booksharev2;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Base64;
import android.view.GestureDetector;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageButton;
import android.widget.Toast;





import com.example.raamzz.booksharev2.CustomListAdapter;
import com.example.raamzz.booksharev2.AppController;
import com.example.raamzz.booksharev2.Book;

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

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.widget.ListView;

import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.JsonArrayRequest;

public class Romance extends AppCompatActivity {


String TITLES[] = {"Home","Events","Books","Wishlist","Nearby","Edit Profile "};
int ICONS[] = {R.drawable.home,R.drawable.events,R.drawable.books,R.drawable.wishlist,R.drawable.taxi,R.drawable.edit};








private Toolbar toolbar; // Declaring the Toolbar Object

RecyclerView mRecyclerView; // Declaring RecyclerView
RecyclerView.Adapter mAdapter; // Declaring Adapter For Recycler View
RecyclerView.LayoutManager mLayoutManager; // Declaring Layout Manager as a linear layout manager
DrawerLayout Drawer; // Declaring DrawerLayout

ActionBarDrawerToggle mDrawerToggle; // Declaring Action Bar Drawer Toggle



String UserID,UserFN,UserEmail,UserPassword,UserAddress,UserPhone,UserGender,UDOB,ProfPicture;

public static final String DEFUALT_SHARED="N/A";


//---------------------------------//


// Log tag
private static final String TAG = Romance.class.getSimpleName();

// Movies json url
private static final String url = "http://mybookshare.com/app/GetRomanceBooks.php";
private ProgressDialog pDialog;
private List<Book> bookList = new ArrayList<Book>();
private ListView listView;
private CustomListAdapter adapter;





@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_romance);
SharedPreferences sp =getSharedPreferences("UserData", Context.MODE_PRIVATE);
UserID = sp.getString("UserID", DEFUALT_SHARED );
UserFN=sp.getString("UserFN",DEFUALT_SHARED);
UserEmail=sp.getString("UserEmail",DEFUALT_SHARED);
ProfPicture=sp.getString("ProfPicture",DEFUALT_SHARED);


//-----------------------------------//

listView = (ListView) findViewById(R.id.list);
adapter = new CustomListAdapter(this, bookList);
listView.setAdapter(adapter);

pDialog = new ProgressDialog(this);

// Showing progress dialog before making http request
pDialog.setMessage("Loading...");
pDialog.show();

//-----------------------------------//





byte[] decodedString = Base64.decode(ProfPicture, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);



/* Assinging the toolbar object ot the view
and setting the the Action bar to our toolbar
*/
toolbar = (Toolbar) findViewById(R.id.app_bar);
setSupportActionBar(toolbar);




mRecyclerView = (RecyclerView) findViewById(R.id.RecyclerView); // Assigning the RecyclerView Object to the xml View

mRecyclerView.setHasFixedSize(true); // Letting the system know that the list objects are of fixed size

mAdapter = new MyAdapter(TITLES,ICONS,UserFN,UserEmail,decodedByte); // Creating the Adapter of MyAdapter class(which we are going to see in a bit)
// And passing the titles,icons,header view name, header view email,
// and header view profile picture

mRecyclerView.setAdapter(mAdapter); // Setting the adapter to RecyclerView


final GestureDetector mGestureDetector = new GestureDetector(Romance.this, new GestureDetector.SimpleOnGestureListener() {

@Override public boolean onSingleTapUp(MotionEvent e) {
return true;
}

});



mRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
@Override
public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
View child = recyclerView.findChildViewUnder(motionEvent.getX(),motionEvent.getY());



if(child!=null && mGestureDetector.onTouchEvent(motionEvent)){

int position=recyclerView.getChildAdapterPosition(child);

switch (position){

case 1:
Intent intent1 = new Intent(Romance.this, UserProfileHOME.class);
Toast.makeText(getApplicationContext(), "Case 1 in home to event", Toast.LENGTH_LONG).show();
Romance.this.startActivity(intent1);
break;


case 2:
Intent intent2 = new Intent(Romance.this, Events.class);
Toast.makeText(getApplicationContext(), "Case 2 in home to event", Toast.LENGTH_LONG).show();
Romance.this.startActivity(intent2);
break;

case 3:
Intent intent3 = new Intent(Romance.this, Books.class);
Toast.makeText(getApplicationContext(), "Case 3 in home to books", Toast.LENGTH_LONG).show();
Romance.this.startActivity(intent3);
break;

case 4:
Intent intent4 = new Intent(Romance.this, Wishlist.class);
Toast.makeText(getApplicationContext(), "Case 4 in home to wishlist", Toast.LENGTH_LONG).show();
Romance.this.startActivity(intent4);
break;
case 5:
Intent intent5 = new Intent(Romance.this, Nearby.class);
Toast.makeText(getApplicationContext(), "Case 5 in home to nearby", Toast.LENGTH_LONG).show();
Romance.this.startActivity(intent5);
break;
case 6:
Intent intent6 = new Intent(Romance.this, Editprofile.class);
Toast.makeText(getApplicationContext(), "Case 6 in home to editprof", Toast.LENGTH_LONG).show();
Romance.this.startActivity(intent6);
break;

}

Drawer.closeDrawers();


}

return false;
}

@Override
public void onTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {

}

@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

}
});



mLayoutManager = new LinearLayoutManager(this); // Creating a layout Manager

mRecyclerView.setLayoutManager(mLayoutManager); // Setting the layout Manager


Drawer = (DrawerLayout) findViewById(R.id.DrawerLayout); // Drawer object Assigned to the view
mDrawerToggle = new ActionBarDrawerToggle(this,Drawer,toolbar,R.string.openDrawer,R.string.closeDrawer){

@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
// code here will execute once the drawer is opened( As I dont want anything happened whe drawer is
// open I am not going to put anything here)
}

@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
// Code here will execute once drawer is closed
}



}; // Drawer Toggle Object Made
Drawer.setDrawerListener(mDrawerToggle); // Drawer Listener set to the Drawer toggle
mDrawerToggle.syncState(); // Finally we set the drawer toggle sync State


//-----------------------------------------------------------------------------//


// Creating volley request obj
JsonArrayRequest movieReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();

// Parsing json
for (int i = 0; i < response.length(); i++) {
try {

JSONObject obj = response.getJSONObject(i);
Book book = new Book();
book.setTitle(obj.getString("BTitle"));
book.setThumbnailUrl(obj.getString("BCoverpath"));
book.setAuthor(obj.getString("BAuthor"));
book.setEdition(obj.getString("BEdition"));



// adding movie to movies array
bookList.add(book);

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

}

// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();

}
});

// Adding request to request queue
AppController.getInstance().addToRequestQueue(movieReq);
}

@Override
public void onDestroy() {
super.onDestroy();
hidePDialog();
}

private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}








}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}

}


and here is my php which is sending the json array :

<?php

header('Content-Type: application/json');


$response = array();


require_once('init.php');

$result = mysqli_query($conn,"SELECT *FROM book WHERE IDCateOf = 8") or die(mysql_error());

if (mysqli_num_rows($result) > 0) {

$response["books"]= array();

while ($row = mysqli_fetch_array($result)) {


$books["BID"] = $row["BID"];
$book["BTitle"] = $row["BTitle"];
$book["BAuthor"] = $row["BAuthor"];
$book["BCoverpath"] =$row["BCoverpath"];
$book["BEdition"] = $row["BEdition"];



array_push( $response["books"], $book);

}



echo json_encode($response, JSON_UNESCAPED_SLASHES && JSON_PRETTY_PRINT);
}
?>


the array that is generated using this php script is like this :

{
"books": [
{
"BTitle": "Attachments",
"BAuthor": "Rainbow Rowell",
"BCoverpath": "http://mybookshare.com/books/1.jpg",
"BEdition": "2th"
},
{
"BTitle": "Maybe Someday",
"BAuthor": "Colleen Hoover",
"BCoverpath": "http://mybookshare.com/books/2.jpg",
"BEdition": "1th"
},
{
"BTitle": "Me Before You : A Novel (Movie Tie-In)",
"BAuthor": "Jojo Moyes",
"BCoverpath": "http://mybookshare.com/books/3.jpg",
"BEdition": "1th"
},
{
"BTitle": "Hopeless",
"BAuthor": "Colleen Hoover",
"BCoverpath": "http://mybookshare.com/books/4.jpg",
"BEdition": "1th"
},
{
"BTitle": "Finding Cinderella",
"BAuthor": "Colleen Hoover",
"BCoverpath": "http://mybookshare.com/books/5.jpg",
"BEdition": "1th"
},
{
"BTitle": "November Nine",
"BAuthor": "Colleen Hoover",
"BCoverpath": "http://mybookshare.com/books/6.jpg",
"BEdition": "1th"
},
{
"BTitle": "Ugly Love",
"BAuthor": "Colleen Hoover",
"BCoverpath": "http://mybookshare.com/books/7.jpg",
"BEdition": "3th"
}
]
}


which my android activity is not recognizing because it json array must be like this :

[
{
"BTitle": "Attachments",
"BAuthor": "Rainbow Rowell",
"BCoverpath": "http://mybookshare.com/books/1.jpg",
"BEdition": "2th"
},
{
"BTitle": "Maybe Someday",
"BAuthor": "Colleen Hoover",
"BCoverpath": "http://mybookshare.com/books/2.jpg",
"BEdition": "1th"
},
{
"BTitle": "Me Before You : A Novel (Movie Tie-In)",
"BAuthor": "Jojo Moyes",
"BCoverpath": "http://mybookshare.com/books/3.jpg",
"BEdition": "1th"
},
{
"BTitle": "Hopeless",
"BAuthor": "Colleen Hoover",
"BCoverpath": "http://mybookshare.com/books/4.jpg",
"BEdition": "1th"
},
{
"BTitle": "Finding Cinderella",
"BAuthor": "Colleen Hoover",
"BCoverpath": "http://mybookshare.com/books/5.jpg",
"BEdition": "1th"
},
{
"BTitle": "November Nine",
"BAuthor": "Colleen Hoover",
"BCoverpath": "http://mybookshare.com/books/6.jpg",
"BEdition": "1th"
},
{
"BTitle": "Ugly Love",
"BAuthor": "Colleen Hoover",
"BCoverpath": "http://mybookshare.com/books/7.jpg",
"BEdition": "3th"
}
]


and i tried to make a .json file and i put the last json array without the name and the application worked just fine but i need to solve this problem because i need to get the data dynamically from the database using the php script

Answer

Your first JSON is not an array. It's an object with "books" array in it. You need to create appropriate object for this JSON, like:

class BookList {
    List<Book> books;
}

Here is you modified code to work with that JSON:

JsonArrayRequest movieReq = new JsonArrayRequest(url,
        new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                Log.d(TAG, response.toString());
                hidePDialog();

                // Parsing json
                JSONArray arr = response.getJSONArray("books");

                for (int i = 0; i < arr.length(); i++) {
                    try {
                        JSONObject obj = arr.getJSONObject(i);

                        Book book = new Book();
                        book.setTitle(obj.getString("BTitle"));
                        book.setThumbnailUrl(obj.getString("BCoverpath"));
                        book.setAuthor(obj.getString("BAuthor"));
                        book.setEdition(obj.getString("BEdition"));



                        // adding movie to movies array
                        bookList.add(book);

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

                }

                // notifying list adapter about data changes
                // so that it renders the list view with updated data
                adapter.notifyDataSetChanged();
            }
        }, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        VolleyLog.d(TAG, "Error: " + error.getMessage());
        hidePDialog();

    }
});