I have a AutoCompleteTextView which gives user auto-completion search result from Google Places API. Once I was done I discovered SearchView and how it can be placed in the ActionBar. I checked out the SearchView example provided by google and added it to my application as a starting point (it lists the installed applications) but I don´t know how to proceed from here. I want to have the same functionality as AutoCompleteTextView but use the SearchView instead.
Any suggestion?
The whole class is provided below.
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());
}
}
}
After updating the code suggested by saxman, I can see that the query method in the provider is never called:
My manifest file looks like this:
<?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>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".PlacesListActivity" >
</activity>
<activity android:name=".PlacesListSearchActivity" >
<action android:name="android.intent.action.SEARCH" />
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
<activity android:name=".TestMapActivity" >
</activity>
<activity android:name=".SettingsPreferencesActivity" >
</activity>
<activity android:name="com.rathinavelu.util.ConnectionChecker" >
</activity>
<uses-library android:name="com.google.android.maps" />
<service
android:name=".places.PlacesRESTService"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.ACTION_SYNC" />
</intent-filter>
</service>
<provider
android:name=".places.PlacesSuggestionProvider"
android:authorities="com.rathinavelu.rea.places.search_suggestion_provider"
android:syncable="false" />
</application>
</manifest>
I use the same authority in the manifest, content provider and manifest file. I see the searchView in the menu and I have not modified the query method so It should just return the one line cursor. but the query method is never called. please help.
Another issue I just spotted is that the searchView does not show the specified search_hint!
Providing more code
*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>
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.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();
}
}
To get Places Autocomplete API results in a SearchView, you'll first need a ContentProvider for the API.
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();
}
}
Then add your Places Autocomplete API client code into the query method on the content provider. You extract the user input as follows:
String query = uri.getLastPathSegment().toLowerCase();
Add the PlacesSuggestionProvider to your AndroidManifest, and make sure your activity has a searchable configuration.
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity android:name=".PlacesSearchViewActivity" >
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<action android:name="android.intent.action.MAIN" />
<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>
And make sure your searchable configuration (res/xml/searchable.xml) has a search suggest authority.
<?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>
The authority should be the same in AndroidManifest.xml, searchable.xml, and your content provider.
Create a options menu for your ActionBar that includes a SearchView (/res/menu/options_menu.xml).
<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>
Configure your Activity with a SearchView that's associated with your searchable configuration/
#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;
}
A few key docs are:
Adding Custom Suggestions:
http://developer.android.com/guide/topics/search/adding-custom-suggestions.html
Creating a Content Provider:
http://developer.android.com/guide/topics/providers/content-provider-creating.html
Using a Search Widget:
http://developer.android.com/guide/topics/search/search-dialog.html#UsingSearchWidget
AutoCompleteTextView with google search Api
your 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" />
your java code
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);
}
});
SearchAutocompleteAdapter
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;
}
}
Related
I am facing crash on the getting list view with use of volley library .
I have used login with Facebook separate . and got list view with volley library separate. But when i am integrating both then i am getting crash . I want to login with Facebook after successful login i want list view. But i am getting crash .
see in the image when i did with separate project then i am getting list view with volley library.
But after adding Facebook login. I am getting crash. Please tell me solution for same.
MainActivity.java
public class MainActivity extends Activity {
private CallbackManager callbackManager;
private LoginButton loginButton;
private TextView btnLogin;
private ProgressDialog progressDialog;
User user;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(this);
setContentView(R.layout.activity_main);
//Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
//setSupportActionBar(toolbar);
if(PrefUtils.getCurrentUser(MainActivity.this) != null){
//Intent homeIntent = new Intent(MainActivity.this, LogoutActivity.class);
Intent homeIntent = new Intent(MainActivity.this, ListViewActivity.class);
startActivity(homeIntent);
finish();
}
try {
PackageInfo info = getPackageManager().getPackageInfo(
"com.comida",
PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
}
} catch (PackageManager.NameNotFoundException e) {
} catch (NoSuchAlgorithmException e) {
}
/* FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});*/
}
#Override
protected void onResume() {
super.onResume();
callbackManager=CallbackManager.Factory.create();
loginButton= (LoginButton)findViewById(R.id.login_button);
loginButton.setReadPermissions("public_profile", "email","user_friends");
btnLogin= (TextView) findViewById(R.id.btnLogin);
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage("Loading...");
progressDialog.show();
loginButton.performClick();
loginButton.setPressed(true);
loginButton.invalidate();
loginButton.registerCallback(callbackManager, mCallBack);
loginButton.setPressed(false);
loginButton.invalidate();
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}
private FacebookCallback<LoginResult> mCallBack = new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
progressDialog.dismiss();
// App code
GraphRequest request = GraphRequest.newMeRequest(
loginResult.getAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(
JSONObject object,
GraphResponse response) {
Log.e("response: ", response + "");
try {
user = new User();
user.facebookID = object.getString("id").toString();
user.email = object.getString("email").toString();
user.name = object.getString("name").toString();
user.gender = object.getString("gender").toString();
PrefUtils.setCurrentUser(user,MainActivity.this);
}catch (Exception e){
e.printStackTrace();
}
Toast.makeText(MainActivity.this,"welcome "+user.name,Toast.LENGTH_LONG).show();
Intent intent=new Intent(MainActivity.this,ListViewActivity.class);
//Intent intent=new Intent(MainActivity.this,LogoutActivity.class);
startActivity(intent);
finish();
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,email,gender, birthday");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
progressDialog.dismiss();
}
#Override
public void onError(FacebookException e) {
progressDialog.dismiss();
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
/*#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}*/
}
ListViewActivity.java
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.ProgressDialog;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.widget.ListView;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.JsonArrayRequest;
import com.comida.MainActivity;
import com.comida.R;
import com.comida.adater.CustomListAdapter;
import com.comida.app.AppController;
import com.comida.model.Movie;
public class ListViewActivity extends Activity {
// Log tag
private static final String TAG = ListViewActivity.class.getSimpleName();
private static final String url = "http://wpgmiiyrhn.localtunnel.me/api/v1/restaurants?per_page=10&page=1&sort_col=average_ratings";
// Movies json url
//private static final String url = "http://api.androidhive.info/json/movies.json";
private ProgressDialog pDialog;
private List<Movie> movieList = new ArrayList<Movie>();
private ListView listView;
private CustomListAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_listview);
listView = (ListView) findViewById(R.id.list);
adapter = new CustomListAdapter(this, movieList);
listView.setAdapter(adapter);
pDialog = new ProgressDialog(this);
// Showing progress dialog before making http request
pDialog.setMessage("Loading...");
pDialog.show();
// changing action bar color
getActionBar().setBackgroundDrawable(
new ColorDrawable(Color.parseColor("#1b1b1b")));
// Creating volley request obj
JsonArrayRequest movieReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
Movie movie = new Movie();
//movie.setTitle(obj.getString("title"));
movie.setName(obj.getString("name"));
//movie.setThumbnailUrl(obj.getString("image"));
movie.setThumbnailUrl(obj.getString("image_url"));
movie.setAverage_ratings(obj.getString("average_ratings"));
movie.setCuisine(obj.getString("cuisine"));
movie.setAddress(obj.getJSONObject("address").getString("area"));
//movie.setAddress(obj.getString("address"));
//movie.setYear(obj.getInt("releaseYear"));
// Genre is json array
/*JSONArray genreArry = obj.getJSONArray("genre");
ArrayList<String> genre = new ArrayList<String>();
for (int j = 0; j < genreArry.length(); j++) {
genre.add((String) genreArry.get(j));
}
movie.setGenre(genre);*/
// adding movie to movies array
movieList.add(movie);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(movieReq);
}
#Override
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
/*#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}*/
}
adater -> CustomListAdapter.java
import com.comida.R;
import com.comida.app.AppController;
import com.comida.model.Movie;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.NetworkImageView;
import java.util.List;
public class CustomListAdapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private List<Movie> movieItems;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
public CustomListAdapter(Activity activity, List<Movie> movieItems) {
this.activity = activity;
this.movieItems = movieItems;
}
#Override
public int getCount() {
return movieItems.size();
}
#Override
public Object getItem(int location) {
return movieItems.get(location);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.list_row, null);
if (imageLoader == null)
imageLoader = AppController.getInstance().getImageLoader();
/*ImageView img;
img = (ImageView)convertView
.findViewById(R.id.img);
img.setImageResource(R.drawable.bc);
else {*/
NetworkImageView _ImageView = (NetworkImageView) convertView.findViewById(R.id.thumbnail);
_ImageView.setDefaultImageResId(R.drawable.bc);
//NetworkImageView.setImageUrl(m.getThumbnailUrl(), ImageLoader);
/*NetworkImageView thumbNail = (NetworkImageView) convertView
.findViewById(R.id.thumbnail);*/
TextView name = (TextView) convertView.findViewById(R.id.name);
TextView average_ratings = (TextView) convertView.findViewById(R.id.average_ratings);
TextView address=(TextView) convertView.findViewById(R.id.area);
TextView cuisine =(TextView) convertView.findViewById(R.id.cuisine);
//TextView genre = (TextView) convertView.findViewById(R.id.genre);
//TextView year = (TextView) convertView.findViewById(R.id.releaseYear);
// getting movie data for the row
Movie m = movieItems.get(position);
// thumbnail image
//_ImageView.setImageUrl(m.getThumbnailUrl(), imageLoader);
/*if (TextUtils.isEmpty(m.getThumbnailUrl()))
thumbNail.setImageResource(R.drawable.bc);
else
//Log.d("KeyHash:","Neeraj");*/
_ImageView.setImageUrl(m.getThumbnailUrl(), imageLoader);
/*if (m.getThumbnailUrl().compareTo("")!=0)
thumbNail.setImageUrl(m.getThumbnailUrl(), imageLoader);
//else{
//thumbNail.setImageResource(R.drawable.bc);
else {
thumbNail.setDefaultImageResId(R.drawable.bc);
//thumbNail.setErrorImageResId(R.drawable.bc);
}*/
// title
name.setText(m.getName());
// rating
average_ratings.setText("Rating: " + String.valueOf(m.getAverage_ratings()));
address.setText("Area: " + String.valueOf(m.getAddress()));
cuisine.setText("Cusine: " + String.valueOf(m.getCuisine()));
/*// genre
String genreStr = "";
for (String str : m.getGenre()) {
genreStr += str + ", ";
}
genreStr = genreStr.length() > 0 ? genreStr.substring(0,
genreStr.length() - 2) : genreStr;
genre.setText(genreStr);
// release year
year.setText(String.valueOf(m.getYear()));*/
return convertView;
}
}
app ->appcontroller.java
import com.comida.util.LruBitmapCache;
import android.app.Application;
import android.text.TextUtils;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;
public class AppController extends Application {
public static final String TAG = AppController.class.getSimpleName();
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private static AppController mInstance;
#Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
public static synchronized AppController getInstance() {
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
public ImageLoader getImageLoader() {
getRequestQueue();
if (mImageLoader == null) {
mImageLoader = new ImageLoader(this.mRequestQueue,
new LruBitmapCache());
}
return this.mImageLoader;
}
public <T> void addToRequestQueue(Request<T> req, String tag) {
// set the default tag if tag is empty
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
public void cancelPendingRequests(Object tag) {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
}
Movie -> movie.java
public class Movie {
private String name, thumbnailUrl;
//private int year;
private String average_ratings,area,cuisine,address;
// private ArrayList<String> genre;
public Movie() {
}
public Movie(String name, String thumbnailUrl, String average_ratings, String area, String cuisine, String address
) {
this.name = name;
this.thumbnailUrl = thumbnailUrl;
//this.year = year;
this.average_ratings = average_ratings;
this.area=area;
this.cuisine=cuisine;
this.address=address;
//this.genre = genre;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getThumbnailUrl() {
return thumbnailUrl;
}
public void setThumbnailUrl(String thumbnailUrl) {
this.thumbnailUrl = thumbnailUrl;
}
/*public int getYear() {
return year;
}*/
/*public void setYear(int year) {
this.year = year;
}*/
public String getAverage_ratings() {
return average_ratings;
}
public void setAverage_ratings(String average_ratings) {
this.average_ratings = average_ratings;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCuisine() {
return cuisine;
}
public void setCuisine(String cuisine) {
this.cuisine = cuisine;
}
/*public ArrayList<String> getGenre() {
return genre;
}
public void setGenre(ArrayList<String> genre) {
this.genre = genre;
}
*/
}
util -> LruBitmapCache
import com.android.volley.toolbox.ImageLoader.ImageCache;
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
public class LruBitmapCache extends LruCache<String, Bitmap> implements ImageCache {
public static int getDefaultLruCacheSize() {
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
return cacheSize;
}
public LruBitmapCache() {
this(getDefaultLruCacheSize());
}
public LruBitmapCache(int sizeInKiloBytes) {
super(sizeInKiloBytes);
}
#Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight() / 1024;
}
#Override
public Bitmap getBitmap(String url) {
return get(url);
}
#Override
public void putBitmap(String url, Bitmap bitmap) {
put(url, bitmap);
}
}
logcat ->
/com.comida E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.comida, PID: 7059
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.comida/com.comida.ListViewActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'com.android.volley.toolbox.ImageLoader com.comida.app.AppController.getImageLoader()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'com.android.volley.toolbox.ImageLoader com.comida.app.AppController.getImageLoader()' on a null object reference
at com.comida.adater.CustomListAdapter.<init>(CustomListAdapter.java:22)
at com.comida.ListViewActivity.onCreate(ListViewActivity.java:44)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
07-21 17:09:01.800 2971-3347/system_process W/ActivityManager: Force finishing activity com.comida/.ListViewActivity
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.comida"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="24" />
<!-- To access internet -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- To access accounts configured on device -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- To use account credentials -->
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:name="android.support.multidex.MultiDexApplication"
android:theme="#style/AppTheme">
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="#string/facebook_app_id"/>
<activity android:name="com.facebook.FacebookActivity"
android:configChanges=
"keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:theme="#android:style/Theme.Translucent.NoTitleBar"
android:label="#string/app_name" />
<activity
android:name="com.comida.MainActivity"
android:label="#string/app_name" >
</activity>
<activity
android:name=".ListViewActivity"
>
</activity>
<!--<activity
android:name=".LogoutActivity"
android:label="#string/title_activity_logout" >
</activity>-->
<activity
android:name="SplashActivity"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
</manifest>
Update your Manifest File.
Change tag android:name="Your.Pakage.Name.AppController"
"path.to.this.class.AppController"
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:name="Your.Pakage.Name.AppController"
android:theme="#style/AppTheme">
Update:
Now you are setting actionbar properties and getting issue.
To fix change Activity to AppCompatActivity
ListViewActivity extend AppCompatActivity
So I'm trying to put some modifications on this code now the problem is the application refuses to connect to the game play service and load data , because it uses the old appstate api ! Now i need to migrate from the old Appstate to the new Saved Gamed API
The Android Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="maths.workout.jellyapp"
android:versionCode="4"
android:versionName="1.3" >
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.arkay.funwithmaths.HomeMenuActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.Black.NoTitleBar" >
</activity>
<activity
android:name="com.arkay.funwithmaths.SplashScreenActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.Black.NoTitleBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.arkay.funwithmaths.MultiPlayerPlayActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.Black.NoTitleBar.Fullscreen" >
</activity>
<activity
android:name="com.arkay.funwithmaths.SinglePlayerPlayFragment"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.Black.NoTitleBar" >
</activity>
<activity
android:name="com.arkay.funwithmaths.SettingActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.Black.NoTitleBar" >
</activity>
<!-- <activity
android:name="com.google.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" /> -->
<activity
android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" />
<!-- Google Play Service -->
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version"/>
<meta-data android:name="com.google.android.gms.appstate.APP_ID"
android:value="#string/app_id" />
<meta-data android:name="com.google.android.gms.games.APP_ID"
android:value="#string/app_id" />
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<!-- End Google Play -->
</application>
The Home Menu Activiy
package com.arkay.funwithmaths;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import maths.workout.jellyapp.R;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.LinearLayout;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.InterstitialAd;
import com.google.android.gms.appstate.AppStateManager;
import com.google.android.gms.appstate.AppStateStatusCodes;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.games.Games;
import com.google.example.games.basegameutils.BaseGameActivity;
/**
* Home Screen of the app. It will display tow button one for Play and one for play multiplayer
* #author I-BALL
*
*/
public class HomeMenuActivity extends BaseGameActivity implements
View.OnClickListener, GooglePlayServicesClient.OnConnectionFailedListener, SinglePlayerPlayFragment.Listener {
public static final String PREFS_NAME = "preferences";
private static final String DATABASE_NAME = "database.db";
public static final String MUSIC_SOUND = "music_sound";
public static final String SOUND_EFFECT = "sound_effect";
public static final String VIBRATION = "vibration";
public static final String THIS_lEVEL_TOTAL_SCORE = "this_level_total_score";
public static final String IS_LAST_LEVEL_COMPLETED = "is_last_level_completed";
public static final String LAST_LEVEL_SCORE = "last_level_score";
public static final String MULTI_PLAYER_TOP_TRUE_SCORE="multi_player_game_score";
//Achivement
public static final String HOW_MANY_TIMES_PLAY_QUIZ = "how_many_time_play_quiz";
public static final String HOW_MANY_QUESTION_COMPLETED = "count_question_completed";
public static final String LEVEL_COMPLETED = "level_completed";
public static final String TOTAL_SCORE = "total_score";
public static final String LEVEL ="level";
public static final String VERY_CURIOUS_UNLOCK="is_very_curious_unlocked";
private Button btnSinglePlayer, btnMultiplayer, btnSetting,btnAchivement,btnLeaderBoard,btnHelp;
final int RC_RESOLVE = 5000, RC_UNUSED = 5001;
private static final int OUR_STATE_KEY = 2;
private GameData gameData;
SharedPreferences settings;
SinglePlayerPlayFragment singlePlayerFragment;
/** The view to show the ad. */
private AdView adView;
//Intersial Ads
private InterstitialAd interstitial;
private final Handler mHandler = new Handler();
private ProgressDialog progress;
public HomeMenuActivity() {
super( BaseGameActivity.CLIENT_GAMES | BaseGameActivity.CLIENT_APPSTATE);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFormat(PixelFormat.RGBA_8888);
setContentView(R.layout.activity_home_menu);
settings = getSharedPreferences(HomeMenuActivity.PREFS_NAME, 0);
gameData = new GameData(getSharedPreferences(HomeMenuActivity.PREFS_NAME, 0));
btnSinglePlayer = (Button)findViewById(R.id.btnSinglePlayer);
btnSinglePlayer.setOnClickListener(this);
btnMultiplayer = (Button)findViewById(R.id.btnMultiplayer);
btnMultiplayer.setOnClickListener(this);
btnSetting = (Button)findViewById(R.id.btnSetting);
btnSetting.setOnClickListener(this);
btnAchivement = (Button)findViewById(R.id.btnAchivement);
btnAchivement.setOnClickListener(this);
btnLeaderBoard = (Button)findViewById(R.id.btnLeaderBoard);
btnLeaderBoard.setOnClickListener(this);
btnHelp= (Button)findViewById(R.id.btnHelp);
btnHelp.setOnClickListener(this);
checkDB();
findViewById(R.id.sign_in_button).setOnClickListener(this);
findViewById(R.id.sign_out_button).setOnClickListener(this);
singlePlayerFragment = new SinglePlayerPlayFragment();
singlePlayerFragment.setListener(this);
SignInButton mSignInButton = (SignInButton)findViewById(R.id.sign_in_button);
mSignInButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// start the asynchronous sign in flow
System.out.println("Click on Sign-in");
beginUserInitiatedSignIn();
}
});
/** Create the interstitial.*/
interstitial = new InterstitialAd(this);
interstitial.setAdUnitId(getString(R.string.admob_intersititial));
/** Create ad request. */
Resources ress = getResources();
/**set testmost false when publish app*/
boolean isTestMode = ress.getBoolean(R.bool.istestmode);
AdRequest adRequest =null;
if(isTestMode){
adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.addTestDevice("B15149A4EC1ED23173A27B04134DD483").build();
}else{
adRequest = new AdRequest.Builder().build();
}
/** Begin loading your interstitial. */
interstitial.loadAd(adRequest);
// Create an ad.
adView = new AdView(getApplicationContext());
adView.setAdSize(AdSize.SMART_BANNER);
adView.setAdUnitId(getString(R.string.admob_banner));
// Add the AdView to the view hierarchy. The view will have no size until the ad is loaded.
LinearLayout layout = (LinearLayout) findViewById(R.id.ads_layout);
layout.addView(adView);
mHandler.postDelayed(mUpdateUITimerTask, 10 * 1200);
progress = new ProgressDialog(this);
progress.setTitle("Please Wait!!");
progress.setMessage("Data Loading..");
progress.setCancelable(false);
progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progress.show();
}
/**
* Display Interstital ads.
*/
public void displayInterstitial() {
if (interstitial.isLoaded()) {
interstitial.show();
}
}
public void checkDB() {
try {
String packageName = this.getPackageName();
String destPath = "/data/data/" + packageName + "/databases";
String fullPath = "/data/data/" + packageName + "/databases/"+ DATABASE_NAME;
// this database folder location
File f = new File(destPath);
// this database file location
File obj = new File(fullPath);
// check if databases folder exists or not. if not create it
if (!f.exists()) {
f.mkdirs();
f.createNewFile();
}else{
boolean isDelete = f.delete();
Log.i("Delete", "Delete"+isDelete);
}
// check database file exists or not, if not copy database from assets
if (!obj.exists()) {
this.CopyDB(fullPath);
}else{
this.CopyDB(fullPath);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void CopyDB(String path) throws IOException {
InputStream databaseInput = null;
String outFileName = path;
OutputStream databaseOutput = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024];
int length;
// open database file from asset folder
databaseInput = this.getAssets().open(DATABASE_NAME);
while ((length = databaseInput.read(buffer)) > 0) {
databaseOutput.write(buffer, 0, length);
databaseOutput.flush();
}
databaseInput.close();
databaseOutput.flush();
databaseOutput.close();
}
#Override
public void onSignInFailed() {
System.out.println("Sing In Fail");
findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE);
findViewById(R.id.sign_out_button).setVisibility(View.GONE);
findViewById(R.id.sign_out_bar).setVisibility(View.GONE);
findViewById(R.id.sign_in_bar).setVisibility(View.VISIBLE);
progress.cancel();
}
#Override
public void onSignInSucceeded() {
System.out.println("Sing In Succcess");
findViewById(R.id.sign_in_button).setVisibility(View.GONE);
findViewById(R.id.sign_out_button).setVisibility(View.VISIBLE);
findViewById(R.id.sign_in_bar).setVisibility(View.GONE);
findViewById(R.id.sign_out_bar).setVisibility(View.VISIBLE);
loadFromCloud();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
System.out.println("Result Code: onConnectionFailed: " + arg0);
}
public void unlockAchievement(int achievementId, String fallbackString) {
if (isSignedIn()) {
Games.Achievements.unlock(getApiClient(), getString(achievementId));
}
}
#Override
public void onStartGameRequested(boolean hardMode) {
getSupportFragmentManager().popBackStack();
this.findViewById(R.id.linearLayout1).setVisibility(View.VISIBLE);
}
#Override
public void onShowAchievementsRequested() {
// TODO Auto-generated method stub
if (isSignedIn()) {
startActivityForResult(Games.Achievements.getAchievementsIntent(getApiClient()),
RC_UNUSED);
} else {
showAlert(getString(R.string.achievements_not_available));
}
}
#Override
public void onShowLeaderboardsRequested() {
}
#Override
public void onSignInButtonClicked() {
}
#Override
public void onSignOutButtonClicked() {
}
boolean addList = false;
#Override
public void onBackPressed() {
getSupportFragmentManager().popBackStack();
this.findViewById(R.id.linearLayout1).setVisibility(View.VISIBLE);
if(getSupportFragmentManager().getBackStackEntryCount()==0){
super.onBackPressed();
displayInterstitial(false);
}
}
public void displayInterstitial(boolean isFirstTime) {
if (interstitial.isLoaded()) {
interstitial.show();
if(isFirstTime){
// Create the interstitial.
interstitial = new InterstitialAd(this);
interstitial.setAdUnitId(getString(R.string.admob_intersititial));
// Begin loading your interstitial.
interstitial.loadAd(new AdRequest.Builder().build());
}
}
}
#Override
public void displyHomeScreen() {
getSupportFragmentManager().popBackStack();
}
/**
* Update leaderboards with the user's score.
*
* #param finalScore The score the user got.
*/
#Override
public void updateLeaderboards(int finalScore) {
if (isSignedIn()) {
if (finalScore >= 0) {
Games.Leaderboards.submitScore(getApiClient(), getString(R.string.leaderboard_fun_with_maths),
finalScore);
byte[] scoreData = intToByteArray(finalScore);
AppStateManager.update(getApiClient(), 1, scoreData);
}
}
}
public static byte[] intToByteArray(int a) {
return BigInteger.valueOf(a).toByteArray();
}
public static int byteArrayToInt(byte[] b) {
return new BigInteger(b).intValue();
}
public void loadFromCloud() {
if(isSignedIn()){
AppStateManager.load(getGameHelper().getApiClient(), OUR_STATE_KEY).setResultCallback(mResultCallback);
}
}
public void saveToCloud() {
if(isSignedIn()){
AppStateManager.update(getGameHelper().getApiClient(), OUR_STATE_KEY, gameData.toBytes());
}
}
ResultCallback<AppStateManager.StateResult> mResultCallback = new
ResultCallback<AppStateManager.StateResult>() {
#Override
public void onResult(AppStateManager.StateResult result) {
AppStateManager.StateConflictResult conflictResult = result.getConflictResult();
AppStateManager.StateLoadedResult loadedResult = result.getLoadedResult();
if (loadedResult != null) {
processStateLoaded(loadedResult);
} else if (conflictResult != null) {
processStateConflict(conflictResult);
}
}
};
private void processStateConflict(AppStateManager.StateConflictResult result) {
// Need to resolve conflict between the two states.
// We do that by taking the union of the two sets of cleared levels,
// which means preserving the maximum star rating of each cleared
// level:
byte[] serverData = result.getServerData();
byte[] localData = result.getLocalData();
GameData localGame = new GameData(localData);
GameData serverGame = new GameData(serverData);
GameData resolvedGame = localGame.unionWith(serverGame);
AppStateManager.resolve(getApiClient(), result.getStateKey(), result.getResolvedVersion(),
resolvedGame.toBytes()).setResultCallback(mResultCallback);
}
private void processStateLoaded(AppStateManager.StateLoadedResult result) {
switch (result.getStatus().getStatusCode()) {
case AppStateStatusCodes.STATUS_OK:
// Data was successfully loaded from the cloud: merge with local data.
gameData = gameData.unionWith(new GameData(result.getLocalData()));
saveToCloud();
gameData.saveDataLocal(settings);
GameData tem = new GameData(result.getLocalData());
System.out.println("Game Data: "+tem);
System.out.println("Local Data: "+gameData);
progress.cancel();
break;
case AppStateStatusCodes.STATUS_STATE_KEY_NOT_FOUND:
// key not found means there is no saved data. To us, this is the same as
// having empty data, so we treat this as a success.
progress.cancel();
break;
case AppStateStatusCodes.STATUS_NETWORK_ERROR_NO_DATA:
// can't reach cloud, and we have no local state. Warn user that
// they may not see their existing progress, but any new progress won't be lost.
progress.cancel();
break;
case AppStateStatusCodes.STATUS_NETWORK_ERROR_STALE_DATA:
// can't reach cloud, but we have locally cached data.
progress.cancel();
break;
case AppStateStatusCodes.STATUS_CLIENT_RECONNECT_REQUIRED:
// need to reconnect AppStateClient
reconnectClient();
break;
default:
break;
}
}
#Override
public GameData getGameData() {
return this.gameData;
}
#Override
public void saveDataToCloud() {
saveToCloud();
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btnSinglePlayer:
getSupportFragmentManager().beginTransaction().replace( R.id.fragment_container, singlePlayerFragment ).addToBackStack( "tag" ).commit();
break;
case R.id.btnMultiplayer:
Intent selectLevelActivity = new Intent(this, MultiPlayerPlayActivity.class);
startActivity(selectLevelActivity);
break;
case R.id.btnSetting:
selectLevelActivity = new Intent(this, SettingActivity.class);
startActivity(selectLevelActivity);
break;
case R.id.btnLeaderBoard:
if (isSignedIn()) {
SharedPreferences.Editor edit = settings.edit();
edit.putInt(VERY_CURIOUS_UNLOCK, 1);
edit.commit();
unlockAchievement(R.string.achievement_very_curious,"Very Curious");
startActivityForResult(Games.Leaderboards.getAllLeaderboardsIntent(getApiClient()),RC_UNUSED);
} else {
showAlert(getString(R.string.leaderboards_not_available));
}
break;
case R.id.btnAchivement:
if (isSignedIn()) {
unlockAchievement(R.string.achievement_curious, "Curious");
startActivityForResult(Games.Achievements.getAchievementsIntent(getApiClient()),RC_UNUSED);
}else {
showAlert(getString(R.string.achievements_not_available));
}
break;
case R.id.btnHelp:
QuizCompletedForMultiPlayerDialog cdd=new QuizCompletedForMultiPlayerDialog(this);
cdd.show();
break;
}
if (v.getId() == R.id.sign_in_button) {
beginUserInitiatedSignIn();
findViewById(R.id.sign_in_button).setVisibility(View.GONE);
findViewById(R.id.sign_out_button).setVisibility(View.VISIBLE);
findViewById(R.id.sign_in_bar).setVisibility(View.GONE);
findViewById(R.id.sign_out_bar).setVisibility(View.VISIBLE);
} else if (v.getId() == R.id.sign_out_button) {
signOut();
findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE);
findViewById(R.id.sign_out_button).setVisibility(View.GONE);
findViewById(R.id.sign_out_bar).setVisibility(View.GONE);
findViewById(R.id.sign_in_bar).setVisibility(View.VISIBLE);
}
}
#Override
public void onResume() {
super.onResume();
if (adView != null) {
adView.resume();
}
}
#Override
public void onPause() {
if (adView != null) {
adView.pause();
}
super.onPause();
}
/** Called before the activity is destroyed. */
#Override
public void onDestroy() {
// Destroy the AdView.
if (adView != null) {
adView.destroy();
}
super.onDestroy();
}
class QuizCompletedForMultiPlayerDialog extends Dialog implements
android.view.View.OnClickListener {
public Activity c;
public Dialog d;
int levelStaus = 1;
int levelNo = 1;
int lastLevelScore = 0;
public QuizCompletedForMultiPlayerDialog(Activity a) {
super(a);
this.c = a;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.custom_help_dialog);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnPlayAgain:
break;
case R.id.btnQuit:
default:
break;
}
dismiss();
}
}
/**
* Display Ads after some interval of game start.
*/
private final Runnable mUpdateUITimerTask = new Runnable() {
public void run() {
displayInterstitial(true);
}
};
}
I am migrating search view Item provided in action bar using support library .Here I have done as mentioned in doc but still it is giving error while creating options menu.Please tell me where I have done wrong.Here is my code.
contacts_list_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:com.utteru.ui="http://schemas.android.com/apk/res-auto"
xmlns:yourapp="http://schemas.android.com/tools">
<!-- The search menu item. Honeycomb and above uses an ActionView or specifically a SearchView
which expands within the Action Bar directly. Note the initial collapsed state set using
collapseActionView in the showAsAction attribute. -->
<group
android:id="#+id/main_menu_group">
<item
android:id="#+id/menu_search"
android:actionViewClass="android.widget.SearchView"
android:icon="#drawable/ic_action_search"
yourapp:showAsAction="ifRoom|collapseActionView"
yourapp:actionViewClass="android.support.v7.widget.SearchView"
android:title="#string/menu_search" />
</group>
<group
android:id="#+id/refresh_group">
<item
android:id="#+id/refresh"
android:icon="#android:drawable/ic_popup_sync"
yourapp:showAsAction="ifRoom|collapseActionView"
yourapp:actionViewClass="android.support.v7.widget.SearchView"
android:title="#string/menu_search" />
</group>
</menu>
ContactsListFragment.java
import android.accounts.Account;
import android.app.SearchManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Contacts.Photo;
import android.support.v4.BuildConfig;
import android.support.v4.app.ListFragment;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.SearchView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class ContactsListFragment extends ListFragment {
private static final String TAG = "ContactsAccessFragment";
private static final String STATE_PREVIOUSLY_SELECTED_KEY =
"com.Utteru.ui.SELECTED_ITEM";
ArrayList<AccessContactDto> allcontacts;
ArrayList<AccessContactDto> databasecontacts;
TextView textempty;
public Context mContext;
private AccessContactAdapter mAdapter;
private ImageLoader mImageLoader; // Handles loading the contact image in a background thread
// Stores the previously selected search item so that on a configuration change the same item
// can be reselected again
private int mPreviouslySelectedSearchItem = 0;
// Whether or not the search query has changed since the last time the loader was refreshed
private boolean mSearchQueryChanged;
// Whether or not this fragment is showing in a two-pane layout
private boolean mIsTwoPaneLayout;
// Whether or not this is a search result view of this fragment, only used on pre-honeycomb
// OS versions as search results are shown in-line via Action Bar search from honeycomb onward
private boolean mIsSearchResultView = false;
/**
* Fragments require an empty constructor.
*/
public ContactsListFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mIsTwoPaneLayout = getResources().getBoolean(R.bool.has_two_panes);
getActivity().setTitle("");
if (savedInstanceState != null) {
// If we're restoring state after this fragment was recreated then
// retrieve previous search term and previously selected search
// result.
mPreviouslySelectedSearchItem =
savedInstanceState.getInt(STATE_PREVIOUSLY_SELECTED_KEY, 0);
}
mImageLoader = new ImageLoader(getActivity(), CommonUtility.getListPreferredItemHeight(getActivity())) {
#Override
protected Bitmap processBitmap(Object data) {
// This gets called in a background thread and passed the data from
// ImageLoader.loadImage().
return loadContactPhotoThumbnail((String) data, getImageSize());
}
};
// Set a placeholder loading image for the image loader
mImageLoader.setLoadingImage(R.drawable.ic_contact_picture_holo_light);
// Add a cache to the image loader
mImageLoader.addImageCache(getActivity().getSupportFragmentManager(), 0.1f);
mContext = getActivity().getBaseContext();
new loadData().execute();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the list fragment layout
View all_contacts_view = inflater.inflate(R.layout.contact_list_fragment, container, false);
textempty = (TextView)all_contacts_view.findViewById(android.R.id.empty);
textempty.setText("No contacts found");
return all_contacts_view;
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
AccessContactDto cdto = (AccessContactDto) l.getItemAtPosition(position);
Log.e("number on click",""+cdto.getMobile_number());
cdto=UserService.getUserServiceInstance(mContext).getAccessConDataByNumber(cdto.getMobile_number());
if(cdto==null)
cdto = (AccessContactDto) l.getItemAtPosition(position);
else
Log.e("mumber not mull from db","number not null from db");
Intent detailsActivity = new Intent(mContext, ContactDetailActivity.class);
detailsActivity.putExtra("selected_con", cdto);
startActivity(detailsActivity);
getActivity().overridePendingTransition(R.anim.animation1, R.anim.animation2);
super.onListItemClick(l, v, position, id);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Let this fragment contribute menu items
setHasOptionsMenu(true);
// Set up ListView, assign adapter and set some listeners. The adapter was previously
// created in onCreate().
setListAdapter(mAdapter);
getListView().setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView absListView, int scrollState) {
// Pause image loader to ensure smoother scrolling when flinging
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
mImageLoader.setPauseWork(true);
} else {
mImageLoader.setPauseWork(false);
}
}
#Override
public void onScroll(AbsListView absListView, int i, int i1, int i2) {
}
});
if (mIsTwoPaneLayout) {
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
}
if (mPreviouslySelectedSearchItem == 0) {
}
}
#Override
public void onPause() {
super.onPause();
mImageLoader.setPauseWork(false);
}
#Override
public void onPrepareOptionsMenu(Menu menu) {
menu.clear();
getActivity().getMenuInflater().inflate(R.menu.contact_list_menu, menu);
MenuItem searchItem = menu.findItem(R.id.menu_search);
menu.setGroupVisible(R.id.main_menu_group, true);
if (mIsSearchResultView) {
searchItem.setVisible(false);
}
if (Utils.hasHoneycomb()) {
final SearchManager searchManager =
(SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getActivity().getComponentName()));
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String queryText) {
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
Log.e("on query text change ","on query text change");
if (newText != null && !newText.equals(""))
{
ArrayList<AccessContactDto> filterList = new ArrayList<AccessContactDto>();
for (AccessContactDto a : allcontacts) {
if (a.getDisplay_name().toLowerCase().startsWith(newText.toLowerCase())) {
filterList.add(a);
continue;
}
getListView().setAdapter(new AccessContactAdapter(filterList, getActivity(), mImageLoader));
}
return true;
}
else{
getListView().setAdapter(new AccessContactAdapter(allcontacts, getActivity(), mImageLoader));
return true;
}
}
});
}
super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_search:
if (!Utils.hasHoneycomb()) {
getActivity().onSearchRequested();
}
break;
case R.id.refresh:
if (CommonUtility.isNetworkAvailable(getActivity())) {
final Account account = new Account(Constants.ACCOUNT_NAME, Constants.ACCOUNT_TYPE);
Bundle bundle = new Bundle();
bundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
ContentResolver.requestSync(account, ContactsContract.AUTHORITY, bundle);
mAdapter.notifyDataSetChanged();
// new CountDownTimer(5000, 1000) {
// #Override
// public void onTick(long millisUntilFinished) {
// }
//
// #Override
// public void onFinish() {
//
// }
// }.start();
} else {
Toast.makeText(getActivity(), "Internet Connection Required!!", Toast.LENGTH_SHORT).show();
}
break;
}
return super.onOptionsItemSelected(item);
}
private Bitmap loadContactPhotoThumbnail(String photoData, int imageSize) {
if (!isAdded() || getActivity() == null) {
return null;
}
AssetFileDescriptor afd = null;
try {
Uri thumbUri;
if (Utils.hasHoneycomb()) {
thumbUri = Uri.parse(photoData);
} else {
final Uri contactUri = Uri.withAppendedPath(Contacts.CONTENT_URI, photoData);
thumbUri = Uri.withAppendedPath(contactUri, Photo.CONTENT_DIRECTORY);
}
afd = getActivity().getContentResolver().openAssetFileDescriptor(thumbUri, "r");
FileDescriptor fileDescriptor = afd.getFileDescriptor();
if (fileDescriptor != null) {
return ImageLoader.decodeSampledBitmapFromDescriptor(
fileDescriptor, imageSize, imageSize);
}
} catch (FileNotFoundException e) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "Contact photo thumbnail not found for contact " + photoData
+ ": " + e.toString());
}
} finally {
if (afd != null) {
try {
afd.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
public ArrayList<AccessContactDto> readContactsNew() {
ArrayList<AccessContactDto> list = new ArrayList<AccessContactDto>();
AccessContactDto adto;
Cursor phones = mContext.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
while (phones.moveToNext())
{
String name=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String photouri= phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
String contact_id= phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID));
Uri con_uri= Contacts.getLookupUri(phones.getLong(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID)), phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY)));
adto = new AccessContactDto(contact_id, name, null, phoneNumber, null, photouri, con_uri.toString(),null,null,null);
list.add(adto);
}
phones.close();
return list;
}
public class loadData extends AsyncTask<Void, Void, Void>
{
#Override
protected void onPostExecute(Void aVoid) {
mAdapter = new AccessContactAdapter(allcontacts, getActivity(), mImageLoader);
if(getActivity()!=null)
getListView().setAdapter(mAdapter);
super.onPostExecute(aVoid);
}
#Override
protected Void doInBackground(Void... params) {
allcontacts = readContactsNew();
// databasecontacts = UserService.getUserServiceInstance(mContext).getAllAccessContacts();
// allcontacts.removeAll(databasecontacts);
// allcontacts.addAll(databasecontacts);
Collections.sort(allcontacts, new Comparator<AccessContactDto>() {
#Override
public int compare(AccessContactDto lhs, AccessContactDto rhs) {
return lhs.getDisplay_name().compareToIgnoreCase(rhs.getDisplay_name());
}
});
return null;
}
}
}
ContactsListActivity.java
import android.accounts.AccountManager;
import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.PagerTabStrip;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import com.viewpagerindicator.IconPagerAdapter;
public class ContactsListActivity extends ActionBarActivity {
DemoCollectionPagerAdapter mDemoCollectionPagerAdapter;
ViewPager mViewPager;
private ContactDetailFragment mContactDetailFragment;
private boolean isTwoPaneLayout;
AccountManager mAccountManager;
Boolean checkAccount;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDemoCollectionPagerAdapter = new DemoCollectionPagerAdapter(getSupportFragmentManager());
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(R.color.purple));
getSupportActionBar().setIcon(new ColorDrawable(getResources().getColor(android.R.color.transparent)));
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mDemoCollectionPagerAdapter);
isTwoPaneLayout = getResources().getBoolean(R.bool.has_two_panes);
PagerTabStrip pagerTabStrip = (PagerTabStrip) findViewById(R.id.pager_title_strip);
pagerTabStrip.setTextSpacing(0);
pagerTabStrip.setPadding(0, 0, 0, 10);
pagerTabStrip.setTextSize(1, 20);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.remove("android:support:fragments");
}
#Override
public void onBackPressed() {
startActivity(new Intent(ContactsListActivity.this, MenuScreen.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK));
this.finish();
overridePendingTransition(R.anim.card_rotate_in, R.anim.card_rotate_out);
}
#Override
protected void onDestroy() {
if(CommonUtility.dialog!=null){
CommonUtility.dialog.dismiss();
}
super.onDestroy();
}
#Override
public boolean onSearchRequested() {
boolean isSearchResultView = false;
return !isSearchResultView && super.onSearchRequested();
}
public static class DemoCollectionPagerAdapter extends FragmentPagerAdapter implements IconPagerAdapter {
protected static final String[] CONTENT = new String[]{"All Contacts", "Access Contacts"};
protected final int[] ICONS = new int[]{
R.drawable.all_contact,
R.drawable.access_contacts
};
private int mCount = CONTENT.length;
public DemoCollectionPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
// All Contacts Fragment
return new ContactsListFragment();
case 1:
// Access Contacts Fragment
return new ContactsAccessFragment();
}
return null;
}
#Override
public CharSequence getPageTitle(int position) {
return DemoCollectionPagerAdapter.CONTENT[position % CONTENT.length];
}
#Override
public int getIconResId(int index) {
return ICONS[index % ICONS.length];
}
#Override
public int getCount() {
return mCount;
}
public void setCount(int count) {
if (count > 0 && count <= 10) {
mCount = count;
notifyDataSetChanged();
}
}
}
}
Error Log:
java.lang.NullPointerException
at com.hello.ContactsListFragment.onPrepareOptionsMenu(ContactsListFragment.java:236)
at android.support.v4.app.Fragment.performPrepareOptionsMenu(Fragment.java:1882)
at android.support.v4.app.FragmentManagerImpl.dispatchPrepareOptionsMenu(FragmentManager.java:2020)
at android.support.v4.app.FragmentActivity.onPreparePanel(FragmentActivity.java:459)
at android.support.v7.app.ActionBarActivity.superOnPreparePanel(ActionBarActivity.java:280)
at android.support.v7.app.ActionBarActivityDelegate$1.onPreparePanel(ActionBarActivityDelegate.java:84)
at android.support.v7.app.ActionBarActivityDelegateBase.preparePanel(ActionBarActivityDelegateBase.java:1006)
at android.support.v7.app.ActionBarActivityDelegateBase.doInvalidatePanelMenu(ActionBarActivityDelegateBase.java:1182)
at android.support.v7.app.ActionBarActivityDelegateBase.access$100(ActionBarActivityDelegateBase.java:79)
at android.support.v7.app.ActionBarActivityDelegateBase$1.run(ActionBarActivityDelegateBase.java:115)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:155)
at android.app.ActivityThread.main(ActivityThread.java:5520)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1029)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:796)
at dalvik.system.NativeStart.main(Native Method)
Actually i try to do parse simple XML containing some details using SAX parser and display the result in Spinner. But i con't identify the what is the problem in my problem i mean may be it will be syntax error or my program was not correct. can anyone help me to fix this issues.
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<Spinner
android:id="#+id/spinner1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="178dp" />
<Button
android:id="#+id/button1"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/spinner1"
android:layout_alignParentTop="true"
android:layout_alignRight="#+id/spinner1"
android:layout_marginTop="17dp"
android:text="Parse XML using SAX" />
</RelativeLayout>
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/title"
style="#style/spinner" />
styles.xml
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme" parent="#android:style/android:Theme" />
<style name="spinner">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">fill_parent</item>
<item name="android:textColor">#0000CD</item>
<item name="android:text">15dp</item>
<item name="android:typeface">monospace</item>
<item name="android:maxHeight">35dp</item>
<item name="android:paddingTop">5dp</item>
<item name="android:paddingBottom">8dp</item>
</style>
</resources>
Mainactivity.class
public abstract class MainActivity extends Activity implements OnClickListener,OnItemSelectedListener {
Button button;
Spinner spinner;
List<Item> item = null;
static final String URL = "http://www.androidituts.com/source/tutorials.xml";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById();
button.setOnClickListener(this);
}
private void findViewById() {
// TODO Auto-generated method stub
button = (Button) findViewById(R.id.button1);
spinner = (Spinner) findViewById(R.id.spinner1);
}
public void onClick(View v) {
item = SAXXMLParser.parse(URL);
ArrayAdapter<Item> adapter = new ArrayAdapter<Item>(this,
R.layout.list_item, item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(this);
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int pos,
long id) {
Item item = (Item) parent.getItemAtPosition(pos);
Toast.makeText(parent.getContext(), item.getDetails(),
Toast.LENGTH_LONG).show();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
}
}
Item.java
public class Item {
private String name;
private int id;
private String category;
private String published;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void setcategory(String category) {
this.category = category;
}
public String getcategory() {
return category;
}
public void setpublished(String published) {
this.published = published;
}
public String getpublished() {
return published;
}
public String getDetails() {
// TODO Auto-generated method stub
String result = id + ": " + name + "\n" + category + "-" + published;
return result;
}
}
SAXXMLParser.java
public class SAXXMLParser {
public static List<Item> parse(String URL) {
List<Item> menu=null;
try {
// create a XMLReader from SAXParser
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser()
.getXMLReader();
// create a SAXXMLHandler
SAXXMLHandler saxHandler = new SAXXMLHandler();
// store handler in XMLReader
xmlReader.setContentHandler(saxHandler);
// the process starts
xmlReader.parse(URL);
// get the `Employee list`
menu = saxHandler.getmenu();
} catch (Exception ex) {
Log.d("XML", "SAXXMLParser: parse() failed");
}
// return Employee list
return menu;
}
}
SAXXMLHandler.java
public class SAXXMLHandler extends DefaultHandler {
private List<Item> menu;
private String tempVal;
private Item tempEmp;
public SAXXMLHandler() {
menu = new ArrayList<Item>();
}
public List<Item> getmenu() {
return menu;
}
// Event Handlers
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// reset
tempVal = "";
if (qName.equalsIgnoreCase("item")) {
// create a new instance of employee
tempEmp = new Item();
}
}
public void characters(char[] ch, int start, int length)
throws SAXException {
tempVal = new String(ch, start, length);
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (qName.equalsIgnoreCase("item")) {
// add it to the list
menu.add(tempEmp);
} else if (qName.equalsIgnoreCase("id")) {
tempEmp.setId(Integer.parseInt(tempVal));
} else if (qName.equalsIgnoreCase("name")) {
tempEmp.setName(tempVal);
} else if (qName.equalsIgnoreCase("category")) {
tempEmp.setcategory(tempVal);
} else if (qName.equalsIgnoreCase("published")) {
tempEmp.setpublished(tempVal);
}
}
}
Android manifesto.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.xmlspinner"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.xmlspinner.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
logcat detail
http://i.stack.imgur.com/BpNKV.jpg
I have done changes in codes try below codes...
import java.net.URL;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.Toast;
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
#SuppressLint("NewApi")
public class XMLParsingDOMExample extends Activity implements AdapterView.OnItemSelectedListener {
ArrayList<String> title;
Button button;
Spinner spinner;
ArrayAdapter<String> from_adapter;
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
title = new ArrayList<String>();
button = (Button) findViewById(R.id.button1);
spinner = (Spinner) findViewById(R.id.spinner1);
spinner.setOnItemSelectedListener(this);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
button.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
parse();
from_adapter=new ArrayAdapter<String>(getBaseContext(),android.R.layout.simple_spinner_item, title);
from_adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(from_adapter);
}
});
}
public void onItemSelected(AdapterView<?> parent, View view, int pos,
long id) {
Toast.makeText(parent.getContext(), ""+spinner.getSelectedItem().toString().trim(),
Toast.LENGTH_LONG).show();
}
public void onNothingSelected(AdapterView<?> arg0) {
}
protected void parse() {
// TODO Auto-generated method stub
try {
URL url = new URL(
"http://www.androidituts.com/source/tutorials.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(url.openStream()));
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getElementsByTagName("item");
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
Element fstElmnt = (Element) node;
NodeList nameList = fstElmnt.getElementsByTagName("id");
Element nameElement = (Element) nameList.item(0);
nameList = nameElement.getChildNodes();
NodeList websiteList = fstElmnt.getElementsByTagName("name");
Element websiteElement = (Element) websiteList.item(0);
websiteList = websiteElement.getChildNodes();
NodeList websiteList1 = fstElmnt.getElementsByTagName("category");
Element websiteElement1 = (Element) websiteList1.item(0);
websiteList1 = websiteElement1.getChildNodes();
NodeList websiteList2 = fstElmnt.getElementsByTagName("published");
Element websiteElement2 = (Element) websiteList2.item(0);
websiteList2 = websiteElement2.getChildNodes();
title.add(((Node) nameList.item(0)).getNodeValue()+":"+((Node) websiteList.item(0)).getNodeValue() +"\n"+((Node) websiteList1.item(0)).getNodeValue()+"-"+((Node) websiteList2.item(0)).getNodeValue());
}
} catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
}
}
Now you can get all the details in that spinner...
You can't Performing Network Operations ON GUI thread so you have to create a thread to fitch and parse data from URL.
public void onClick(View v) {
new Thread(new Runnable() {
#Override
public void run() {
item = SAXXMLParser.parse(URL);
spinhandler.sendEmptyMessage(0);
}
}).start();
}
Create Handler
private Handler spinhandler = new Handler() {
#Override
public void handleMessage(Message msg) {
if(msg.what == 0) {
ArrayAdapter<Item> adapter = new ArrayAdapter<Item>(MainActivity.this, R.layout.list_item, item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(MainActivity.this);
}
}
};
When try to put data in Item Object the Item object equal null so you have to intialize the object before start access it
if (qName.equalsIgnoreCase("id")) {
tempEmp = new Item();
tempEmp.setId(Integer.parseInt(tempVal));
}
I followed a simple tutorial (http://www.cse.nd.edu/courses/cse40814/www/RSS_Android.pdf) to read RSS feed from a given URL into a listView. I have added the INTERNET permission and the code is error free in Eclipse but it will not show any RSS feed when launched on a device or emulator. I can't make the code anymore simpler, and the feed I am using is stable feed from www.nba.com : http://www.nba.com/rss/nba_rss.xml though i have tested it on several RSS feeds and with still no feed showing.
Any ideas guys?
Main.java
package com.android.simplerssreader;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.android.simplerssreader.data.RssItem;
import com.android.simplerssreader.util.RssReader;
public class Main extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
RssReader rssReader = new RssReader(
"http://www.nba.com/rss/nba_rss.xml");
ListView Items = (ListView) findViewById(R.id.listView1);
ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(this,
android.R.layout.simple_list_item_1, rssReader.getItems());
Items.setAdapter(adapter);
Items.setOnItemClickListener(new ListListener(rssReader.getItems(),
this));
} catch (Exception e) {
Log.e("SimpleRssReader", e.getMessage());
}
}
}
ListListener.java
package com.android.simplerssreader;
import java.util.List;
import com.android.simplerssreader.data.RssItem;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
public class ListListener implements OnItemClickListener {
List<RssItem> listItems;
Activity activity;
public ListListener(List<RssItem> listItems, Activity activity) {
this.listItems = listItems;
this.activity = activity;
}
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(listItems.get(pos).getLink()));
activity.startActivity(i);
}
}
RssItem.java
package com.android.simplerssreader.data;
public class RssItem {
private String title;
private String link;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
}
RssParseHandler.java
package com.android.simplerssreader.util;
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.android.simplerssreader.data.RssItem;
public class RssParseHandler extends DefaultHandler {
private List<RssItem> rssItems;
private RssItem currentItem;
private boolean parsingTitle;
private boolean parsingLink;
public RssParseHandler() {
rssItems = new ArrayList<RssItem>();
}
public List<RssItem> getItems() {
return rssItems;
}
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if ("content-item".equals(qName)) {
currentItem = new RssItem();
} else if ("title".equals(qName)) {
parsingTitle = true;
} else if ("url".equals(qName)) {
parsingLink = true;
}
}
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if ("content-item".equals(qName)) {
rssItems.add(currentItem);
currentItem = null;
} else if ("title".equals(qName)) {
parsingTitle = false;
} else if ("url".equals(qName)) {
parsingLink = false;
}
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (parsingTitle) {
if (currentItem != null)
currentItem.setTitle(new String(ch, start, length));
} else if (parsingLink) {
if (currentItem != null) {
currentItem.setLink(new String(ch, start, length));
parsingLink = false;
}
}
}
}
RssReader.java
package com.android.simplerssreader.util;
import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import com.android.simplerssreader.data.RssItem;
public class RssReader {
private String rssUrl;
public RssReader(String rssUrl) {
this.rssUrl = rssUrl;
}
public List<RssItem> getItems() throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
RssParseHandler handler = new RssParseHandler();
saxParser.parse(rssUrl, handler);
return handler.getItems();
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000000"
android:orientation="vertical" >
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:cacheColorHint="#FFA500"
android:scrollingCache="false"
android:textColor="#ADD8E6" >
</ListView>
</LinearLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.simplerssreader"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="16" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.android.simplerssreader.Main"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
LogCat
01-04 16:22:16.171: E/SimpleRssReader(8685): Couldn't open http://www.nba.com/rss/nba_rss.xml
replace
Log.e("SimpleRssReader", e.getMessage());
with
Log.e("SimpleRssReader", e.getMessage(), e);
you lose the stack trace information.
BTW, your error is that you can't access the network in Android when you are inside the UI Thread (after HoneyComb) : How to fix android.os.NetworkOnMainThreadException?