Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: Pavel2 20. 03. 2015, 12:17:32
-
Zdravim,
zkousim svoji prvni aplikaci zalozenou na GPS. Podle meho umisteni by mi mela vratit polohu bodu v okoli v blizkosti treba 1 Km. Data vsech bodu jsou ulozena v DB. Android by mel skriptu na serveru rict moje poloha je Lat/Long a vrat mi vsechno co je v dosahu <= 900M. Data z DB podle zadaneho kriteria vytahne php a android vysledky zobrazi pomoci seznamu. Je tohle vhodna metoda implementace?
-
To záleží jestli co je to za data a jestli to má fungovat offline, jak často se databáze bodů mění, jak je velká (kolik bodů) atd. Alternativně cachovat databázi bodů v telefonu (aplikaci) a body vybírat (a předpokládám také nějak řadit) podle vzdálenosti přímo v aplikaci.
Neboli si podrobně promyslet co si od té aplikace z pohledu uživatele slibujete, a pak teprve řešit jak to technicky udělat.
-
ano.
data z aplikacie musia chodit do zoznamu asynchronne lebo vam chcipne UI thread. pozrite sa na loadery alebo asynctasky
-
Lokace se meni nasledovne. Aplikace se spusti nebo se obnovi z pozadi a provede GPS update + data refresh. Kazda polozka vyobrazena ze seznamu obsahuje vlastni ikonu. Pokud chce uzivatel aktualizovat lokaci sam musi kliknout na tlacitko "aktualizace lokace".
-
Zni to dobre, delal jsem neco podobnyho.
Dva drobny poznatky, co se Ti muzou hodit:
- https://developers.google.com/maps/documentation/distancematrix/ - super vec, pokud Te zajima realna vzdalenost tech vysledku
- ohledne funkce "v okruhu" a pokud budes mit hodne bodu/hodne dotazu se vyplati zamyslet nad vhodnou DB se spatial funkcemi a indexy. Na "obycejne" relacni DB pro to nejde pouzit index (funkce 4 promennych), da se to resit treba tak, ze neuvazujes okruh, ale ctvercovou oblast, tam se da pak pouzit klasicke porovnavani a indexy.
-
Pokud potrebuju reprezentovat data tahana z DB v listview je "best practice" pouzit json?
-
Pro zobrazování dat v listview můžeš použít cokoliv, protože ten json, xml či co budeš muset nasekat na objekty.
-
Snazil sem se vytvori tridu, ktera mi dostane ze serveru co potrebuji. Ovsem nekde delam porad chybu a dostavam NullPointException.
package com.example.jacob.myapplication02;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.widget.TextView;
import android.widget.Toast;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Text;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class phprequestdata extends AsyncTask<String,String,String>{
StringBuilder builder = new StringBuilder();
HttpClient client = new DefaultHttpClient();
@Override
public String doInBackground(String... params) {
justdoit();
return null;
}
public String justdoit (){
HttpGet httpGet = new HttpGet("https://server/test.php");
HttpResponse response = null;
try {
response = client.execute(httpGet);
} catch (IOException e) {
e.printStackTrace();
}
HttpEntity entity = response.getEntity();
InputStream content = null;
try {
content = entity.getContent();
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String line;
try {
while ((line = reader.readLine()) != null) {
builder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
return builder.toString();
}
public String showdata(){
return null;
}
}
Tridu se pak snazim volat nasledovne
String results;
phprequestdata test= null;
results=test.justdoit();
-
To volani sem opravil na:
String result;
phprequestdata test= new phprequestdata();
result=test.justdoit();
a ted dostavam chybu
android.os.NetworkOnMainThreadException
-
Je tohle reseni vhodne?
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
-
threadpolicy sa nedotykajte ked neviete co robite. vlastne cele je to o tom ze prasit thready je ako strihat si vlasy cirkularom
asynctask pouzivate zle. volate na tom tu vasu metodu ktora sa spusti v ui threade co vam android nedovoli. prakticky ste nepouzili nic z asynctasku
riesenie je volat execute(). ta spawne novy thread ktory spusti na pozadi doinbackground()
v metode onPostExecute() v asynctasku aktualizujte ui s vysledkami co vam dojdu
public void onButtonClick(View v) {
PhpRequestData request = new PhpRequestData();
request.execute();
}
pozrite example http://developer.android.com/reference/android/os/AsyncTask.html
dalsia vec namiesto parsovania stringu z odpovede cez bufferedreadery skuste EntityUtils.toString() usetrite si tony kodu
-
Ne, není vhodné.
Pro každý jen trochu náročnější task (třeba práce s networkem) používej AsyncTask.
https://stackoverflow.com/questions/6343166/android-os-networkonmainthreadexception
-
threadpolicy sa nedotykajte ked neviete co robite. vlastne cele je to o tom ze prasit thready je ako strihat si vlasy cirkularom
asynctask pouzivate zle. volate na tom tu vasu metodu ktora sa spusti v ui threade co vam android nedovoli. prakticky ste nepouzili nic z asynctasku
riesenie je volat execute(). ta spawne novy thread ktory spusti na pozadi doinbackground()
v metode onPostExecute() v asynctasku aktualizujte ui s vysledkami co vam dojdu
public void onButtonClick(View v) {
PhpRequestData request = new PhpRequestData();
request.execute();
}
pozrite example http://developer.android.com/reference/android/os/AsyncTask.html
dalsia vec namiesto parsovania stringu z odpovede cez bufferedreadery skuste EntityUtils.toString() usetrite si tony kodu
Dekuji...
Tridu jsem trosku zmenil
public class phprequestdata extends AsyncTask<String,String,String>{
StringBuilder builder = new StringBuilder();
HttpClient client = new DefaultHttpClient();
String results="Empty";
@Override
public String doInBackground(String... params) {
justdoit();
return null;
}
public String justdoit (){
HttpGet httpGet = new HttpGet("https://server.com/test.php");
HttpResponse response = null;
try {
response = client.execute(httpGet);
} catch (IOException e) {
e.printStackTrace();
}
HttpEntity entity = response.getEntity();
InputStream content = null;
try {
content = entity.getContent();
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String line;
try {
while ((line = reader.readLine()) != null) {
builder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
setData(builder.toString());
return null;
}
public void setData(String a){
results = a;
}
public String showdata(){
return results;
}
}
Volani ted provadim nasledovne:
phprequestdata test = new phprequestdata();
test.execute();
V tomhle okamziku vidim, ze aplikace hrabla na server. Pokud ale volam
String results;
results = test.showdata();
Dostavam, ze results uvnitr tridy jsou stale Empty, tedy vychozi hodnota a nemuzu prijit na to proc se do ni neulozi data ze serveru.
-
ste si isty ze ste si precitali dokumentaciu? ak nie tak bez citania to bude trvat cele tyzdne kym urobite nieco co funguje
pisem este raz:
veci na pozadi idu v doinbacgrkound(), veci po dobehnuti v onpostexecute() v ui threade kde sa maju aktualizovat komponenty.
na odovzdavanie dat medzi cinnostou na pozadi a cinnostou po dobehnuti ktora sa spusti v ui threade je ten navratovy typ v doinbackground. data ktore vratite v doinbacgrkound sa zjavia ako parameter v onpostexecute
to ze si odovzdavate data cez stringbuilder je preto a) zbytocnost b) patlanie. /napriklad stringbuilder nie je threadsafe tak sa tam mozu diat divne veci. zhodou okolnosti asi nebudu/
kod ani nefixujem tu je spravna verzia
public class PhpRequestData extends AsyncTask<String,String,String> {
private HttpClient client = new DefaultHttpClient();
private TextView textView;
public PhpRequestData(TextView textView) {
this.textView = textView;
}
@Override
public String doInBackground(String... params) {
return doRequest();
}
@Override
protected void onPostExecute(String data) {
textView.setText(data);
}
public String doRequest() {
try {
HttpGet httpGet = new HttpGet("https://technet.kosinka.com/test.php");
HttpResponse response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
return EntityUtils.toString(entity);
} catch (IOException e) {
Log.e("PhpRequestData", "HTTP request failed");
return "No data";
}
}
}
-
Můj tip je, že se ti při volání String results = data.showdata() vytvoří nová instance třídy PhpRequestData, která vrací results jako "Empty". Přidal sis Internet Permission do manifestu? Co ukazuje log? Použij metodu onPostExecute(), je to popsaný v odkazu na stackoverflow, co jsem postoval dole.
-
permissiony su dalsia vec co treba dodat :-)
hlavne volat metody pre ziskanie resultov: lebo v ui vlakne sa uz ide vytiahnut hodnota ktora tam este nie je (je null alebo nic) pretoze thread na pozadi este nedobehol
-
Vida, perceptron je vždycky o něco rychlejší :)
Dej si záležet na namingu, číst tvůj kód je docela pain. Určitě začni s camelCase u metod, gettery/settery a názvy tříd začínají velkým.
-
Za kod se omlouvam. Je to jenom pro test.