• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Apps Spinner / ListView wont refresh after DataBase update.

ConzT

Newbie
Mar 13, 2016
25
1
Hey everyone!
Im new to Android Developement and currently working on my first app that should give me the time between first time clicking a button and second time clicking the button and save it to a currently selected customer.(I know there are already tons of those applications out there, but since im still learning and want an app that can be usefull for myself i decided to try
wink.png
)


To the problem:

When my app starts, in the main activity i call a method, that requests all my "customers" from the database and stores them in a list.
This list i use to display the customers in a ListView and a spinner.
The spinner is also created in the main activity onCreate(). So after i get the data from the database i want to fill the spinner with this data. But it doesnt work, to show the data when starting the app.

What doesnt work either:

When adding a new customer in the app, the customer is saved to the database.
then i have to open my ListView(Button: Kundenübersicht) two times till the new customers is displayed. After that, the data is also visible in the spinner.


Heres my code:

MainActivity(ZeitErfassen)

Java:
package com.example.cmsolutions.zeiterfassung;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import android.view.View;

import java.io.File;
import java.lang.reflect.Array;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;


public class ZeitErfassen extends AppCompatActivity {

    public static LinkedList<Kunde> kunden = new LinkedList<Kunde>();
    boolean running = false;
    long startTime,endTime,totalTime;

    private SharedPreferences app_preferences;
    private SharedPreferences.Editor editor;
    private TextView displayTime;
    public Button startEndButton;
    private ArrayAdapter<String> adapter;
    private Spinner spinner;
    public static Kunde selectedCustomer;
    private static int numberOfCustomers = -1;




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_zeit_erfassen);
        //Einstellungen laden
        app_preferences =  getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
        startTime= app_preferences.getLong("startTime", 0);
        endTime = app_preferences.getLong("endTime", 0);
        running = app_preferences.getBoolean("running", false);
        displayTime = (TextView)findViewById(R.id.zeit_bei_Kunde);
        displayTime.setText((CharSequence) app_preferences.getString("zeitAnzeige", "Zeit bei Kunde"));
        startEndButton = (Button)findViewById(R.id.start_Timer);
        startEndButton.setText((CharSequence) app_preferences.getString("timerButton", "Start Timer"));
        editor = app_preferences.edit();
        editor.commit();
    }


    public void onDestroy() {
        super.onDestroy();

        editor.putLong("startTime", startTime);
        editor.putString("zeitAnzeige", (String) displayTime.getText());
        editor.putString("timerButton", (String) startEndButton.getText());
        editor.putLong("endTime", endTime);
        editor.putLong("totalTime", totalTime);
        editor.putBoolean("running", app_preferences.getBoolean("running", false));
        editor.commit();
        this.finish();
    }


    public void onStart() {
        super.onStart();
        DatabaseHelper.customerFromDatabaseToList(this);
        createDropDown();
        numberOfCustomers= kunden.size();
    }
    public void onResume() {
        super.onResume();
       // DatabaseHelper.customerFromDatabaseToList(this);
       // createDropDown();
       // numberOfCustomers = kunden.size();
    }


    public void startTimer(View view) {
        editor = app_preferences.edit();

        if(running == false) {
            startTime = getTime();
            running = true;
            editor.putLong("startTime", startTime);
            startEndButton.setText("End Timer");
            displayTime.setText("Zeitstoppung läuft");
            editor.putString("zeitAnzeige", (String) displayTime.getText());
            editor.putString("timerButton", (String) startEndButton.getText());
            editor.putBoolean("running", true);
            editor.commit();

        } else {
            setSelectedCustomer();
            endTime = getTime();
            editor.putLong("endTime",endTime);
            totalTime = endTime - startTime;
            editor.putLong("totalTime", totalTime);
            displayTime.setText(formatTime(totalTime));
            editor.putString("zeitAnzeige", (String) displayTime.getText());
            startEndButton.setText("Start Timer");
            editor.putString("timerButton", (String) startEndButton.getText());
            running = false;
            editor.putBoolean("running", false);
            editor.commit();
            DatabaseHelper.timeToDatabase(String.valueOf(selectedCustomer.getId()),formatTime(totalTime),this);
        //    selectedCustomer.saveTimeToCustomer(selectedCustomer, formatTimeForCustomer(totalTime));

        }
    }

    public String formatTime(Long totalTime) {
        int hours   = (int) ((totalTime / (1000*60*60)) % 24);
        int minutes = (int) ((totalTime / (1000*60)) % 60);
        int seconds = (int) (totalTime / 1000) % 60;

        String time = (String.valueOf(hours) + ":" + String.valueOf(minutes) + ":" + String.valueOf(seconds));
        return time;
    }

    public String formatTimeForCustomer(Long totalTime) {
        StringBuilder time = new StringBuilder();
        Calendar cal = Calendar.getInstance();
        int year    = cal.get(Calendar.YEAR);
        int month   = cal.get(Calendar.MONTH);
        int day     = cal.get(Calendar.DAY_OF_MONTH);
        time.append((String.valueOf(year) + "." + String.valueOf(month) + "." + String.valueOf(day))).append(formatTime(totalTime));
        return time.toString();
    }

    public void  neuerKunde(View view) {
        Intent intent = new Intent(this, AddKunde.class);
        startActivity(intent);
    }
    public void kundenÜbersicht(View view) {
    //    setSelectedCustomer();
        Intent intent = new Intent(this, DisplayCustomer.class);
        startActivity(intent);
    }

    public long getTime() {
        long millis = System.currentTimeMillis();
        return millis;
    }

    public void setSelectedCustomer() {
        if(kunden.size() > 0) {
            if (spinner.getSelectedItem().toString() != null) {
                String tempCustomer = spinner.getSelectedItem().toString();
                for (Kunde k : kunden) {
                    if (k.getName().equals(tempCustomer)) {
                        selectedCustomer = k;
                    }
                }
            }
        }
    }


    public void createDropDown() {
            if (kunden.size() > 0) {
                spinner = (Spinner) findViewById(R.id.chooseCustomer);
                // Create an ArrayAdapter using the string array and a default spinner layout
                adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, DisplayCustomer.namesOfCustomers());

                // Specify the layout to use when the list of choices appears
                adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
                // Apply the adapter to the spinner
                spinner.setAdapter(adapter);
            }
    }
}


DatabaseHelper Class

Java:
package com.example.cmsolutions.zeiterfassung;

import android.app.AlertDialog;
import android.content.Context;
import android.widget.ArrayAdapter;
import android.widget.Toast;

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.StringRequest;
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.HashMap;
import java.util.LinkedList;
import java.util.Map;

/**
* Created by cm.solutions on 15.03.2016.
*/
public class DatabaseHelper {
    public static RequestQueue requestQueue;
    public static final String host = "http://192.168.150.238/";
    public static final String insertUrl = host+"insertCustomer.php";
    public static final String showUrl = host+"showCustomer.php";
    public static final String insertTimeUrl = host+"insertTime.php";
    public static final String showTimeUrl = host+"showTimes.php";

    public static void customerFromDatabaseToList(final Context context)  {
        //Display customer from database
        requestQueue = Volley.newRequestQueue(context);
        final ArrayList<String> customerNames = new ArrayList<>();
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, showUrl, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                try {
                    JSONArray customers = response.getJSONArray("customers");
                    if(customers.length() > 0) {
                        for (int i = 0; i < customers.length(); i++) {
                            JSONObject customer = customers.getJSONObject(i);
                            String customerName = customer.getString("cus_name");
                            String customerAddress = customer.getString("cus_address");
                            int customerID = Integer.valueOf(customer.getString("cus_id"));
                            if (customerName != null && customerAddress != null) {
                                try {
                                    Kunde k = new Kunde(customerName, customerAddress, customerID);
                                    if (!listContainsObject(k)) {
                                        ZeitErfassen.kunden.add(k);
                                    }
                                } catch (Exception e) {
                                    Toast.makeText(context, "Fehler in customerFromDatabaseToListn!Code:X1", Toast.LENGTH_SHORT).show();
                                }
                            } else {
                                Toast.makeText(context,"Fehler in customerFromDatabaseToListn!Code:X2", Toast.LENGTH_SHORT).show();
                            }
                        }
                    }
                } catch (JSONException e) {
                    Toast.makeText(context,"Fehler bei holen der Daten!Code:X3",Toast.LENGTH_SHORT).show();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(context,"Fehler beim holen der Daten!Code:X4",Toast.LENGTH_SHORT).show();
            }
        });
        requestQueue.add(jsonObjectRequest);
    }

    public static boolean listContainsObject(Kunde cust) {
        for(Kunde k : ZeitErfassen.kunden) {
            if((k.getId() >0 )&& (k.getId() == cust.getId())) {
                return true;
            }
        }
        return false;
    }

    public static void timeToDatabase(final String customer_id, final String time_value, final Context context) {
        requestQueue = Volley.newRequestQueue(context);
        StringRequest request = new StringRequest(Request.Method.POST, DatabaseHelper.insertTimeUrl, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(context,"Fehler beim holen der Daten!Code:X5",Toast.LENGTH_SHORT).show();
            }
        }) {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String,String> parameters = new HashMap<String,String>();
                parameters.put("customerid",customer_id);
                parameters.put("timevalue",time_value);
                return parameters;
            }
        };
        requestQueue.add(request);
    };

    public static ArrayList<String> timesFromDataBaseToList(final Context context,final int customer_id) {
        requestQueue = Volley.newRequestQueue(context);
        final String cus_id = String.valueOf(customer_id) ;
        final ArrayList<String> customerTimes = new ArrayList<>();

        StringRequest jsonObjectRequest = new StringRequest(Request.Method.POST, showTimeUrl, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    JSONObject object = new JSONObject(response.toString());
                    JSONArray times = object.getJSONArray("customertimes");
                    if (times.length() > 0) {
                        for (int i = 0; i < times.length(); i++) {
                            JSONObject jsonObject = times.getJSONObject(i);
                            String timeValue = jsonObject.getString("time_value");
                            if (timeValue != null) {
                                customerTimes.add(timeValue);
                            }
                        }
                    }
                } catch (JSONException e) {
                    Toast.makeText(context,"Fehler beim holen der Daten!Code:X6",Toast.LENGTH_SHORT).show();
                }
            }
        }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Toast.makeText(context,"Fehler beim Holen der Zeiten, keine Verbindung zur Datenbank!Code: X7",Toast.LENGTH_LONG).show();
                    error.printStackTrace();
                }
        }){
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String,String> parameters = new HashMap<String,String>();
                parameters.put("cus_id",cus_id);
                return parameters;
            }
        };
        requestQueue.add(jsonObjectRequest);
        return customerTimes;
    };
}

DisplayCustomer, where all my customers are displayed

Java:
package com.example.cmsolutions.zeiterfassung;

import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;


import java.util.ArrayList;

public class DisplayCustomer extends AppCompatActivity {
    CustomerAdapter customerAdapter;
    public ArrayAdapter<String> adapterCustomerView;
    private ListView listCustomerView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_display_customer);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        ArrayList<Kunde> customerList = getCustomerObjects();
        customerAdapter = new CustomerAdapter(this,customerList);
        listCustomerView = (ListView)findViewById(R.id.list_View_Customers);
        //  adapterCustomerView = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, namesOfCustomers());
        listCustomerView.setAdapter(customerAdapter);
        openCustomerDetails();
    }


    public static ArrayList<String> namesOfCustomers() {
        ArrayList<String> customerNames = new ArrayList<>();
        if(ZeitErfassen.kunden.size() > 0 ) {
            for (Kunde k : ZeitErfassen.kunden) {
                customerNames.add(k.getName());
            }
        }
        return customerNames;
    }


    public static ArrayList<Kunde> getCustomerObjects() {
        ArrayList<Kunde> customerList = new ArrayList<>();
        if(ZeitErfassen.kunden.size() > 0 ) {
            for (Kunde k : ZeitErfassen.kunden) {
                customerList.add(k);
            }
        }
        return customerList;
    }


    public void openCustomerDetails() {
        listCustomerView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Kunde kunde = new Kunde();
                kunde = (Kunde)listCustomerView.getItemAtPosition(position);
                Intent intent = new Intent(DisplayCustomer.this, DisplayDetailedCustomer.class);
                intent.putExtra("selectedCustomerObject",(Parcelable)kunde);
                startActivity(intent);
            }
        });
    }
}

AddKunde / Class for adding customer

Code:
    package com.example.cmsolutions.zeiterfassung;

    import android.content.Context;
    import android.os.Bundle;
    import android.provider.ContactsContract;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.Toolbar;
    import android.text.TextUtils;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.Toast;

    import com.android.volley.AuthFailureError;
    import com.android.volley.Request;
    import com.android.volley.RequestQueue;
    import com.android.volley.Response;
    import com.android.volley.VolleyError;
    import com.android.volley.toolbox.StringRequest;
    import com.android.volley.toolbox.Volley;

    import java.io.File;
    import java.util.HashMap;
    import java.util.Map;


    public class AddKunde extends AppCompatActivity {

    public RequestQueue requestQueue;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_kunde);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }



    public void addKunde(View view) throws Exception {
        try {
            EditText nameField = (EditText) findViewById(R.id.customerName);
            String name = nameField.getText().toString();
            EditText addressField = (EditText) findViewById(R.id.addressField);
            String address = addressField.getText().toString();
            if(TextUtils.isEmpty(name)){
                nameField.setError("Ungültiger Name!");
                return;
            } else if(TextUtils.isEmpty(address)){
                addressField.setError("Ungültige Adresse");
                return;
            } else {
                try {
                    customerToDatabase(name, address);
                    Kunde customer = new Kunde(name, address);
                } catch (VolleyError e) {
                    Toast.makeText(this,"Fehler: Keine Verbindung zur Datenbank!",Toast.LENGTH_SHORT).show();
                }
            }
        } catch (Exception e) {
            throw new Exception("Fehler in addKunde!");
        }
        finish();
    }



        public void customerToDatabase(final String name, final String address) {
            requestQueue = Volley.newRequestQueue(getApplicationContext());
            StringRequest request = new StringRequest(Request.Method.POST, DatabaseHelper.insertUrl, new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {

                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    error.printStackTrace();
                }
            }) {
                @Override
                protected Map<String, String> getParams() throws AuthFailureError {
                   Map<String,String> parameters = new HashMap<String,String>();
                    parameters.put("customername",name);
                    parameters.put("customeraddress",address);
                    return parameters;
                }
            };
            requestQueue.add(request);
        };
}


If you need more information, please let me know!
 
So when your app starts, does the spinner have any entries in it?
Might be worth verifying that when the application starts, this piece of code is not returning an empty list:

Code:
public static ArrayList<String> namesOfCustomers() {
        ArrayList<String> customerNames = new ArrayList<>();
        if(ZeitErfassen.kunden.size() > 0 ) {
            for (Kunde k : ZeitErfassen.kunden) {
                customerNames.add(k.getName());
            }
        }
        return customerNames;
    }
 
Upvote 0
Hey LV426, thanks for your response!

No the spinner doesnt have any entries.

The spinner should get its entries from the list "kunden".
The list "kunden" is filled by the method customerFromDatabaseToList(). This method, i call in the main activity onCreate() but it doesnt fill the list when first calling this method.
So the spinner wont get any data on first opening the app, because the list is empty...
 
Upvote 0
So is your problem that you expect the list to be populated when you initially call customerFromDatabaseToList()?

If so, then that question can't be answered because the code is calling a remote web service which returns the data. If it returns nothing, then the problem lies on the server side, with the code which constructs and returns the data.
 
Upvote 0
EDIT: Video Link:
Yes exactly, i expect it to be populated when creating the app but it doesnt...



So a server side problem...

This is the showCustomer.php script is use to get the information from database. It works fine when testing with Postman...

I'll install the app on my phone to see if im facing the same problems and maybe ill take a video of it so you can see better what i mean.

PHP:
<?php
    if($_SERVER["REQUEST_METHOD"]=="POST") {
    include 'connection.php';
    showCustomer();
    }


function showCustomer()
{
    global $connect;

  
  
    $query = " SELECT * FROM zeiterfassung.customer;";
  
    $result = mysqli_query($connect,$query);
    $number_of_rows = mysqli_num_rows($result);
  
    $temp_array = array();
  
    if($number_of_rows > 0) {
        while($row = mysqli_fetch_assoc($result)){
            $temp_array[] = $row;
        }
    }
  
    header('Content-Type: application/json');
    echo json_encode(array("customers"=>$temp_array));
    mysqli_close($connect);
}
  
?>

And the connection.php

Code:
<?php
    define('hostname','localhost');
    define('user','root');
    define('password','********');
    define('databaseName','zeiterfassung');
  
  
    $connect = mysqli_connect(hostname,user,password,databaseName);
?>
 
Last edited:
Upvote 0
I notice in your code that you start the Activity to handle entering a new customer. But the parent activity doesn't deal with the child activity completing.

You should be using StartActivityForResult(), and on completion, the parent activity should update the list used to populate the spinner. This is basically why you're not seeing the new customer in the spinner, you haven't updated the list used in its adapter.

See here for information on how to use StartActivityForResult(). There's tons more stuff on this

http://developer.android.com/training/basics/intents/result.html
 
Upvote 0
Hey LV426,


thanks for your reply!
I tried it with startActivityForResult() and passed the new customer to the main activity. There in the onActivityResult() method, i added the new customer to my list "kunden", because the adapter is using this list to get the customer names.

So now it shows this new customer in the spinner, !but! , it is a wrong entry, because it doesnt have an ID yet.

I get the ID from the database, and add it to the customers when calling customerFromDatabaseToList.


I know that the new customer has a wrong id because when opening the overview of my customers, i see the new customer twice.
When clicking on them, i get all the times stored in the database from that customer.
When clicking on those new customer(s) i shouldnt get any timerecords because i just created it.

But for one of them I get all the times where customer_id="" in the database. And this is the customer I just added in the onActivityResult() method because i didnt asign any id to it...
 
Upvote 0
I may be stating the blindingly obvious here, but if you're getting the ID from the database, why don't you insert the new customer record into the table, before re-populating the spinner?

So the workflow would be:-

1. User enters new customer details
2 Details are sent to remote web server
3 Web server returns data
4 Your app inserts new record into the database
5 Read all records from the database to populate the spinner
 
Upvote 0
Thanks, ill try it like you mentioned! I will let you know as soon as i got it ;-)

I ran into another problem...

I set up a public webserver with a database and install my app on the phone.

For the internet connection i use my mobile internet connection.

The app works fine. Its inserting customers into the database and also reciving the customers from the database to display them. It even works to insert times into the database.

But what doesnt work is to display the times when clicking on a specific customer in the ListView.
It just shows no data when using my mobiles internet connection.

On the other side it works when i use my wireless lan. The mobile internet connection works(browsing and other apps), I have tried that...

EDIT: It doesnt show any Error. If an exception is thrown it shows me a Toast msg
 
Upvote 0
About the workflow... I dont know the best way how to perceive it.

1. User enters customer details - I wouldnt change anything here

2. Details are sent to the webserver - Should i just let the Database know that I want to receive information about the highest customer ID(To insert data into db in step 5)?

3. Web server returns data - Webserver returns the highest customer id from the database

4. App inserts new record into database - Now insert the new user into the database with customer id+1, which the database returned.

5. Read all records from database to populate Spinner - Should i make the adapter a custom adapter like I used for my ListView to populate the customers? I actually just need to know the names but if i create one adapter, i can use it for both, the ListView for customers and for the spinner, right?
To create the adapter I would use a list of object "Kunde". Do you think that this is a good idea? Should i all store them in an ArrayList?

For the performance, when adding a customer to the database, should i automaticly also add the user to my List?


Thanks LV for taking your time to help us out here!

EDIT: Should i continue working with Volley? Or is there a better alternative?
 
Last edited:
Upvote 0
About the workflow... I dont know the best way how to perceive it.

1. User enters customer details - I wouldnt change anything here

Correct, that stuff is fine

2. Details are sent to the webserver - Should i just let the Database know that I want to receive information about the highest customer ID(To insert data into db in step 5)?

3. Web server returns data - Webserver returns the highest customer id from the database

4. App inserts new record into database - Now insert the new user into the database with customer id+1, which the database returned.

You could do that. Your app aldready has the customer name, so all you need to know is the ID of the record inserted in the server's database.

5. Read all records from database to populate Spinner - Should i make the adapter a custom adapter like I used for my ListView to populate the customers? I actually just need to know the names but if i create one adapter, i can use it for both, the ListView for customers and for the spinner, right?
To create the adapter I would use a list of object "Kunde". Do you think that this is a good idea? Should i all store them in an ArrayList?

For the performance, when adding a customer to the database, should i automaticly also add the user to my List?

Thanks LV for taking your time to help us out here!

You can't use the same adapter for both Spinner and ListView because they use different layouts. But you can use the same ArrayList for both adapters.
 
  • Like
Reactions: ConzT
Upvote 0
Man it works!! The spinner updates right after inserting a new customer :) Now i just need to figure out how to update it right on start of the app.
edit: that youll have something to laugh about.. yesterday i tried to update it, with a while loop, that it should try fill my list kunden as long as its length is equal to 0 ;D Didnt work though ;-)

To the question with the app not working correctly on my mobile phone.. Do you have any idea where that comes from?
It's a S5 mini, when debugging the app in the emulator im using a Nexus 5, Api 23...

Edit: Thanks again! ;-)


Edit: It didnt work as i wanted to... im on it again
 
Last edited:
Upvote 0
On my phone, when using mobile internet, everything works fine but displaying the times from the database. I display them by clicking on a customer in my ListView, but it shows no data.

On the other hand when using wireless lan it works and shows me the times...


To populating the spinner.. I stilled tried to populate it with my method, customerFromDatabaseToList and i call this method after inserting the new user into the database. While debuggin i saw that the response on this request is an empty array:
"jsonObjectRequest: "[] http://10.0.0.7/showCustomer.php 0x1e7daaac NORMAL 1"

I just dont get why the array it returns me is once empty and then at another point of time filled with the database information. Just doesnt get into my head^^


EDIT: I just found out that the [ ] doesnt mean that the array is empty... It shows the same on a succesfull(full arry) response.

But what really drives me crazy is finding the data in the variables while debugging.
A "hint" i found, and a personall success ;-), is that under requestQueue -> mWaitingRequests -> 0 -> key -> count = 34

count = 34 must be the number of customers i should get returned...
EDIT: It is not, there are just 24 values in my database.

But, i searched really deep through all those variables, i didnt find any variables where it shows me the data that im getting from the database....

I also tried to google it but i didnt get any info on that...



EDIT2:

In the onCreate method I fetch all my data from the database, now finally after days of debugging it I had the great Idea to log the response from the jsonobjcrequest: Whats interesting, is that the response is delivering the data, at least this it what logd says...... and i call it right before adding my customers to the list... Maybe this will help us?

If i debug the method, it never jumps into the onreponse body... i always stepped into and it didnt show the LOG on the Android Monitor..?

Method body of onResponse:

Java:
 public void onResponse(JSONObject response) {
                try {
                    String LOG ="DEBUG RESPONSE";
                    Log.d(LOG, "onResponse: "+ response.toString());
                    JSONArray customers = response.getJSONArray("customers");
                    ZeitErfassen.kunden.removeAll(ZeitErfassen.kunden);
                    if(customers.length() > 0) {
                        for (int i = 0; i < customers.length(); i++) {
                            JSONObject customer = customers.getJSONObject(i);
                            String customerName = customer.getString("cus_name");
                            String customerAddress = customer.getString("cus_address");
                            int customerID = Integer.valueOf(customer.getString("cus_id"));
                            if (customerName != null && customerAddress != null) {
                                try {
                                    Kunde k = new Kunde(customerName, customerAddress, customerID);
                                    ZeitErfassen.kunden.add(k);

                                } catch (Exception e) { public void onResponse(JSONObject response) {
                try {
                    String LOG ="DEBUG RESPONSE";
                    Log.d(LOG, "onResponse: "+ response.toString());
                    JSONArray customers = response.getJSONArray("customers");
                    ZeitErfassen.kunden.removeAll(ZeitErfassen.kunden);
                    if(customers.length() > 0) {
                        for (int i = 0; i < customers.length(); i++) {
                            JSONObject customer = customers.getJSONObject(i);
                            String customerName = customer.getString("cus_name");
                            String customerAddress = customer.getString("cus_address");
                            int customerID = Integer.valueOf(customer.getString("cus_id"));
                            if (customerName != null && customerAddress != null) {
                                try {
                                    Kunde k = new Kunde(customerName, customerAddress, customerID);
                                    ZeitErfassen.kunden.add(k);

                                } catch (Exception e) {


LOG
Java:
03-24 23:00:18.408 7644-7644/? I/art: Not late-enabling -Xcheck:jni (already on)
03-24 23:00:18.549 7644-7644/com.example.cmsolutions.zeiterfassung W/System: ClassLoader referenced unknown path: /data/app/com.example.cmsolutions.zeiterfassung-2/lib/x86
03-24 23:00:18.823 7644-7682/com.example.cmsolutions.zeiterfassung D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
03-24 23:00:18.832 7644-7644/com.example.cmsolutions.zeiterfassung D/DEBUG RESPONSE: onResponse: {"customers":[{"cus_id":"70","cus_name":"Kundenname","cus_address":"Adresse"},{"cus_id":"71","cus_name":"test","cus_address":"Adresse"},{"cus_id":"72","cus_name":"name","cus_address":"Adresse"},{"cus_id":"73","cus_name":"test2","cus_address":"Adresse"},{"cus_id":"74","cus_name":"Knname","cus_address":"Adresse"},{"cus_id":"75","cus_name":"e","cus_address":"Adresse"},{"cus_id":"76","cus_name":"test","cus_address":"Adresse"},{"cus_id":"77","cus_name":"testme","cus_address":"Adresse"},{"cus_id":"78","cus_name":"Kundenname","cus_address":"Adresse"},{"cus_id":"79","cus_name":"Kundenname","cus_address":"Adresse"},{"cus_id":"80","cus_name":"e","cus_address":"Adresse"},{"cus_id":"81","cus_name":"enname","cus_address":"Adresse"},{"cus_id":"82","cus_name":"Kundenname","cus_address":"Adresse"},{"cus_id":"83","cus_name":"Kundenn","cus_address":"Adresse"},{"cus_id":"84","cus_name":"\"Test\"","cus_address":"\"test"},{"cus_id":"85","cus_name":"Kundenname","cus_address":"Adresse"},{"cus_id":"86","cus_name":"Kundenname","cus_address":"Adresse"},{"cus_id":"87","cus_name":"e","cus_address":"Adresse"},{"cus_id":"88","cus_name":"Kundenname","cus_address":"Adresse"},{"cus_id":"89","cus_name":"me","cus_address":"Adresse"},{"cus_id":"90","cus_name":"Kukkjjjjjjjje","cus_address":"Adresse"},{"cus_id":"91","cus_name":"Kujjmnnname","cus_address":"Adresse"},{"cus_id":"92","cus_name":"ame","cus_address":"Adresse"},{"cus_id":"93","cus_name":"Kundenname","cus_address":"Adresse"}]}
03-24 23:00:18.893 7644-7682/com.example.cmsolutions.zeiterfassung I/OpenGLRenderer: Initialized EGL, version 1.4
03-24 23:00:18.968 7644-7682/com.example.cmsolutions.zeiterfassung W/EGL_emulation: eglSurfaceAttrib not implemented
03-24 23:00:18.968 7644-7682/com.example.cmsolutions.zeiterfassung W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xabe7e0e0, error=EGL_SUCCESS
03-24 23:00:19.665 7644-7644/com.example.cmsolutions.zeiterfassung I/Choreographer: Skipped 33 frames!  The application may be doing too much work on its main thread.
 
Last edited:
Upvote 0
I set another Log in the for loop in the on response.
It even prints i so 1,2,3,4,5,6,7... .
So there must be a problem in the add or Constructor method...

I set a Breakpoint at the Zeiterfassen.kunden.add() method, and when its working on that method, the activity is allready visible! How can i tell the activity to wait till the method is completed?
 
Last edited:
Upvote 0
Adding a callback worked here!

Java:
public class DatabaseHelper {
    public static void customerFromDatabaseToList(final Context context) {
        customerFromDatabaseToList(context, null);
    }

    public static void customerFromDatabaseToList(final Context context, final Runnable onSuccess)  {
        //Display customer from database
        requestQueue = Volley.newRequestQueue(context);
        final ArrayList<String> customerNames = new ArrayList<>();
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, showUrl, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                try {
                    JSONArray customers = response.getJSONArray("customers");
                    if(customers.length() > 0) {
                        for (int i = 0; i < customers.length(); i++) {
                            JSONObject customer = customers.getJSONObject(i);
                            String customerName = customer.getString("cus_name");
                            String customerAddress = customer.getString("cus_address");
                            int customerID = Integer.valueOf(customer.getString("cus_id"));
                            if (customerName != null && customerAddress != null) {
                                try {
                                    Kunde k = new Kunde(customerName, customerAddress, customerID);
                                    if (!listContainsObject(k)) {
                                        ZeitErfassen.kunden.add(k);
                                    }
                                } catch (Exception e) {
                                    showAlert("Fehler in customerFromDatabaseToListn!", "Fehler", context);
                                }
                            } else {
                                showAlert("Fehler in customerFromDatabaseToListn!", "Fehler", context);
                            }
                        }
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                if (onSuccess != null)
                    onSuccess.run();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
            }
        });
        requestQueue.add(jsonObjectRequest);
    }
}

public class ZeitErfassen extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_zeit_erfassen);
        //Einstellungen laden
        app_preferences =  getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
        startTime= app_preferences.getLong("startTime", 0);
        endTime = app_preferences.getLong("endTime", 0);
        running = app_preferences.getBoolean("running", false);
        displayTime = (TextView)findViewById(R.id.zeit_bei_Kunde);
        displayTime.setText((CharSequence) app_preferences.getString("zeitAnzeige", "Zeit bei Kunde"));
        startEndButton = (Button)findViewById(R.id.start_Timer);
        startEndButton.setText((CharSequence) app_preferences.getString("timerButton", "Start Timer"));
        DatabaseHelper.customerFromDatabaseToList(this, new Runnable() {
            @Override
            public void run() {
                createDropDown();
            }
        });
        // the list can still be populated here as well if desiered
        createDropDown();
        editor = app_preferences.edit();
        editor.commit();
    }
}
 
Upvote 0

BEST TECH IN 2023

We've been tracking upcoming products and ranking the best tech since 2007. Thanks for trusting our opinion: we get rewarded through affiliate links that earn us a commission and we invite you to learn more about us.

Smartphones