【问题标题】:Android app for sending GPS coordinates to server is crashing用于向服务器发送 GPS 坐标的 Android 应用程序崩溃
【发布时间】:2014-01-21 11:59:28
【问题描述】:

我正在构建一个 android 应用程序,它将 GPS 坐标发送到服务器,但它显示 gps 坐标之后它立即崩溃,根本不向服务器发送坐标。

我的 MainActivity.java 是

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import android.R.string;
import android.app.Activity;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;



public class MainActivity extends Activity implements LocationListener{


private TextView latituteField;
  private TextView longitudeField;
  private LocationManager locationManager;
  private String provider;
  String lat;
String lng;


/** Called when the activity is first created. */

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    latituteField = (TextView) findViewById(R.id.TextView02);
    longitudeField = (TextView) findViewById(R.id.TextView04);

    // Get the location manager
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    // Define the criteria how to select the locatioin provider -> use
    // default
    Criteria criteria = new Criteria();
    provider = locationManager.getBestProvider(criteria, false);
    Location location = locationManager.getLastKnownLocation(provider);

    // Initialize the location fields
    if (location != null) {
      System.out.println("Provider " + provider + " has been selected.");
      onLocationChanged(location);
    } else {
      latituteField.setText("Location not available");
      longitudeField.setText("Location not available");
    }
  }

  /* Request updates at startup */
  @Override
  protected void onResume() {
    super.onResume();
    locationManager.requestLocationUpdates(provider, 400, 1, this);
  }

  /* Remove the locationlistener updates when Activity is paused */
  @Override
  protected void onPause() {
    super.onPause();
    locationManager.removeUpdates(this);
  }




  @Override
  public void onLocationChanged(Location location) {
     lat = Double.toString(location.getLatitude());
     lng = Double.toString (location.getLongitude());
    latituteField.setText(String.valueOf(lat));
    longitudeField.setText(String.valueOf(lng));
    longitudeField.setText(String.valueOf(lng));
    LoadServerASYNC task = new LoadServerASYNC();
    task.execute();


       }



  @Override
  public void onStatusChanged(String provider, int status, Bundle extras) {
    // TODO Auto-generated method stub

  }

  @Override
  public void onProviderEnabled(String provider) {
    Toast.makeText(this, "Enabled new provider " + provider,
        Toast.LENGTH_SHORT).show();

  }

  @Override
  public void onProviderDisabled(String provider) {
    Toast.makeText(this, "Disabled provider " + provider,
        Toast.LENGTH_SHORT).show();
  }

  private class LoadServerASYNC extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... arg0) {
        postData(lat,lng);
         StringBuilder builder = new StringBuilder();
          HttpClient client = new DefaultHttpClient();
        return null;
    }

    public void postData(String currLat, String currLon) { 
        // List with arameters and their values

        String Text2 = "String is: " +

        "Latitud = " + currLat +

        "Longitud = " + currLon;

        Toast.makeText(getApplicationContext(), Text2, Toast.LENGTH_LONG).show();

        HttpPost post = new HttpPost("http://www.url.com/*.php");
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
        nameValuePairs.add(new BasicNameValuePair("myusername", currLat));
        nameValuePairs.add(new BasicNameValuePair("mypassword", currLon));
        HttpClient client = new DefaultHttpClient();    

        try {
            post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse response = client.execute(post);
            HttpEntity entity = response.getEntity();
            String responseText = EntityUtils.toString(entity);
            responseText = responseText.trim();

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        }
         }
         }

这是我的日志

 01-21 06:16:17.400: I/System.out(1107): Provider gps has been selected.
    01-21 06:16:17.630: D/gralloc_goldfish(1107): Emulator without GPU emulation detected.
    01-21 06:16:17.790: W/dalvikvm(1107): threadid=11: thread exiting with uncaught       exception (group=0xb4a15ba8)
    01-21 06:16:17.820: E/AndroidRuntime(1107): FATAL EXCEPTION: AsyncTask #1
    01-21 06:16:17.820: E/AndroidRuntime(1107): Process: com.example.gpsexample2a, PID: 1107
    01-21 06:16:17.820: E/AndroidRuntime(1107): java.lang.RuntimeException: An error   occured while executing doInBackground()
    01-21 06:16:17.820: E/AndroidRuntime(1107):     at android.os.AsyncTask$3.done(AsyncTask.java:300)
    01-21 06:16:17.820: E/AndroidRuntime(1107):     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
    01-21 06:16:17.820: E/AndroidRuntime(1107):     at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
    01-21 06:16:17.820: E/AndroidRuntime(1107):     at java.util.concurrent.FutureTask.run(FutureTask.java:242)
    01-21 06:16:17.820: E/AndroidRuntime(1107):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
    01-21 06:16:17.820: E/AndroidRuntime(1107):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    01-21 06:16:17.820: E/AndroidRuntime(1107):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    01-21 06:16:17.820: E/AndroidRuntime(1107):     at java.lang.Thread.run(Thread.java:841)
    01-21 06:16:17.820: E/AndroidRuntime(1107): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    01-21 06:16:17.820: E/AndroidRuntime(1107):     at android.os.Handler.<init>(Handler.java:200)
    01-21 06:16:17.820: E/AndroidRuntime(1107):     at android.os.Handler.<init>(Handler.java:114)
    01-21 06:16:17.820: E/AndroidRuntime(1107):     at android.widget.Toast$TN.<init>(Toast.java:327)
    01-21 06:16:17.820: E/AndroidRuntime(1107):     at android.widget.Toast.<init>(Toast.java:92)
    01-21 06:16:17.820: E/AndroidRuntime(1107):     at android.widget.Toast.makeText(Toast.java:241)
   01-21 06:16:17.820: E/AndroidRuntime(1107):  at com.example.gpsexample2a.MainActivity$LoadServerASYNC.postData(MainActivity.java:143)
   01-21 06:16:17.820: E/AndroidRuntime(1107):  at   com.example.gpsexample2a.MainActivity$LoadServerASYNC.doInBackground(MainActivity.java:128)
   01-21 06:16:17.820: E/AndroidRuntime(1107):  at com.example.gpsexample2a.MainActivity$LoadServerASYNC.doInBackground(MainActivity.java:1) 
   01-21 06:16:17.820: E/AndroidRuntime(1107):  at android.os.AsyncTask$2.call(AsyncTask.java:288) 
   01-21 06:16:17.820: E/AndroidRuntime(1107):  at java.util.concurrent.FutureTask.run(FutureTask.java:237)

【问题讨论】:

    标签: android android-intent android-asynctask gps


    【解决方案1】:

    从您的 postData 方法中删除这一行

    Toast.makeText(getApplicationContext(), Text2, Toast.LENGTH_LONG).show();
    

    doInBackground(String... arg0)中不能调用Toast方法

    或使用Handler

    【讨论】:

    • 或使用处理程序为您完成工作
    • @alecnash 同意你的看法
    • @alecnash 你能告诉我如何在这里使用处理程序
    • @user3209703 请通过我编辑的答案中发布的教程链接来了解处理程序的实现。
    【解决方案2】:

    你应该使用

    runOnUiThread(new Runnable() {
    
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        Toast.makeText(getApplicationContext(),data, Toast.LENGTH_LONG).show();
                    }
                });
    

    【讨论】:

      【解决方案3】:
       Toast.makeText(getApplicationContext(), Text2, Toast.LENGTH_LONG).show();
      

      在 postData 方法中是原因。您不应该在 AsyncTask 类“doInBackground()”方法上执行 UI-Task。 但是您可以通过其他方法显示 Toast,例如“onPreExecute()”、“onProgressUpdate()”、“onPostExecute()”方法。要了解如何正确使用 AyncTask 类,请参阅this link

      【讨论】:

        【解决方案4】:

        问题与这行代码有关:

        Toast.makeText(getApplicationContext(), Text2, Toast.LENGTH_LONG).show();
        

        此代码与 UI 竞赛有关,android 希望在此竞赛中运行它,而不是在后台线程中运行。

        因此有这个日志:

        异常:无法在未调用 Looper.prepare() 的线程内创建处理程序

        【讨论】:

          猜你喜欢
          • 2018-04-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多