В приведенном ниже коде есть одно действие, которое извлекает данные из базы данных mysql (6 строк) через php в приложение Android и прямо в ListView.
Извлечение данных работает нормально, мне просто нужно, чтобы ListView автоматически обновлял его, а также предупреждал пользователя о том, что новые данные были получены звуком и вибрацией.
Будем благодарны за решение, спасибо заранее.
PS: Я знаю, что использую устаревшие методы из API 22 и т. Д.
<?php define('HOST','my_hostname..'); define('USERNAME','mysql username'); define('PASSWORD','mysql password'); define('DB','mysql db name'); $con = mysqli_connect(HOST,USERNAME,PASSWORD,DB) or die('Unable to connect'); $sql = "select * from orders"; $res = mysqli_query($con,$sql); $result = array(); while($row = mysqli_fetch_array($res)){ array_push($result, array('user'=>$row[0],'city'=>$row[1],'street'=>$row[2], 'streetnumber'=>$row[3],'phone'=>$row[4],'name'=>$row[5])); } echo json_encode(array("result"=>$result)); mysqli_close($con); ?>
И активность Android Studio
import android.os.AsyncTask; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.view.MenuItem; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.SimpleAdapter; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.BasicHttpParams; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.HashMap; public class ViewOrdersActivity extends ActionBarActivity { String myJSON; private static final String TAG_RESULTS="result"; private static final String TAG_USER = "user"; private static final String TAG_CITY = "city"; private static final String TAG_STREET ="street"; private static final String TAG_STREETNUMBER ="streetnumber"; private static final String TAG_PHONE ="phone"; private static final String TAG_NAME ="name"; JSONArray ORDERS = null; ArrayList<HashMap<String, String>> ordersList; ListView list; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_view_orders); list = (ListView) findViewById(R.id.listView); ordersList = new ArrayList<HashMap<String,String>>(); getData(); } protected void showList(){ try { JSONObject jsonObj = new JSONObject(myJSON); ORDERS = jsonObj.getJSONArray(TAG_RESULTS); for(int i=0;i<ORDERS.length();i++){ JSONObject c = ORDERS.getJSONObject(i); String user = c.getString(TAG_USER); String city = c.getString(TAG_CITY); String street = c.getString(TAG_STREET); String streetnumber = c.getString(TAG_STREETNUMBER); String phone = c.getString(TAG_PHONE); String name = c.getString(TAG_NAME); HashMap<String,String> orders = new HashMap<String,String>(); orders.put(TAG_USER, user); orders.put(TAG_CITY, city); orders.put(TAG_STREET, street); orders.put(TAG_STREETNUMBER, streetnumber); orders.put(TAG_PHONE, phone); orders.put(TAG_NAME, name); ordersList.add(orders); } ListAdapter adapter = new SimpleAdapter( ViewOrdersActivity.this, ordersList, R.layout.list_item, new String[]{TAG_USER, TAG_CITY, TAG_STREET, TAG_STREETNUMBER, TAG_PHONE, TAG_NAME}, new int[]{R.id.user, R.id.city, R.id.street,R.id.streetnumber, R.id.phone , R.id.name} ); list.setAdapter(adapter); list.invalidateViews(); } catch (JSONException e) { e.printStackTrace(); } } public void getData(){ class GetDataJSON extends AsyncTask<String, Void, String>{ @Override protected String doInBackground(String... params) { DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams()); HttpPost httppost = new HttpPost("http://myweb/folder/myphpfile.php"); httppost.setHeader("Content-type", "application/json"); InputStream inputStream = null; String result = null; try { HttpResponse response = httpclient.execute(httppost); HttpEntity entity = response.getEntity(); inputStream = entity.getContent(); // json is UTF-8 by default BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } result = sb.toString(); } catch (Exception e) { // Oops } finally { try{if(inputStream != null)inputStream.close();}catch(Exception squish){} } return result; } @Override protected void onPostExecute(String result){ myJSON=result; showList(); } } GetDataJSON g = new GetDataJSON(); g.execute(); } @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); } }
Этот вопрос может быть сделан двумя способами: по типу TimerTask, а другой – по классу Handler. Я предпочитаю Handler one, поэтому я размещаю как делать с помощью Handler
http://developer.android.com/reference/java/util/TimerTask.html
final Handler handler = new Handler() handler.postDelayed( new Runnable() { @Override public void run() { YOUR_ADAPTER_GOES_HERE.notifyDataSetChanged(); //dont forget to call getData(); handler.postDelayed( this, 60 * 10000 ); //ensure to run after 10 minutes } }, 60 * 10000 );
Вы должны обновлять только пользовательский интерфейс в основном потоке (UI).
Создав обработчик в основном потоке, вы убедитесь, что все, что вы отправляете в обработчик, также запускается в основном потоке.
public void refreshlistview(){ CountDownTimer mCountDownTimer = new CountDownTimer(60000, 1000) { public void onTick(long millisUntilFinished) { } public void onFinish() { //do refresh here //then call it again - Recursive refreshlistview(); } } ; }
вы можете использовать таймер и обновлять каждые 1 минуту = 60000 миллисекунд
для сравнения данных, я вижу, что вы используете хэш-карту в своем showlist (), поэтому сделайте так, чтобы она возвращала хэш-карту, и вы можете вызывать ее всякий раз, когда вам нужно извлекать новые данные и передавать старый и новый метод, если он возвращает true, тогда данные равны другим, вы можете сообщить пользователю, что данные были изменены, и снова установить адаптер списка
public HashMap<String,String> compare(Map<String, String> old,Map<String,String> new) { for (String i : old.keySet()) { if (old.get(i) != new.get(i)) { return false; } } return true; }