关于android:将AutoCompleteTextView改为ActionBar中的SearchView
Turn AutoCompleteTextView into a SearchView in ActionBar instead
我有一个 AutoCompleteTextView,它为用户提供来自 Google Places API 的自动完成搜索结果。完成后,我发现了 SearchView 以及如何将其放置在 ActionBar 中。我查看了 google 提供的 SearchView 示例,并将其作为起点添加到我的应用程序中(它列出了已安装的应用程序),但我不知道如何从这里开始。我想拥有与 AutoCompleteTextView 相同的功能,但改用 SearchView。
有什么建议吗?
下面提供了整个课程。
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.app.SearchManager; import android.app.SearchableInfo; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.preference.PreferenceManager; import android.text.Editable; import android.text.TextWatcher; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.Window; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import android.widget.ImageView; import android.widget.ListView; import android.widget.SearchView; import android.widget.TextView; import android.widget.Toast; /** * * @author * */ public class PlacesListSearchActivity extends Activity implements SearchView.OnQueryTextListener{ 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; private SearchView mSearchView; private TextView mStatusView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().requestFeature(Window.FEATURE_ACTION_BAR); setContentView(R.layout.places_search); mStatusView = (TextView) findViewById(R.id.status_text); final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.item_list); 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) { } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.searchview_in_menu, menu); MenuItem searchItem = menu.findItem(R.id.action_search); mSearchView = (SearchView) searchItem.getActionView(); setupSearchView(searchItem); return true; } private void setupSearchView(MenuItem searchItem) { if (isAlwaysExpanded()) { mSearchView.setIconifiedByDefault(false); } else { searchItem.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW); } SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); if (searchManager != null) { List<SearchableInfo> searchables = searchManager.getSearchablesInGlobalSearch(); // Try to use the"applications" global search provider SearchableInfo info = searchManager.getSearchableInfo(getComponentName()); for (SearchableInfo inf : searchables) { if (inf.getSuggestAuthority() != null && inf.getSuggestAuthority().startsWith("applications")) { info = inf; } } mSearchView.setSearchableInfo(info); } mSearchView.setOnQueryTextListener(this); } public boolean onQueryTextChange(String newText) { mStatusView.setText("Query =" + newText); return false; } public boolean onQueryTextSubmit(String query) { mStatusView.setText("Query =" + query +" : submitted"); return false; } public boolean onClose() { mStatusView.setText("Closed!"); return false; } protected boolean isAlwaysExpanded() { return false; } 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("PlacesListActivity","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=" + SEARCHES FOR GEO CODES "&types=establishment&language=en&sensor=true&key=" + getResources().getString(R.string.googleAPIKey)); Log.d("PlacesListActivity", 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("PlacesListActivity","GetPlaces : doInBackground", e); } catch (JSONException e) { Log.e("PlacesListActivity","GetPlaces : doInBackground", e); } return predictionsArr; } @Override protected void onPostExecute(ArrayList<String> result){ Log.d("PlacesListActivity","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("PlacesListActivity","onPostExecute : result =" + string); adapter.add(string); adapter.notifyDataSetChanged(); } Log.d("PlacesListActivity","onPostExecute : autoCompleteAdapter" + adapter.getCount()); } } } |
更新saxman建议的代码后,我可以看到provider中的查询方法从来没有被调用过:
我的清单文件如下所示:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.rathinavelu.rea" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="15" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name"> <activity android:name=".MainActivity" android:label="@string/app_name" android:screenOrientation="portrait"> <intent-filter> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </activity> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" /> </activity> </activity> </activity> </activity> <uses-library android:name="com.google.android.maps" /> <service android:name=".places.PlacesRESTService" android:enabled="true" android:exported="false"> <intent-filter> </intent-filter> </service> <provider android:name=".places.PlacesSuggestionProvider" android:authorities="com.rathinavelu.rea.places.search_suggestion_provider" android:syncable="false" /> </application> </manifest> |
我在清单、内容提供者和清单文件中使用相同的权限。我在菜单中看到了 searchView 并且我没有修改查询方法,所以它应该只返回一行光标。但查询方法永远不会被调用。请帮忙。
我刚刚发现的另一个问题是 searchView 没有显示指定的 search_hint!
提供更多代码
*PlacesListSearchActivity.java*
public class PlacesListSearchActivity extends Activity { private static final String TAG ="PlacesListSearchActivity"; private ResultReceiver mReceiver; private OnSharedPreferenceChangeListener sharedPreferencesListener; private SharedPreferences sharedPreferences; /** Called when the activity is first created. */ public ArrayAdapter<String> adapter; public AutoCompleteTextView textView; private SearchView mSearchView; private TextView mStatusView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().requestFeature(Window.FEATURE_ACTION_BAR); setContentView(R.layout.places_search); mStatusView = (TextView) findViewById(R.id.status_text); final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.item_list); 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) { } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // super.onCreateOptionsMenu(menu); // Inflate the options menu from XML MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.places_list_search_options_menu, menu); SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView(); // Tells your app's SearchView to use this activity's searchable configuration searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default // setupSearchView(searchItem); return true; } |
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> <TextView android:id="@+id/status_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal"/> </RelativeLayout> |
places_list_search_options_menu.xml
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/menu_search" android:title="@string/menu_search" android:icon="@android:drawable/ic_menu_search" android:showAsAction="collapseActionView|ifRoom" android:actionViewClass="android.widget.SearchView" /> </menu> |
可搜索的.xml
<?xml version="1.0" encoding="utf-8"?> <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/app_name" android:hint="@string/search_hint" android:searchSuggestAuthority="com.rathinavelu.rea.places.search_suggestion_provider"> </searchable> |
PlacesSuggestionProvider.java
public class PlacesSuggestionProvider extends ContentProvider { private static final String LOG_TAG ="PlacesSuggestionProvider"; public static final String AUTHORITY ="com.rathinavelu.rea.places.search_suggestion_provider"; public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY +"/search"); // UriMatcher constant for search suggestions private static final int SEARCH_SUGGEST = 1; private static final UriMatcher uriMatcher; private static final String[] SEARCH_SUGGEST_COLUMNS = { BaseColumns._ID, SearchManager.SUGGEST_COLUMN_TEXT_1, SearchManager.SUGGEST_COLUMN_TEXT_2, SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID }; static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST); uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY +"/*", SEARCH_SUGGEST); } @Override public int delete(Uri uri, String arg1, String[] arg2) { throw new UnsupportedOperationException(); } @Override public String getType(Uri uri) { switch (uriMatcher.match(uri)) { case SEARCH_SUGGEST: return SearchManager.SUGGEST_MIME_TYPE; default: throw new IllegalArgumentException("Unknown URL" + uri); } } @Override public Uri insert(Uri uri, ContentValues arg1) { throw new UnsupportedOperationException(); } @Override public boolean onCreate() { return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Log.d(LOG_TAG,"query =" + uri); // Use the UriMatcher to see what kind of query we have switch (uriMatcher.match(uri)) { case SEARCH_SUGGEST: Log.d(LOG_TAG,"Search suggestions requested."); MatrixCursor cursor = new MatrixCursor(SEARCH_SUGGEST_COLUMNS, 1); cursor.addRow(new String[] { "1","Search Result","Search Result Description","content_id" }); return cursor; default: throw new IllegalArgumentException("Unknown Uri:" + uri); } } @Override public int update(Uri uri, ContentValues arg1, String arg2, String[] arg3) { throw new UnsupportedOperationException(); } } |
- 嗨,只是想知道,在操作栏中使用 SearchView 而不是 AutoCompleteTextView 搜索功能有什么优势吗?
- 为未来的访问者提供了极好的链接; drzon.net/…
要在 SearchView 中获取 Places Autocomplete API 结果,您首先需要 API 的 ContentProvider。
import android.app.SearchManager; import android.content.ContentProvider; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.MatrixCursor; import android.net.Uri; import android.provider.BaseColumns; import android.util.Log; public class PlacesSuggestionProvider extends ContentProvider { private static final String LOG_TAG ="ExampleApp"; public static final String AUTHORITY ="com.example.google.places.search_suggestion_provider"; public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY +"/search"); // UriMatcher constant for search suggestions private static final int SEARCH_SUGGEST = 1; private static final UriMatcher uriMatcher; private static final String[] SEARCH_SUGGEST_COLUMNS = { BaseColumns._ID, SearchManager.SUGGEST_COLUMN_TEXT_1, SearchManager.SUGGEST_COLUMN_TEXT_2, SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID }; static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST); uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY +"/*", SEARCH_SUGGEST); } @Override public int delete(Uri uri, String arg1, String[] arg2) { throw new UnsupportedOperationException(); } @Override public String getType(Uri uri) { switch (uriMatcher.match(uri)) { case SEARCH_SUGGEST: return SearchManager.SUGGEST_MIME_TYPE; default: throw new IllegalArgumentException("Unknown URL" + uri); } } @Override public Uri insert(Uri uri, ContentValues arg1) { throw new UnsupportedOperationException(); } @Override public boolean onCreate() { return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Log.d(LOG_TAG,"query =" + uri); // Use the UriMatcher to see what kind of query we have switch (uriMatcher.match(uri)) { case SEARCH_SUGGEST: Log.d(LOG_TAG,"Search suggestions requested."); MatrixCursor cursor = new MatrixCursor(SEARCH_SUGGEST_COLUMNS, 1); cursor.addRow(new String[] { "1","Search Result","Search Result Description","content_id" }); return cursor; default: throw new IllegalArgumentException("Unknown Uri:" + uri); } } @Override public int update(Uri uri, ContentValues arg1, String arg2, String[] arg3) { throw new UnsupportedOperationException(); } } |
然后将您的 Places Autocomplete API 客户端代码添加到内容提供程序的查询方法中。您提取用户输入如下:
String query = uri.getLastPathSegment().toLowerCase(); |
将 PlacesSuggestionProvider 添加到您的 AndroidManifest,并确保您的活动具有可搜索的配置。
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name"> <intent-filter> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" /> </activity> <provider android:name="com.example.google.places.PlacesSuggestionProvider" android:authorities="com.example.google.places.search_suggestion_provider" android:syncable="false" /> </application> </manifest> |
并确保您的可搜索配置 (res/xml/searchable.xml) 具有搜索建议权限。
<?xml version="1.0" encoding="utf-8"?> <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/app_name" android:hint="@string/search_hint" android:searchSuggestAuthority="com.example.google.places.search_suggestion_provider"> </searchable> |
AndroidManifest.xml、searchable.xml 和你的内容提供者中的权限应该相同。
为包含 SearchView (/res/menu/options_menu.xml) 的 ActionBar 创建一个选项菜单。
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/menu_search" android:title="@string/menu_search" android:icon="@drawable/ic_menu_search" android:showAsAction="collapseActionView|ifRoom" android:actionViewClass="android.widget.SearchView" /> </menu> |
使用与您的可搜索配置相关联的 SearchView 配置您的 Activity/
@Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the options menu from XML MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.options_menu, menu); SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView(); // Tells your app's SearchView to use this activity's searchable configuration searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default return true; } |
几个关键文档是:
添加自定义建议:
http://developer.android.com/guide/topics/search/adding-custom-suggestions.html
创建内容提供者:
http://developer.android.com/guide/topics/providers/content-provider-creating.html
使用搜索小部件:
http://developer.android.com/guide/topics/search/search-dialog.html#UsingSearchWidget
- 谢谢回复。所以内容提供者将在 Google Places 上进行查找并返回一个光标!但是我还是不知道searchView是怎么连接的?
- 也添加了该代码(最后 2 个代码块)。在 onCreateOptionsMenu 中,您将 SearchView 配置为使用您为活动定义的可搜索配置。
- 听起来您可能错过了最后一部分:将您的可搜索配置与 SearchView 相关联。请同时发布您的其他文件(searchable.xml、PlacesListSearchActivity、PlaceSuggestionProvider 以及您用于选项菜单的任何文件)。
- 我已经添加了几乎所有的课程。可搜索的.xml
带有谷歌搜索 API 的 AutoCompleteTextView
你的xml
<AutoCompleteTextView android:id="@+id/main_omnibox_input" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:background="@null" android:hint="Search" android:focusable="true" android:focusableInTouchMode="true" android:selectAllOnFocus="true" android:singleLine="true" android:textSize="@dimen/_14sdp" /> |
你的java代码
this.inputBox = (AutoCompleteTextView) findViewById(R.id.main_omnibox_input); inputBox.setAdapter(new SearchAutocompleteAdapter(SearchActivity.this, new SearchAutocompleteAdapter.OnSearchCommitListener() { @Override public void onSearchCommit(String text) { inputBox.setText(text); inputBox.setSelection(text.length()); } })); this.inputBox.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView< ? > adapterView, View view, int i, long j) { String charSequence = ((TextView) view.findViewById(android.R.id.text1)).getText().toString(); inputBox.setText(Html.fromHtml(BrowserUnit.urlWrapper(charSequence)), BufferType.SPANNABLE); inputBox.setSelection(charSequence.length()); // your code // updateAlbum(charSequence); // hideSoftInput(SearchActivity.this.inputBox); } }); |
搜索自动完成适配器
public class SearchAutocompleteAdapter extends BaseAdapter implements Filterable { interface OnSearchCommitListener { void onSearchCommit(String text); } private final Context mContext; private final OnSearchCommitListener commitListener; private List<String> completions = new ArrayList<>(); static final String searchCompleteUrl ="https://www.google.com/complete/search?client=firefox&q=%s"; SearchAutocompleteAdapter(Context context, OnSearchCommitListener commitListener) { mContext = context; this.commitListener = commitListener; } @Override public int getCount() { return completions.size(); } @Override public Object getItem(int position) { return completions.get(position); } @Override public long getItemId(int position) { return position; } @SuppressLint("ClickableViewAccessibility") @Override @SuppressWarnings("ConstantConditions") public View getView(final int position, View convertView, ViewGroup parent) { if (convertView == null) { LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(android.R.layout.simple_dropdown_item_1line, parent, false); } TextView textview = convertView.findViewById(android.R.id.text1); textview.setText(completions.get(position)); Drawable d = ContextCompat.getDrawable(mContext, R.drawable.icon_goarrowsmall); final int size = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 32, mContext.getResources().getDisplayMetrics()); d.setBounds(0, 0, size, size); textview.setCompoundDrawables(null, null, d, null); textview.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { if (event.getAction() != MotionEvent.ACTION_DOWN) { return false; } TextView t = (TextView) view; if (event.getX() > t.getWidth() - t.getCompoundPaddingRight()) { commitListener.onSearchCommit(getItem(position).toString()); return true; } return false; } }); parent.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { if (event.getX() > view.getWidth() - size * 2) { return true; } return false; } }); return convertView; } @Override public Filter getFilter() { return new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { // Invoked on a worker thread FilterResults filterResults = new FilterResults(); if (constraint != null) { List<String> results = getCompletions(constraint.toString()); filterResults.values = results; filterResults.count = results.size(); } return filterResults; } @Override @SuppressWarnings("unchecked") protected void publishResults(CharSequence constraint, FilterResults results) { if (results != null && results.count > 0) { completions = (List<String>) results.values; notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } } }; } private List<String> getCompletions(String text) { int total = 0; byte[] data = new byte[16384]; try { URL url = new URL(URLUtil.composeSearchUrl(text, searchCompleteUrl,"%s")); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); try { InputStream in = new BufferedInputStream(urlConnection.getInputStream()); while (total <= data.length) { int count = in.read(data, total, data.length - total); if (count == -1) { break; } total += count; } if (total == data.length) { // overflow return new ArrayList<>(); } } finally { urlConnection.disconnect(); } } catch (IOException e) { return new ArrayList<>(); } JSONArray jsonArray; try { jsonArray = new JSONArray(new String(data, StandardCharsets.UTF_8)); } catch (JSONException e) { return new ArrayList<>(); } jsonArray = jsonArray.optJSONArray(1); if (jsonArray == null) { return new ArrayList<>(); } final int MAX_RESULTS = 10; List<String> result = new ArrayList<>(Math.min(jsonArray.length(), MAX_RESULTS)); for (int i = 0; i < jsonArray.length() && result.size() < MAX_RESULTS; i++) { String s = jsonArray.optString(i); if (s != null && !s.isEmpty()) { result.add(s); } } return result; } |
}