これは非常に単純なはずですが、何か/どのように Null になるかわかりません。Google Places API の結果をAutoCompleteTextViewにしようとしています。URL の作成が正しいことがわかります。Google から結果を取得していますが、結果が textView に伝達されると、すべてがクラッシュします。
XML レイアウト - places_search.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#dddddd">
<AutoCompleteTextView android:id="@+id/autoCompleteTextView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp" >
<requestFocus></requestFocus>
</AutoCompleteTextView>
</RelativeLayout>
TextView の XML レイアウト:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp"
android:textColor="#000">
</TextView>
以下は、Google Places API からオートコンプリート結果を検索する完全なコードです。
public class PlacesListSearchActivity extends Activity {
private static final String TAG = "PlacesListActivity";
private ResultReceiver mReceiver;
private OnSharedPreferenceChangeListener sharedPreferencesListener;
private SharedPreferences sharedPreferences;
/** Called when the activity is first created. */
public ArrayAdapter<String> adapter;
public AutoCompleteTextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.places_search);
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.item_list);
final AutoCompleteTextView textView = (AutoCompleteTextView)findViewById(R.id.autoCompleteTextView1);
adapter.setNotifyOnChange(true);
textView.setHint("type store name");
textView.setAdapter(adapter);
textView.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (count%3 == 1) {
adapter.clear();
GetPlaces task = new GetPlaces();
//now pass the argument in the textview to the task
task.execute(textView.getText().toString());
}
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
public void afterTextChanged(Editable s) {
}
});
}
class GetPlaces extends AsyncTask<String, Void, ArrayList<String>> {
@Override
// three dots is java for an array of strings
protected ArrayList<String> doInBackground(String... args)
{
Log.d("gottaGo", "doInBackground");
ArrayList<String> predictionsArr = new ArrayList<String>();
try
{
URL googlePlaces = new URL(
"https://maps.googleapis.com/maps/api/place/autocomplete/json?input=" +
URLEncoder.encode(args[0], "UTF-8") +
"&types=geocode&language=en&sensor=true&key=" +
getResources().getString(R.string.googleAPIKey));
Log.d("URL", googlePlaces.toString());
URLConnection tc = googlePlaces.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
tc.getInputStream()));
String line;
StringBuffer sb = new StringBuffer();
//take Google's legible JSON and turn it into one big string.
while ((line = in.readLine()) != null) {
sb.append(line);
}
//turn that string into a JSON object
JSONObject predictions = new JSONObject(sb.toString());
//now get the JSON array that's inside that object
JSONArray ja = new JSONArray(predictions.getString("predictions"));
for (int i = 0; i < ja.length(); i++) {
JSONObject jo = (JSONObject) ja.get(i);
//add each entry to our array
predictionsArr.add(jo.getString("description"));
}
} catch (IOException e)
{
Log.e("YourApp", "GetPlaces : doInBackground", e);
} catch (JSONException e)
{
Log.e("YourApp", "GetPlaces : doInBackground", e);
}
return predictionsArr;
}
//then our post
@Override
protected void onPostExecute(ArrayList<String> result){
Log.d("YourApp", "onPostExecute : " + result.size());
//update the adapter
adapter = new ArrayAdapter<String>(getBaseContext(), R.layout.item_list);
adapter.setNotifyOnChange(true);
//attach the adapter to textview
textView.setAdapter(adapter);
for (String string : result) {
Log.d("YourApp", "onPostExecute : result = " + string);
adapter.add(string);
adapter.notifyDataSetChanged();
}
Log.d("YourApp", "onPostExecute : autoCompleteAdapter" + adapter.getCount());
}
}
}
以下はLOGCATです:
06-24 09:34:41.225: E/AndroidRuntime(10588): FATAL EXCEPTION: main
06-24 09:34:41.225: E/AndroidRuntime(10588): java.lang.NullPointerException
06-24 09:34:41.225: E/AndroidRuntime(10588): at com.rathinavelu.rea.PlacesListSearchActivity$GetPlaces.onPostExecute(PlacesListSearchActivity.java:156)
06-24 09:34:41.225: E/AndroidRuntime(10588): at com.rathinavelu.rea.PlacesListSearchActivity$GetPlaces.onPostExecute(PlacesListSearchActivity.java:1)
06-24 09:34:41.225: E/AndroidRuntime(10588): at android.os.AsyncTask.finish(AsyncTask.java:602)
06-24 09:34:41.225: E/AndroidRuntime(10588): at android.os.AsyncTask.access$600(AsyncTask.java:156)
06-24 09:34:41.225: E/AndroidRuntime(10588): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615)
06-24 09:34:41.225: E/AndroidRuntime(10588): at android.os.Handler.dispatchMessage(Handler.java:99)
06-24 09:34:41.225: E/AndroidRuntime(10588): at android.os.Looper.loop(Looper.java:137)
06-24 09:34:41.225: E/AndroidRuntime(10588): at android.app.ActivityThread.main(ActivityThread.java:4507)
06-24 09:34:41.225: E/AndroidRuntime(10588): at java.lang.reflect.Method.invokeNative(Native Method)
06-24 09:34:41.225: E/AndroidRuntime(10588): at java.lang.reflect.Method.invoke(Method.java:511)
06-24 09:34:41.225: E/AndroidRuntime(10588): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
06-24 09:34:41.225: E/AndroidRuntime(10588): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
06-24 09:34:41.225: E/AndroidRuntime(10588): at dalvik.system.NativeStart.main(Native Method)
156 行目から、コードの次の行に移動します。
textView.setAdapter(adapter);