ainunqalbi06
ainunqalbi06

Reputation: 1

Populate Android spinner from MySQL database - no items in the list display

I just want to make a simple spinner in my android app. When i try to set items in a spinner, but no items in the list displayed.

My PHP file:

<?php
$con = mysqli_connect("xxxx","xxxx","xxxx","xxxx");
$sql = "select * from mata_kuliah";
$result = mysqli_query($con, $sql) or die("Error in Selecting " . mysqli_error($con));

//create an array
$response = array();
while($row =mysqli_fetch_assoc($result))
{
    $response[] = $row;
}

echo json_encode($response); 
?>

It returns a json string in this format:

[{"id_matkul":"1","kode_matkul":"fffffafafafa","nama_matkul":"adas333","dosen1_matkul":"dddada333","dosen2_matkul":"asdasda"},{"id_matkul":"3","kode_matkul":"asasaaaaa44","nama_matkul":"asas","dosen1_matkul":"asas444","dosen2_matkul":"asa33"}]

My activity code:

package com.qalbistudio.kartukontrolapp;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;

import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.toolbox.Volley;

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

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

    public class DaftarNilaiUtama1 extends AppCompatActivity {

        Spinner sp;
        TextView textView;

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

            sp = (Spinner) findViewById(R.id.spinner);


            Response.Listener<String> responseListener = new Response.Listener<String>() {


            @Override
            public void onResponse(String response) {
                try {


                    JSONObject jsonResponse = new JSONObject(response);
                    JSONArray jsonMainNode = jsonResponse.optJSONArray("response");

                    List<String> item = new ArrayList<String>();

                        for(int i = 0; i < jsonMainNode.length(); i++){

                            JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
                            String nama1 = jsonChildNode.optString("id_matkul");

                            item.add(nama1);

                            ArrayAdapter<String> adapter = new ArrayAdapter<String>(DaftarNilaiUtama1.this,android.R.layout.simple_spinner_dropdown_item, item);

                            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

                            sp.setAdapter(adapter);
                        }

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

                }
        };

        SpRequest spreq = new SpRequest(responseListener);
        RequestQueue queue = Volley.newRequestQueue(DaftarNilaiUtama1.this);
        queue.add(spreq);
    }
}

My server request code:

import com.android.volley.Response;
import com.android.volley.toolbox.StringRequest;

import java.util.Map;

/**
 * Created by callbee on 20/05/2016.
 */
public class SpRequest extends StringRequest {
    private static final String URL = "http://192.168.1.10/KartuKontrolApp/testing.php";
    private Map<String, String> params;

    public SpRequest(Response.Listener<String> listener) {
        super(Method.POST, URL, listener, null);
    }

    public Map<String, String> getParams() {
        return params;
    }
}

Upvotes: 0

Views: 1183

Answers (2)

tony gil
tony gil

Reputation: 9564

Updating from an external server (a task whose completion time may take ages [in processing time]) must be made from within a Thread, like this:

private boolean updateWorkingData() {
    boolean flagOK = false;
    Thread thisThread = null;
    try {
        thisThread = new Thread(new Runnable() {
            @Override
            public void run() {
                Log.w(TAG,"inside JSON thread");
                String urlRest = "http://192.168.1.10/KartuKontrolApp/testing.php"; // TODO 20160523 create a PROPER restful call, verify format
                JSONArray jsonArray = new DbConnectJson().getJSONfromURL(urlRest);
                JSONObject jsonObject = new JSONObject();
                String[][] stringTemp = new String[jsonArray.length()][3];
                try {
                    for (int i=0;i<jsonArray.length();i++) {
                        jsonObject = jsonArray.getJSONObject(i);
                        stringTemp[i][0] = jsonObject.getString("id_matkul");
                        stringTemp[i][1] = jsonObject.getString("kode_matkul");
                        stringTemp[i][2] = jsonObject.getString("nama_matkul"); // etc
                        Log.d(TAG,"id:["+stringTemp[i][0]+"] kode:["+stringTemp[i][1]+"] nama_matkul:["+stringTemp[i][2]+"]");
                    }
                    // TODO 20160523 populate spinner from string array

                } catch (JSONException e) {
                    Log.e(TAG,"CRASHED JSONOBJECT matkul update");
                    e.printStackTrace();
                }
            }
        });
        thisThread.start();
        flagOK = true; // means that the thread was CALLED without CRASH
    } catch (Exception e) {
        Log.e(TAG,"CRASHED JSONOBJECT Thread");
        e.printStackTrace();
    }
    return flagOK;  
}

when you call this thread, you must have protocols of LATER verifying if it worked ok and data was updated.

I would further recommend that you save your spinner data to a SQLite adapter (think of of a MySQL table), which will be stored in a permanent manner with security (it is saved in app's sandbox, inaccessible from outside apps - not what happens if you save data to a TXT file on your device).

Therefore, user doesnt absolutely have to go online EVERY time he/she fires app up.

When app loads, you verify if there is data in adapter and use that data, while you check your RESTful php on your server (as a background test) and establish if updates are available. If, and only if, your app confirms the need to update app fires the update thread again.

Upvotes: 1

Linh
Linh

Reputation: 60973

Do not create the adapter and set adapter for spinner inside the for loop.
You adapter will create multiple time

...
List<String> item = new ArrayList<String>();
for (int i = 0; i < jsonMainNode.length(); i++) {
    JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
    String nama1 = jsonChildNode.optString("id_matkul");

    item.add(nama1);
}
ArrayAdapter < String > adapter = new ArrayAdapter < String > (DaftarNilaiUtama1.this, android.R.layout.simple_spinner_dropdown_item, item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
sp.setAdapter(adapter);

Upvotes: 1

Related Questions