0

I am having a lot of difficulty using Kumulos to populate a ListView. Through my research Ive found numerous tutorials and postings about using SQLite or other databases but nothing with Kumulos =/.

What I need help with:

1) Implementation of Kumulos to fill a ListView

Source: https://docs.kumulos.com/integration/android/

Research conducted:

Encode and decode bitmap object in base64 string in Android

HashMap to ListView

How to retrieve data from DBHelper by HashMap in Multicolumn ListView

HashMap to ListView

MAIN ACTIVITY:

public class PersonSearchPop extends Activity {

private ListView personlist;
private CustomListViewAdapter customListViewAdapter;
public static final String YOUR_API_KEY = "HIDDEN";
public static final String YOUR_SECRET_KEY = "HIDDEN";

public static String encodeToBase64(Bitmap image, Bitmap.CompressFormat compressFormat, int quality)
{
    ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
    image.compress(compressFormat, quality, byteArrayOS);
    return Base64.encodeToString(byteArrayOS.toByteArray(), Base64.DEFAULT);
}

public static Bitmap decodeBase64(String input)
{
    byte[] decodedBytes = Base64.decode(input, 0);
    return BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
}


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

    Kumulos.initWithAPIKeyAndSecretKey(YOUR_API_KEY, YOUR_SECRET_KEY, this);

    DisplayMetrics dm = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(dm);

    int width = dm.widthPixels;
    int height = dm.heightPixels;

    getWindow().setLayout((int) (width * .4), (int) (height * .6));

   ?????????????????????????????????????????????????????????????????????????????????


    personlist.setOnItemClickListener(new AdapterView.OnItemClickListener(){
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id){
            finish();
        }
    });
}

}

CUSTOM ADAPTER:

public class CustomListViewAdapter extends CursorAdapter {

public CustomListViewAdapter(Context context, Cursor c){
    super (context, c);
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {

    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View retView = inflater.inflate(R.layout.personlist_row, parent, false);
    return retView;
}

@Override
public void bindView(View view, Context context, Cursor cursor) {

    TextView dl = (TextView) view.findViewById(R.id.tvdl);
    dl.setText(cursor.getString(cursor.getColumnIndex(cursor.getColumnName(7))));

    TextView last = (TextView) view.findViewById(R.id.tvLastName);
    last.setText(cursor.getString(cursor.getColumnIndex(cursor.getColumnName(1))));

    TextView first = (TextView) view.findViewById(R.id.tvFirstName);
    first.setText(cursor.getString(cursor.getColumnIndex(cursor.getColumnName(3))));

    TextView middle = (TextView) view.findViewById(R.id.tvMiddleName);
    middle.setText(cursor.getString(cursor.getColumnIndex(cursor.getColumnName(2))));

    TextView ss = (TextView) view.findViewById(R.id.tvSS);
    ss.setText(cursor.getString(cursor.getColumnIndex(cursor.getColumnName(8))));

    //ImageView image = (ImageView) view.findViewById(R.id.idPic);
    //image.setImageDrawable(cursor.getString(cursor.getColumnIndex(cursor.getColumnName(12))));
}

}

ENTER DATA:

public class EnterData extends Activity {

EditText lName;
EditText dl;
EditText ss;

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.persons_popup);

    lName = (EditText) findViewById(R.id.etLastName);
    dl = (EditText) findViewById(R.id.etDL);
    ss = (EditText) findViewById(R.id.etSocial);
}

public void onClickSearch (View btnSearch) {

    String personName = lName.getText().toString();
    String personDL = dl.getText().toString();
    String personSS = ss.getText().toString();

    }
}

}

UPDATE: Ok, I changed my code to just two classes and it seems to be working. I am getting an error from Kumulos however =/.

Kumulos error: {"responseCode":32,"responseMessage":"Invalid request: ","payload":null,"sessionToken":"b29366e44a7cdbb905db18b51995e545daf4f816","requestedMethod":"searchPerson","requestedFormat":"json","timestamp":1462147387,"requestReceivedTime":1462147387,"maxAllowedRequestTime":40,"requestProcessingTime":0.012163877487183}

PersonSearchPop:

public class PersonSearchPop extends ListActivity {

public static final String YOUR_API_KEY = "HIDDEN";
public static final String YOUR_SECRET_KEY = "HIDDEN";

static class Person {

    public long personID;
    public String lastName;
    public String middleName;
    public String firstName;
    public String dateOfBirth;
    public String personAddress;
    public int phoneNumber;
    public int driversLicense;
    public int socialSecurity;
    public String personRace;
    public String personSex;
    public String personAge;

    public static Person createFromGenericMap(Map<String, Object> object) {

        Person p = new Person();

        p.personID = (long) object.get("personID");
        p.lastName = (String) object.get("lastName");
        p.middleName = (String) object.get("middleName");
        p.firstName = (String) object.get("firstName");
        p.dateOfBirth = (String) object.get("dob");
        p.personAddress = (String) object.get("address");
        p.phoneNumber = (int) object.get("phone");
        p.driversLicense = (int) object.get("dl");
        p.socialSecurity = (int) object.get("ss");
        p.personRace = (String) object.get("race");
        p.personSex = (String) object.get("sex");
        p.personAge = (String) object.get("age");

        return p;
    }

}

static class PersonAdapter extends BaseAdapter {

    private List<Person> people;

    public PersonAdapter(List<Person> people) {
        this.people = people;
        //inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }


    @Override
    public int getCount() {
        return people.size();
    }

    @Override
    public Object getItem(int position) {
        return people.get(position);
    }

    @Override
    public long getItemId(int position) {
        Person p = people.get(position);
        return p.personID;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View view = convertView;

        if (convertView == null) {


            TextView dl = (TextView) view.findViewById(R.id.tvdl);
            TextView last = (TextView) view.findViewById(R.id.tvLastName);
            TextView first = (TextView) view.findViewById(R.id.tvFirstName);
            TextView middle = (TextView) view.findViewById(R.id.tvMiddleName);
            TextView ss = (TextView) view.findViewById(R.id.tvSS);

            Person mperson = people.get(position);

            dl.setText(mperson.driversLicense);
            last.setText(mperson.lastName);
            first.setText(mperson.firstName);
            middle.setText(mperson.middleName);
            ss.setText(mperson.socialSecurity);
            //ImageView image = (ImageView) view.findViewById(R.id.idPic);
            //image.setImageDrawable(cursor.getString(cursor.getColumnIndex(cursor.getColumnName(12))));
        }
        return view;
    }
}

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

    Kumulos.initWithAPIKeyAndSecretKey(YOUR_API_KEY, YOUR_SECRET_KEY, this);

    DisplayMetrics dm = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(dm);

    int width = dm.widthPixels;
    int height = dm.heightPixels;

    getWindow().setLayout((int) (width * .4), (int) (height * .6));

    // Call Kumulos
    Map<String, String> params = new HashMap<>();
    Intent intent = getIntent();
    String lastName = intent.getStringExtra("lastName");
    params.put("lastName",String.valueOf(lastName));
    Kumulos.call("searchPerson", params, new ResponseHandler() {

        // Handle result
        @Override
        public void didCompleteWithResult(Object result) {
            super.didCompleteWithResult(result);

            // Cast generic response down to list of maps
            ArrayList<LinkedHashMap<String, Object>> objects = (ArrayList<LinkedHashMap<String, Object>>) result;

            // Create a list for the models
            ArrayList<Person> people = new ArrayList<>();

            // Map models from generic objects and add to list
            for (Map<String, Object> personObject : objects) {
                Person p = Person.createFromGenericMap(personObject);
                people.add(p);
            }

            // Create adapter with model list
            final PersonAdapter adapter = new PersonAdapter(people);

            // Set adapter on main UI thread
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    setListAdapter(adapter);
                }
            });
        }
    });
}

}

PersonsPop

 @Override
public void onClick(View v){
    switch(v.getId()){
        case R.id.bCancelPerson:
            finish();
            break;
        case R.id.bSearchPerson:
            EditText lastName = (EditText) findViewById(R.id.etLastName);
            Intent intent = new Intent(PersonsPop.this, PersonSearchPop.class);
            intent.putExtra("lastName", lastName.getText().toString());
            startActivity(new Intent(PersonsPop.this, PersonSearchPop.class));
Community
  • 1
  • 1
F0xcr4f7
  • 61
  • 1
  • 1
  • 10

1 Answers1

0

I'm Chris from Kumulos -- let me try to point you in the right direction.

So in general, the process of displaying data in a list view from a web service looks like:

  1. Call out to the web service and retrieve the list of data

  2. Map those objects down to model classes and either hold in memory or persist to disk

  3. Create an adapter that is backed by the data on the phone

  4. Set the adapter of the list view to be your custom adapter instance

Assuming that you would hold the objects in memory, creating a custom adapter backed by an ArrayList of your model type would be sufficient. This is one of the simplest ways to get started.

So with Kumulos, you could do something like the following:

package com.example.cgwyllie.simplelistview;

import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

import com.kumulos.android.jsonclient.Kumulos;
import com.kumulos.android.jsonclient.ResponseHandler;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class MainActivity extends ListActivity {

    static class Person {

        public long personID;
        public String firstName;
        public String lastName;

        public static Person createFromGenericMap(Map<String, Object> object) {
            Person p = new Person();

            p.personID = (long) object.get("personID");
            p.firstName = (String) object.get("firstName");
            p.lastName = (String) object.get("lastName");

            return p;
        }

    }

    static class PersonAdapter extends BaseAdapter {

        private List<Person> people;

        public PersonAdapter(List<Person> people) {
            this.people = people;
        }

        @Override
        public int getCount() {
            return people.size();
        }

        @Override
        public Object getItem(int position) {
            return people.get(position);
        }

        @Override
        public long getItemId(int position) {
            Person p = people.get(position);
            return p.personID;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO implement your view
            return null;
        }

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Kumulos.initWithAPIKeyAndSecretKey("API_KEY", "SECRET_KEY", this);

        // Call Kumulos
        Map<String,String> params = new HashMap<>();
        Kumulos.call("getPeople", params, new ResponseHandler() {

            // Handle result
            @Override
            public void didCompleteWithResult(Object result) {
                super.didCompleteWithResult(result);

                // Cast generic response down to list of maps
                ArrayList<LinkedHashMap<String, Object>> objects = (ArrayList<LinkedHashMap<String,Object>>) result;

                // Create a list for the models
                ArrayList<Person> people = new ArrayList<>();

                // Map models from generic objects and add to list
                for (Map<String,Object> personObject : objects) {
                    Person p = Person.createFromGenericMap(personObject);
                    people.add(p);
                }

                // Create adapter with model list
                final PersonAdapter adapter = new PersonAdapter(people);

                // Set adapter on main UI thread
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        setListAdapter(adapter);
                    }
                });
            }
        });
    }
}

As mentioned, whilst this is one of the simplest approaches, it does have some limitations around the handling of orientation changes or navigation away from the activity whilst loading is taking place. Implementing the view with recycling is also not covered.

For more comprehensive list view examples, it might be worth checking out http://developer.android.com/training/material/lists-cards.html and http://www.vogella.com/tutorials/AndroidListView/article.html.

Hope this has been useful.

cgwyllie
  • 413
  • 3
  • 10
  • Ok, so if I just want to pull people named Johnson. Do I just set what the user entered into the edittext and place this before the Kumulos call? HashMap params = new HashMap(); params.put("lastName", String.valueOf(personName)); – F0xcr4f7 Apr 28 '16 at 17:37
  • Yep, that could work. Then the server side API would be modified to return results matching the filter. Alternatively you could apply filtering on the client side. Depends on your number of records, if you want pagination etc. – cgwyllie Apr 29 '16 at 09:02
  • Are you not using the inflater for the view? I changed public PersonAdapter(List people) to public PersonAdapter(Context context, List people) in order to call the inflater. How else would you call the view? – F0xcr4f7 May 01 '16 at 02:05
  • Yep, passing the context to the constructor and using `LayoutInflater.from(context)` is one option, another is to use the parent view's context such as `LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);` in the `getView` method of the adapter. – cgwyllie May 02 '16 at 09:24
  • hmm getting an error from Kumulos: {"responseCode":32,"responseMessage":"Invalid request: ","payload":null,"sessionToken":"5a5c1d1a52f955c248d05f632489f2e1445d2b0f","requestedMethod":"searchPerson","requestedFormat":"json","timestamp":1462208512,"requestReceivedTime":1462208512,"maxAllowedRequestTime":40,"requestProcessingTime":0.0094358921051025} – F0xcr4f7 May 02 '16 at 17:02
  • Hi, please file a support ticket with Kumulos for further assistance on this issue, I think it's getting a bit specific for StackExchange. Thanks – cgwyllie May 03 '16 at 11:14