首先,我将解释我正在尝试使用我的Android应用程序。该应用程序允许用户输入他们的车辆信息以及起点和终点。然后,用户将点击“计划我的公路旅行”按钮,该按钮将把它们发送到第二页上有Google Map的页面。在第二页上,应用程序将获取原点和目的地,将它们放入Google Directions URL,即
http://maps.googleapis.com/maps/api/directions/json?origin=90210&destination=02115&sensor=false&units=imperial
然后将“overview_polyline”JSONObject解析为LatLng ArrayList。该ArrayList将用于使用折线绘制原点和目的地之间的路径。
正如您在屏幕截图中看到的那样,用户有4个微调器可供选择,与此问题无关。用户还有一个Origin EditText框和一个我上面提到的Destination EditText框。
我的问题如下。当我单击将我带到第二页的按钮时,应用程序崩溃了。它甚至没有超过setContentView(R.layout.page2);
。我已经在另一个项目中测试了JSON解析,并且解析代码没有任何问题,但由于某种原因它在这种情况下不起作用。我也在使用AsyncTask类。这是要走的路吗?如果没有,是否可以展示一个正确的方法来做这个例子?此外,正如您将在代码中看到的那样,如果我手动将点添加到ArrayList而不是动态填充,则加载地图并使折线工作。
这是代码......
Page2Activity.java
public class Page2Activity extends FragmentActivity {
GoogleMap map;
//Non Dynamic ArrayList
//ArrayList<LatLng> points = new ArrayList<LatLng>();
//Dynamic ArrayList
ArrayList<LatLng> poly = new ArrayList<LatLng>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.page2);
//Async Task here
new populatePolys().execute();
//This works if I manually add the points. Non Dynamic. But obviously this is not what I want.
// SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
// map = fm.getMap();
//
// points.add(new LatLng(51.5, -0.1));
// points.add(new LatLng(40.7, -74.0));
// points.add(new LatLng(30.2, -80.1));
// Polyline line = map.addPolyline(new PolylineOptions()
// .addAll(points)
// .width(5)
// .color(Color.RED));
}
class populatePolys extends AsyncTask<Void, Void, ArrayList<LatLng>> {
protected ArrayList<LatLng> doInBackground(Void... params) {
//Creating a new instance of the Activity for the first page
//The first page holds the user's input for the Origin EditText box and Destination EditText box.
MainActivity mA = new MainActivity();
String pointA = "";
String pointB = "";
try {
//Grabbing the user input from the main page.
pointA = URLEncoder.encode(mA.originEditText.getText().toString(), "UTF-8");
pointB = URLEncoder.encode(mA.destinationEditText.getText().toString(), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
JSONObject jsonObject = null;
String status = "INVALID_REQUEST";
try {
jsonObject = readJsonFromUrl("http://maps.googleapis.com/maps/api/directions/json?origin=" + pointA + "&destination=" + pointB + "&sensor=false&units=imperial");
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
if(status.equals("OK")){
//Directions entered are correct.
JSONObject polyArray;
JSONArray routesArray;
try {
//Grabbing the Polyline points String. This does pull the correct value.
//Parsing is correct.
routesArray = jsonObject.getJSONArray("routes");
JSONObject route = routesArray.getJSONObject(0);
polyArray = route.getJSONObject("overview_polyline");
String polyPoints = polyArray.getString("points");
//Passing the Polyline points from the JSON file I get from the Google Directions URL into a decoder.
decodePoly(polyPoints);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return poly;
}
protected void onPostExecute(NodeList makeList) {
//Adding the Dynamic ArrayList "poly" into Polylines.
SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
map = fm.getMap();
Polyline line = map.addPolyline(new PolylineOptions()
.addAll(poly)
.width(5)
.color(Color.RED));
}
}
/*
* LatLng Decoder for polyline
*/
private List<LatLng> decodePoly(String encoded) {
int index = 0, len = encoded.length();
int lat = 0, lng = 0;
while (index < len) {
int b, shift = 0, result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
LatLng p = new LatLng((int) (((double) lat / 1E5) * 1E6),
(int) (((double) lng / 1E5) * 1E6));
poly.add(p);
}
return poly;
}
/*
* Methods to parse the JSON when grabbing from Google Directions API
*/
private static String readAll(Reader rd) throws IOException {
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
return sb.toString();
}
public static JSONObject readJsonFromUrl(String url) throws IOException, JSONException {
InputStream is = new URL(url).openStream();
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
String jsonText = readAll(rd);
JSONObject jsonObject = new JSONObject(jsonText);
return jsonObject;
} finally {
is.close();
}
}
}
page2.xml的代码.... 更新(请参阅旧代码的编辑)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment"/>
</LinearLayout>
更新了LogCat ......
07-10 11:33:09.193: E/AndroidRuntime(8130): FATAL EXCEPTION: AsyncTask #5
07-10 11:33:09.193: E/AndroidRuntime(8130): java.lang.RuntimeException: An error occured while executing doInBackground()
07-10 11:33:09.193: E/AndroidRuntime(8130): at android.os.AsyncTask$3.done(AsyncTask.java:299)
07-10 11:33:09.193: E/AndroidRuntime(8130): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
07-10 11:33:09.193: E/AndroidRuntime(8130): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
07-10 11:33:09.193: E/AndroidRuntime(8130): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
07-10 11:33:09.193: E/AndroidRuntime(8130): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
07-10 11:33:09.193: E/AndroidRuntime(8130): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
07-10 11:33:09.193: E/AndroidRuntime(8130): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
07-10 11:33:09.193: E/AndroidRuntime(8130): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
07-10 11:33:09.193: E/AndroidRuntime(8130): at java.lang.Thread.run(Thread.java:856)
07-10 11:33:09.193: E/AndroidRuntime(8130): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
07-10 11:33:09.193: E/AndroidRuntime(8130): at android.os.Handler.<init>(Handler.java:121)
07-10 11:33:09.193: E/AndroidRuntime(8130): at android.app.Activity.<init>(Activity.java:763)
07-10 11:33:09.193: E/AndroidRuntime(8130): at com.example.roadtripplanner.MainActivity.<init>(MainActivity.java:51)
07-10 11:33:09.193: E/AndroidRuntime(8130): at com.example.roadtripplanner.Page2Activity$populatePolys.doInBackground(Page2Activity.java:74)
07-10 11:33:09.193: E/AndroidRuntime(8130): at com.example.roadtripplanner.Page2Activity$populatePolys.doInBackground(Page2Activity.java:1)
07-10 11:33:09.193: E/AndroidRuntime(8130): at android.os.AsyncTask$2.call(AsyncTask.java:287)
07-10 11:33:09.193: E/AndroidRuntime(8130): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
07-10 11:33:09.193: E/AndroidRuntime(8130): ... 5 more
要查看旧的logcat,请参阅编辑
请询问您是否需要更多代码。
答案 0 :(得分:3)
请仔细查看错误Caused by: java.lang.ClassCastException: com.google.android.gms.maps.MapFragment cannot be cast to android.support.v4.app.Fragment
我相信你在xml中使用了错误的类
android:name="com.google.android.gms.maps.MapFragment"
应该是
android:name="com.google.android.gms.maps.SupportMapFragment"