2015-09-11 5 views
-1

Я читал весь день тему по этому вопросу я придумал стратегию, но не могу заставить его работатьAndroid: Refresh ListView каждой минута

У меня есть ListView с получением данных в формате JSON от сервера SQL это listview уже имеет функцию обновления салфеток

Мне нужен этот список, чтобы обновляться автоматически только тогда, когда новая база была вставлена ​​в базу данных.

Я пытаюсь построить функцию внутри моего MainActivity:

int OldNumberOfRows = data from the php file 
while(true){ 
int newNumberOfRows = fetch data again using that php 
if(both arent equal) execute refresh command. 
} 

Примечание: Я не получил ни малейшего представления о том, как извлечь строки из моего AsyncTask начать манипулировать мой код с ним.

Вот это вообще, Iv'e добавил основную деятельность, "внешний класс" (FetchNumRowAsync) призванию, что PHP класс салфетки и сам PHP

MainActivity:

public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener { 

    private String TAG = MainActivity.class.getSimpleName(); 

    private String URL = "http://troyka.esy.es/troyka/orders.php"; 


    private SwipeRefreshLayout swipeRefreshLayout; 
    private ListView listView; 
    private SwipeListAdapter adapter; 
    private List<Order> orderList; 

    // initially offset will be 0, later will be updated while parsing the json 
    private int offSet = 0; 

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

     new FetchRowNumAsync(this).execute("http://troyka.esy.es/numberofrows.php"); 

     listView = (ListView) findViewById(R.id.listView); 
     //RelativeLayout.LayoutParams layout_description = new RelativeLayout.LayoutParams(50,10); 

     //Rl.setLayoutParams(layout_description); 

     swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout); 

     orderList = new ArrayList<>(); 
     adapter = new SwipeListAdapter(this, orderList); 
     listView.setAdapter(adapter); 

     swipeRefreshLayout.setOnRefreshListener(this); 

     /** 
     * Showing Swipe Refresh animation on activity create 
     * As animation won't start on onCreate, post runnable is used 
     */ 
     swipeRefreshLayout.post(new Runnable() { 
            @Override 
            public void run() { 
             swipeRefreshLayout.setRefreshing(true); 

             fetchOrders(); 
            } 
           } 
     ); 

    } 

    /** 
    * This method is called when swipe refresh is pulled down 
    */ 


    @Override 
    public void onRefresh() { 
     fetchOrders(); 
    } 

    /** 
    * Fetching movies json by making http call 
    */ 
    private void fetchOrders() { 

     // showing refresh animation before making http call 
     swipeRefreshLayout.setRefreshing(true); 

     // appending offset to url 
     String url = URL + offSet; 

     // Volley's json array request object 
     JsonArrayRequest req = new JsonArrayRequest(url, 
       new Response.Listener<JSONArray>() { 
        @Override 
        public void onResponse(JSONArray response) { 
         Log.d(TAG, response.toString()); 

         if (response.length() > 0) { 

          // looping through json and adding to order list 
          for (int i = 0; i < response.length(); i++) { 
           try { 
            JSONObject orderObj = response.getJSONObject(i); 

            int rank = orderObj.getInt("rank"); 
            String title = orderObj.getString("title"); 

            Order m = new Order(rank, title); 

            orderList.add(0, m); 

            // updating offset value to highest value 
            if (rank >= offSet) 
             offSet = rank; 

           } catch (JSONException e) { 
            Log.e(TAG, "JSON Parsing error: " + e.getMessage()); 
           } 
          } 

          adapter.notifyDataSetChanged(); 
         } 

         // stopping swipe refresh 
         swipeRefreshLayout.setRefreshing(false); 

        } 
       }, new Response.ErrorListener() { 
      @Override 
      public void onErrorResponse(VolleyError error) { 
       Log.e(TAG, "Server Error: " + error.getMessage()); 

       Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show(); 

       // stopping swipe refresh 
       swipeRefreshLayout.setRefreshing(false); 
      } 
     }); 

     // Adding request to request queue 
     MyApplication.getInstance().addToRequestQueue(req); 
    } 

} 

FetchRowNumAsync:

public class FetchRowNumAsync extends AsyncTask<String, Void, String> { 

    private Context mContext; 

    public FetchRowNumAsync(Context ctx){ 
     this.mContext = ctx; 
    } 

    protected String doInBackground(String... urls) 
    { 
     String fullString = ""; 
     try{ 
      URL url = new URL(urls[0]); 
      BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream())); 
      String line; 
      while ((line = reader.readLine()) != null) { 
       fullString += line; 
      } 
      reader.close(); 
     }catch(Exception e){ 
      e.getMessage(); 
     } 
     return fullString; 
    } 

    @Override 
    protected void onPostExecute(String value){ 
     try{ 
      ((OnValueFetchedListener) mContext).onValueFetched(value); 
     }catch(ClassCastException e){} 
    } 

    public interface OnValueFetchedListener{ 
     void onValueFetched(String columns); 
    } 

} 

SwipeListAdapter:

public class SwipeListAdapter extends BaseAdapter { 
     private Activity activity; 
     private LayoutInflater inflater; 
     private List<Order> orderList; 
     private String[] bgColors; 

     public SwipeListAdapter(Activity activity, List<Order> orderList) { 
      this.activity = activity; 
      this.orderList = orderList; 
      bgColors = activity.getApplicationContext().getResources().getStringArray(R.array.movie_serial_bg); 
     } 

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

     @Override 
     public Object getItem(int location) { 
      return orderList.get(location); 
     } 

     @Override 
     public long getItemId(int position) { 
      return position; 
     } 

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

      if (inflater == null) 
       inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      if (convertView == null) 
       convertView = inflater.inflate(R.layout.list_row, null); 

      TextView serial = (TextView) convertView.findViewById(R.id.serial); 
      TextView title = (TextView) convertView.findViewById(R.id.title); 

      serial.setText(String.valueOf(orderList.get(position).id)); 
      title.setText(orderList.get(position).title); 

      String color = bgColors[position % bgColors.length]; 
      serial.setBackgroundColor(Color.parseColor(color)); 

      return convertView; 
     } 

} 

PHP

<?php 
header("refresh: 3;"); 

$mysqli = new mysqli("irrelevant","irrelevant","irrelevant","irrelevant"); 

/* check connection */ 
if (mysqli_connect_errno()) { 
    printf("Connect failed: %s\n", mysqli_connect_error()); 
    exit(); 
} 

$query = "SELECT COUNT(*) FROM orders"; 
$result = mysqli_query($mysqli,$query); 
$rows = mysqli_fetch_row($result); 

echo ($rows[0]); 

$result->close(); 

$mysqli->close(); 
?> 
+0

вы можете иметь дату создания в вас базе данных, так что вы можете запросить только новые элементы. – njzk2

+0

У меня есть временная метка, которая запускается каждый раз, когда вставлена ​​строка, но ее вне темы mate – iguana

+0

не очень. Если вы используете это, вы получите только новые элементы, поэтому вам нужно будет вставить все, что вы получаете со своего сервера, в свой список. – njzk2

ответ

0

Попробуйте этот подход:

  • Создание конечной точки в вашем сервере, как следующее:

    //http://somesite.com/api/data/pull/check 
    
  • Затем, вы можете легко проверить эту конечную точку, которая возвращает некоторое значение, как true или false в зависимости от наличия новых данных, вставленных в db.

  • Из полученного результата вы можете решить, следует ли обновлять данные на телефоне, сделав другой запрос HTTP или нет. Вы всегда хотите избежать ненужных запросов на сервер - помните, что пользователи тратят деньги каждый раз, когда они используют свой план данных (услугу).

  • Я, как и в комментариях выше, рекомендую иметь столбец с меткой времени, которую вы можете проверить, чтобы получить только новые данные вместо всего!

Надеюсь, это даст вам простую идею о том, как подойти к этой проблеме! Удачи!

+0

Насколько я понимаю, мой общий подход был неправильным, мне хотелось бы узнать ваше мнение о том, что я до сих пор получил, php-файл, который просто выбирает все строки из таблицы, анализирует его на json и андроид listview, который ... ясно из чтения ответы здесь я понимаю, что это моя общая ошибка, вопрос заключается в том, как «получать» только новые данные по php? – iguana

+0

Возможно, просто просто предложение WHERE в вашем заявлении sql? – Eenvincible

0

Приложение для Android не будет знать, когда вы добавили/обновили данные в своей таблице на сервере до тех пор, пока вы не вызовете скрипт из приложения и не извлечете данные и не обновите их на своем устройстве.

только если ваше приложение осуществило Эти функции в

  1. толчок уведомление - вызов сценария каждый раз, когда вы получите уведомление.
  2. XMPP сервис - используется для чата приложений (которые, вероятно, не отвечать на свой вопрос прямо сейчас)

вот мое предложение для вас

Со стороны сервера:

  • создать поле метки времени в таблице на сервере. обновите его с текущим значением метки времени при каждом изменении (например, update/add) в таблице. И когда когда этот скрипт вызывается, отправьте его в json и сделайте свое приложение сохраненным в sqlite вместе с данными.

  • сервер будет сравнивать время, отправленное приложением каждый раз, с сохраненной меткой времени на сервере для новых данных.

со стороны клиента:

  • для кулачного времени метки времени от приложения будет 0. сервер будет проверять его и отправить целые данные вместе с меткой времени, сохраненным во время изменений в таблицы. сохраните данные вместе с меткой времени. второй раз, когда скрипт называется App, будет отправлен временной отметкой, которая была последней сохранена.

со всем этим ваше приложение еще не узнает, если новые данные будут добавлены до тех пор, пока вы не вызовете скрипт и не проверите. но по крайней мере он узнает, будут ли получены новые данные или нет, и обновить ли ур экран

теперь приходит сценарий, вызывающий часть с клиентской стороны, которая выполняет задачу assynch, делает это с помощью обработчика для выполнения класса assynch каждую минуту

final Handler timerHandler = new Handler(); 
    Runnable timerRunnable; 


timerRunnable = new Runnable() { 
      @Override 
      public void run() { 
       new FetchRowNumAsync(context).execute(url); 
       timerHandler.postDelayed(timerRunnable, 60000); // run every minute 
      } 
     }; 

и разрегистрировать его в OnDestroy()

@Override 
    public void onDestroyView() { 
      // TODO Auto-generated method stub 
      super.onDestroyView(); 
      timerHandler.removeCallbacks(timerRunnable); 

     }