開始と停止の 2 つのボタンがある Android アプリケーションを作成しました。開始ボタンをクリックすると、1 秒ごとに現在の緯度と経度の値がポストとして usl に送信され、リモートの mysl データベースに挿入されます。
開始ボタン内に、緯度と経度を送信するためのサービス MyService を作成しました。
MyService の onStartCommand(..) メソッド内で、緯度と経度を 1 秒で送信するためのタイマーを作成しました。
しかし、私は次の例外を受けています
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
誰かこれの解決策を教えてください
私のコードは以下の通りです
iLoadPage.java
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class iLoadPage extends Activity {
Button start,stop;
boolean flag=true;
double latin,longin,longitude,latitude;
Activity activity;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.iloadpage);
start = (Button) findViewById(R.id.startapp);
stop = (Button) findViewById(R.id.stop);
stop.setEnabled(false);
start.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
start.setEnabled(false);
stop.setEnabled(true);
String trackid= getIntent().getExtras().getString("trackid");
MyService.setTrackid(trackid);
startService(new Intent(getBaseContext(),MyService.class));
}
});
stop.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
start.setEnabled(true);
stop.setEnabled(false);
stopService(new Intent(getBaseContext(),MyService.class));
}
});
}
@Override
public void onDestroy() {
super.onDestroy();
}
public double getLatin() {
return latin;
}
public void setLatin(double latin) {
this.latin = latin;
}
public double getLongin() {
return longin;
}
public void setLongin(double longin) {
this.longin = longin;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
}
MyService .java
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
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.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.IBinder;
import android.text.Html;
import android.widget.Toast;
public class MyService extends Service {
public static String trackid;
ScheduledExecutorService scheduler ;
GPSTracker gps;
boolean flag=false;
DownloadFile ss;
Handler handler = new Handler();
double latin,longin,longitude,latitude;
private final int TEN_SECONDS = 3000;
@Override
public IBinder onBind(Intent arg0) {
return null;
}
String errors="notnull";
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
try
{
Toast.makeText(this, "Application Service Started!!!...", Toast.LENGTH_LONG).show();
try {
TimerTask myTimerTask = new TimerTask() {
@Override
public void run() {
flag=true;
DownloadFile sd=new DownloadFile();
sd.execute("");
} };
Timer timer = new Timer();
timer.schedule(myTimerTask, 1000);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}catch(Exception e){
e.printStackTrace();
Toast.makeText(this, "Service Error->"+e, Toast.LENGTH_LONG).show();}
return START_STICKY;
}
@Override
public void onDestroy()
{
flag=false;
super.onDestroy();
Toast.makeText(this, "Application Service Stopped!!!...", Toast.LENGTH_LONG).show();
}
public double getLatin() {
return latin;
}
public void setLatin(double latin) {
this.latin = latin;
}
public double getLongin() {
return longin;
}
public void setLongin(double longin) {
this.longin = longin;
}
public static String getTrackid() {
return trackid;
}
public static void setTrackid(String trackid) {
CopyOfMyService.trackid = trackid;
}
String pass;
private class DownloadFile extends AsyncTask<String, Integer, String> {
@Override
protected String doInBackground(String... sUrl) {
try {
gps = new GPSTracker(CopyOfMyService.this);
latin = gps.getLatitude();
longin = gps.getLongitude();
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://iloadlogistics.com.au/insert1.jsp");
String trackid= CopyOfMyService.getTrackid();
List<NameValuePair> namevaluepairs = new ArrayList<NameValuePair>(2);
namevaluepairs.add(new BasicNameValuePair("trackid",trackid));
namevaluepairs.add(new BasicNameValuePair("lat",""+latin));
namevaluepairs.add(new BasicNameValuePair("lon",""+longin));
httppost.setEntity(new UrlEncodedFormEntity(namevaluepairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity rp = response.getEntity();
String origresponseText = EntityUtils.toString(rp);
String htmlTextStr = Html.fromHtml(origresponseText).toString();
pass=htmlTextStr.trim();
if(htmlTextStr.trim().equals("success"))
{
}else if(htmlTextStr.trim().equals("failure")){
}
} catch (Exception e) {
pass=""+e;
// TODO Auto-generated catch block
System.out.println("ERRRRRRRRRRRRRRRRRROR:"+e);
e.printStackTrace();
}
return pass;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(flag)
{
Toast.makeText(getApplicationContext(), "Inserted!!!...", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(getApplicationContext(), "Asyntask is Destroying!!!...", Toast.LENGTH_LONG).show();
onDestroy();
}
}
@Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
}
}
}
GPSTracker.java
public class GPSTracker extends Service implements LocationListener {
private final Context mContext;
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
boolean canGetLocation = false;
Location location; // location
double latitude; // latitude
double longitude; // longitude
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 5; // 10 meters
private static final long MIN_TIME_BW_UPDATES = 1000; // 1 minute
protected LocationManager locationManager;
public GPSTracker(Context context) {
this.mContext = context;
getLocation();
}
public Location getLocation() {
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
this.canGetLocation = true;
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
public void stopUsingGPS(){
if(locationManager != null){
locationManager.removeUpdates(GPSTracker.this);
}
}
public double getLatitude(){
if(location != null){
latitude = location.getLatitude();
}
return latitude;
}
public double getLongitude(){
if(location != null){
longitude = location.getLongitude();
}
return longitude;
}
public boolean canGetLocation() {
return this.canGetLocation;
}
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
alertDialog.setTitle("GPS is settings");
alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
// on pressing cancel button
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
public void onLocationChanged(Location location) {
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
public IBinder onBind(Intent arg0) {
return null;
}
}
UPDATION 2
Timer の代わりに、以下に示す次の定義を持つメソッドscheduleSendLocation()を呼び出していました
Runnable r=new Runnable() {
public void run() {
flag=true;
DownloadFile sd=new DownloadFile();
sd.execute("");
handler.postDelayed(this, TEN_SECONDS);
}
};
public void scheduleSendLocation() {
handler.postDelayed(r, TEN_SECONDS);
}