我编写了下面的代码,根据最终用户输入的地址执行纬度和经度搜索。
班级CadastroClientes.java
。它负责寻找用户的地址(HttpRequestTask
方法)并将此结果设置为char_Logradouro
字段(textvfield)。
在上述字段中设置值后,调用BuscaGeolocalizacao
类,并将getAddressFromLocation
方法作为参数传递,即您输入的地址。到目前为止一切正常。
问题在BuscaGeolocalizacao
课程中开始时,我尝试在字段上设置latitude
和longitude
的结果值:
cc.char_Lat.setText(sb.append(address.getLatitude()));
cc.char_Long.setText(sb.append(address.getLongitude()));
CadastroClientes.java (第一个代码叫做)
package com.clubee.doggywalker;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.os.Handler;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
import java.util.List;
public class CadastroClientes extends Activity {
//JSON node
private static final String TAG_SUCCESS = "success";
//url para cadastrar novo usuário
private static String url_cadastraCliente = "http://clubee.com.br/dev/dbDoggyWalker/DoggyWalker_CadastroCliente_Inserir.php";
JSONParser jsonParser = new JSONParser();
EditText char_Nome;
EditText char_CEP;
EditText char_Email;
EditText char_Cidade;
EditText char_Estado;
EditText char_Logradouro;
EditText char_Endereco;
EditText char_Bairro;
TextView char_Lat;
TextView char_Long;
//barra de progressão
private ProgressDialog pDialog;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cadastro_dw);
char_Nome = (EditText) findViewById(R.id.inputNome);
char_Email = (EditText) findViewById(R.id.inputEmail);
char_Logradouro = (EditText) findViewById(R.id.inputLogradouro);
char_Cidade = (EditText) findViewById(R.id.inputCidade);
char_Estado = (EditText) findViewById(R.id.inputEstado);
char_Bairro = (EditText) findViewById(R.id.inputBairro);
char_CEP = (EditText) findViewById(R.id.inputCEP);
char_Lat = (TextView) findViewById(R.id.inputLatitude);
char_Long = (TextView) findViewById(R.id.inputLongitude);
//Criar botão
Button btnCadastraCliente = (Button) findViewById(R.id.btnCadastraCliente);
Button btnBuscaCEP = (Button) findViewById(R.id.btnBuscaEndereco);
//Criar evento do botão
btnCadastraCliente.setOnClickListener(new View.OnClickListener() {@Override
public void onClick(View view) {
//abre thread em background
new CadastraCliente().execute();
}
});
//Criar evento do botão
btnBuscaCEP.setOnClickListener(new View.OnClickListener() {@Override
public void onClick(View view) {
//abre thread em background
new HttpRequestTask().execute();
}
});
}
private class HttpRequestTask extends AsyncTask < Void, Void, DAOPostmon > {
String charCepTrim = char_CEP.getText().toString().trim();
final String url = "http://api.postmon.com.br/v1/cep/" + charCepTrim;
RestTemplate restTemplate = new RestTemplate();
@Override
protected DAOPostmon doInBackground(Void...params) {
try {
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
DAOPostmon DAOPostmon = restTemplate.getForObject(url, DAOPostmon.class);
return DAOPostmon;
} catch (Exception e) {
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
DAOPostmon DAOPostmon = restTemplate.getForObject(url, DAOPostmon.class);
return DAOPostmon;
}
}
@Override
protected void onPostExecute(DAOPostmon DAOPostmon) {
//quando a tag Logradouro estiver disponiivel no retorno da api rest
if (DAOPostmon.getLogradouro() == null) {
TextView greetingLogradouro = (TextView) findViewById(R.id.inputLogradouro);
TextView greetingBairro = (TextView) findViewById(R.id.inputBairro);
TextView greetingCidade = (TextView) findViewById(R.id.inputCidade);
TextView greetingEstado = (TextView) findViewById(R.id.inputEstado);
TextView greetingCEP = (TextView) findViewById(R.id.inputCEP);
greetingLogradouro.setText(DAOPostmon.getEndereco().toUpperCase());
greetingCidade.setText(DAOPostmon.getCidade().toUpperCase());
greetingBairro.setText(DAOPostmon.getBairro().toUpperCase());
greetingEstado.setText(DAOPostmon.getEstado().toUpperCase());
greetingCEP.setText(DAOPostmon.getCep());
} else {
//senão, quando não tiver a tag logradouro, usar endereco
TextView greetingLogradouro = (TextView) findViewById(R.id.inputLogradouro);
TextView greetingBairro = (TextView) findViewById(R.id.inputBairro);
TextView greetingCidade = (TextView) findViewById(R.id.inputCidade);
TextView greetingEstado = (TextView) findViewById(R.id.inputEstado);
TextView greetingCEP = (TextView) findViewById(R.id.inputCEP);
greetingLogradouro.setText(DAOPostmon.getLogradouro().toUpperCase());
greetingCidade.setText(DAOPostmon.getCidade().toUpperCase());
greetingBairro.setText(DAOPostmon.getBairro().toUpperCase());
greetingEstado.setText(DAOPostmon.getEstado().toUpperCase());
greetingCEP.setText(DAOPostmon.getCep());
}
String address = char_Logradouro.getText().toString();
BuscaGeolocalizacao locationAddress = new BuscaGeolocalizacao();
locationAddress.getAddressFromLocation(address,
getApplicationContext(), new GeocoderHandler());
}
}
private class GeocoderHandler extends Handler {
public void handlerMsg(Message message) {
String locationAddress;
switch (message.what) {
case 1:
Bundle bundle = message.getData();
locationAddress = bundle.getString("char_Logradouro");
char_Lat.setText(locationAddress);
break;
default:
locationAddress = null;
}
}
}
class CadastraCliente extends AsyncTask < String, String, String > {
/**
* Before starting background thread Show Progress Dialog
*/@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(CadastroClientes.this);
pDialog.setMessage("Cadastrando usuário..");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
/**
* Creating product
*/
protected String doInBackground(String...args) {
String Nome = char_Nome.getText().toString();
String Email = char_Email.getText().toString();
String Endereco = char_Endereco.getText().toString();
String TipoLicenca = "DogWalker";
// Building Parameters
List < NameValuePair > params = new ArrayList < NameValuePair > ();
params.add(new BasicNameValuePair("char_Nome", Nome));
params.add(new BasicNameValuePair("char_Email", Email));
params.add(new BasicNameValuePair("char_Endereco", Endereco));
params.add(new BasicNameValuePair("char_TipoLicenca", TipoLicenca));
// getting JSON Object
// Note that create product url accepts POST method
JSONObject json = jsonParser.makeHttpRequest(url_cadastraCliente,
"POST", params);
// check log cat fro response
Log.d("Create Response", json.toString());
// check for success tag
try {
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// successfully created product
Intent i = new Intent(getApplicationContext(), CadastroClientes.class);
startActivity(i);
// closing this screen
finish();
} else {
// failed to create product
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* *
*/
protected void onPostExecute(String file_url) {
// dismiss the dialog once done
pDialog.dismiss();
}
}
}
BuscaGeolocalizacao.java (负责返回lat / long的类)
package com.clubee.doggywalker;
import android.location.Geocoder;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
public class BuscaGeolocalizacao {
private static final String TAG = "GeocodingLocation";
public static void getAddressFromLocation(final String locationAddress,
final Context context, final Handler handler) {
Thread thread = new Thread() {
@Override
public void run() {
Geocoder geocoder = new Geocoder(context, Locale.getDefault());
String result = null;
try {
List<Address> addressList = geocoder.getFromLocationName(locationAddress, 1);
if (addressList != null && addressList.size() > 0) {
CadastroClientes cc = new CadastroClientes();
Address address = addressList.get(0);
StringBuilder sb = new StringBuilder();
sb.append(address.getLatitude()).append("\n");
sb.append(address.getLongitude()).append("\n");
result = sb.toString();
cc.char_Lat.setText(sb.append(address.getLatitude()));
cc.char_Long.setText(sb.append(address.getLongitude()));
}
} catch (IOException e) {
Log.e(TAG, "Unable to connect to Geocoder", e);
} finally {
Message message = Message.obtain();
message.setTarget(handler);
if (result != null) {
message.what = 1;
Bundle bundle = new Bundle();
result = "Address: " + locationAddress +
"\n\nLatitude and Longitude :\n" + result;
bundle.putString("address", result);
message.setData(bundle);
} else {
message.what = 1;
Bundle bundle = new Bundle();
result = "Address: " + locationAddress +
"\n Unable to get Latitude and Longitude for this address location.";
bundle.putString("address", result);
message.setData(bundle);
}
message.sendToTarget();
}
}
};
thread.start();
}
}
尝试为活动实施发送latitude
和longitude
后,系统开始爆炸并显示以下消息
07-01 00:44:18.412 8978-9170 / com.clubee.doggywalker E / AndroidRuntime:FATAL EXCEPTION:Thread-23081 处理:com.clubee.doggywalker,PID:8978 java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序 在android.os.Handler。(Handler.java:200) 在android.os.Handler。(Handler.java:114) 在android.app.Activity。(Activity.java:793) 在com.clubee.doggywalker.CadastroClientes。(CadastroClientes.java:27) 在com.clubee.doggywalker.BuscaGeolocalizacao $ 1.run(BuscaGeolocalizacao.java:33)
答案 0 :(得分:1)
您也可以在UI线程上发布
cc.char_Lat.post(new Runnable() {
@Override
public void run() {
cc.char_Lat.setText("what ever value");
}
});
但顺便说一句,我认为你应该使用你的处理程序而不是使用对CadastroClientes的引用
答案 1 :(得分:0)
在 UI线程中执行您的UI操作。像这样......
runOnUiThread(new Runnable() {
@Override
public void run() {
cc.char_Lat.setText(sb.append(address.getLatitude()));
cc.char_Long.setText(sb.append(address.getLongitude()));
}
});
答案 2 :(得分:0)
Android基本上适用于两种线程类型,即UI线程和后台线程。根据android文档 -
不要从UI线程外部访问Android UI工具包来解决这个问题,Android提供了几种从其他线程访问UI线程的方法。以下是可以提供帮助的方法列表:
Activity.runOnUiThread(Runnable)
View.post(Runnable)
View.postDelayed(Runnable, long)
new Thread()
{
public void run()
{
myactivity.this.runOnUiThread(new runnable()
{
public void run()
{
cc.char_Lat.setText(sb.append(address.getLatitude()));
cc.char_Long.setText(sb.append(address.getLongitude()));
}
});
}
}.start();
答案 3 :(得分:0)
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(location != null) {
showAddress(location);
}
final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location loc) {
showAddress(loc);
}
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
};
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 10, locationListener);
private void showAddress(Location location) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
Geocoder myLoc = new Geocoder(getApplicationContext(), Locale.getDefault());
List<Address> mlist;
try {
mlist = myLoc.getFromLocation(latitude, longitude, 1);
if(mList.size() == 1) { char_Lat.SetText(mlist.get(0).getLatitude().toString()); char_Long.Settext(mlist.get(0).getLongitude().toString());
}
} catch (IOException e) {
// TODO Auto-generated catch block
log.e("IO Exception",e.Message);
}
}
在您的清单中使用位置权限:
android.permission.ACCESS_COARSE_LOCATION或android.permission.ACCESS_FINE_LOCATION
http://developer.android.com/reference/android/Manifest.permission.html