Android YouTubeSupportFragment player returning null - java

I have been working on a personal Android project related to YouTube based off a demo, however I have ran into an issue that I can't seem to figure out (or understand).
The original code uses a basic PlayerView whereas this uses a YouTubePlayerSupportFragment.
The app plays videos just fine as long as player.cueVideo("VIDEOID") is inside onInitializationSuccess. But will crash with a NullPointerException on player variable if placed inside the method playVideoAtSelection.
** The original code had the following line inside onInitializationSuccess, however for me it's telling me that player cannot be resolved. **
I've never seen this used like this before so it has been throwing me off.
this.player = player;
MainActivity.java code:
public class MainActivity extends FragmentActivity implements
AdapterView.OnItemClickListener,
AdapterView.OnItemSelectedListener {
private final String LOG_TAG = MainActivity.class.getSimpleName();
AutoCompleteTextView atvSearch;
public String thumbnailURL;
public String mediaTitle;
public String videoID;
private TextView autoItem;
private ImageView autoImage;
private ArrayList<ArrayList<String>> resultList;
private static final String KEY_CURRENTLY_SELECTED_ID = "currentlySelectedId";
private YouTubePlayer mPlayer;
private YouTubePlayer player = null;
private ArrayAdapter<ListEntry> videoAdapter;
private Spinner videoChooser;
private MyPlayerStateChangeListener playerStateChangeListener;
private int currentlySelectedPosition;
private String currentlySelectedId;
private static final ListEntry[] ENTRIES = {
new ListEntry("Androidify App", "irH3OSOskcE", false),
new ListEntry("Chrome Speed Tests", "nCgQDjiotG0", false),
new ListEntry("Playlist: Google I/O 2012", "PL56D792A831D0C362", true)};
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.v(LOG_TAG, "IN onCreate!");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_playlist, new PlaylistFragment())
.commit();
}
//YouTubePlayerFragment playerFragment = YouTubePlayerFragment.newInstance("irH3OSOskcE");
//getSupportFragmentManager().beginTransaction().replace(R.id.youtube_fragment, playerFragment).commit();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
YouTubePlayerSupportFragment youTubePlayerFragment = new YouTubePlayerSupportFragment();
fragmentTransaction.add(R.id.youtube_fragment, youTubePlayerFragment);
fragmentTransaction.commit();
youTubePlayerFragment.initialize(DeveloperKey.DEVELOPER_KEY, new OnInitializedListener() {
#Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasRestored) {
mPlayer = player;
mPlayer.setPlayerStateChangeListener(playerStateChangeListener);
mPlayer.setPlayerStyle(YouTubePlayer.PlayerStyle.MINIMAL);
if (!wasRestored) {
playVideoAtSelection();
}
}
#Override
public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {
//error
}
});
AutoCompleteTextView autoCompView = (AutoCompleteTextView) findViewById(R.id.atv_search);
autoCompView.setAdapter(new QueryAutoCompleteAdapter(this, R.layout.list_item));
autoCompView.setOnItemClickListener(this);
playerStateChangeListener = new MyPlayerStateChangeListener();
videoChooser = (Spinner) findViewById(R.id.video_chooser);
videoAdapter = new ArrayAdapter<ListEntry>(this, android.R.layout.simple_spinner_item, ENTRIES);
videoAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
videoChooser.setOnItemSelectedListener(this);
videoChooser.setAdapter(videoAdapter);
}
public void playVideoAtSelection() {
if (mPlayer == null) {
Log.v(LOG_TAG, "WE DUN GOOFD PLAYER IS NULL... ");
}
player.cueVideo("nCgQDjiotG0");
Log.v(LOG_TAG, "WE HAVE ENTERED PLAYVIDEOATSELECTION... ");
/*ListEntry selectedEntry = videoAdapter.getItem(currentlySelectedPosition);
if (selectedEntry.id != currentlySelectedId && player != null) {
currentlySelectedId = selectedEntry.id;
if (selectedEntry.isPlaylist) {
player.cuePlaylist(selectedEntry.id);
} else {
player.cueVideo(selectedEntry.id);
}
}*/
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
currentlySelectedPosition = pos;
playVideoAtSelection();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
// Do nothing.
}
#Override
protected void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
state.putString(KEY_CURRENTLY_SELECTED_ID, currentlySelectedId);
}
#Override
protected void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
currentlySelectedId = state.getString(KEY_CURRENTLY_SELECTED_ID);
}
private final class MyPlayerStateChangeListener implements YouTubePlayer.PlayerStateChangeListener {
String playerState = "UNINITIALIZED";
#Override
public void onLoading() {
playerState = "LOADING";
}
#Override
public void onLoaded(String videoId) {
playerState = String.format("LOADED %s", videoId);
}
#Override
public void onAdStarted() {
playerState = "AD_STARTED";
}
#Override
public void onVideoStarted() {
playerState = "VIDEO_STARTED";
}
#Override
public void onVideoEnded() {
playerState = "VIDEO_ENDED";
}
#Override
public void onError(YouTubePlayer.ErrorReason reason) {
playerState = "ERROR (" + reason + ")";
if (reason == YouTubePlayer.ErrorReason.UNEXPECTED_SERVICE_DISCONNECTION) {
// When this error occurs the player is released and can no longer be used.
player = null;
//setControlsEnabled(false);
}
}
}
private static final class ListEntry {
public final String title;
public final String id;
public final boolean isPlaylist;
public ListEntry(String title, String videoId, boolean isPlaylist) {
this.title = title;
this.id = videoId;
this.isPlaylist = isPlaylist;
}
#Override
public String toString() {
return title;
}
}
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
String str = (String) adapterView.getItemAtPosition(position);
Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
}
public class QueryAutoCompleteAdapter extends ArrayAdapter<String> implements Filterable {
public QueryAutoCompleteAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}
#Override
public int getCount() {
return resultList.size();
}
#Override
public String getItem(int index) {
return resultList.get(index).toString();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
LayoutInflater inflater = LayoutInflater.from(getContext());
if (row == null) {
row = inflater.inflate(R.layout.list_item_query, parent, false);
}
ArrayList<String> text = resultList.get(position);
String title = text.get(2);
String url = text.get(1);
videoID = text.get(0);
Log.v(LOG_TAG, "YOOOOOO BAIIII: " + title + url);
autoItem = (TextView) row.findViewById(R.id.list_item_title);
autoImage = (ImageView) row.findViewById(R.id.list_item_thumbnail);
autoItem.setText(title);
Bitmap bm = null;
try {
InputStream in = new java.net.URL(url).openStream();
bm = BitmapFactory.decodeStream(in);
} catch (Exception e) {
//Log.e("ERROR", e.getMessage());
e.printStackTrace();
}
autoImage.setImageBitmap(bm);
return row;
}
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
// Constraint is the input given by the user
if (constraint != null) {
// Retrieve the autocomplete results.
resultList = autocomplete(constraint.toString());
int size = resultList.size();
for (int i=0; i<size; i++) {
//temp = resultList.get(i);
Log.v(LOG_TAG, "YOOOOOO: " + resultList.get(i));
thumbnailURL = resultList.get(i).get(1);
mediaTitle = resultList.get(i).get(2);
}
Log.v(LOG_TAG, "YOOOOOO: " + thumbnailURL + " " + mediaTitle);
// Assign the data to the FilterResults
filterResults.values = resultList;
filterResults.count = resultList.size();
}
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
notifyDataSetChanged();
}
else {
notifyDataSetInvalidated();
}
}};
return filter;
}
}
private ArrayList<ArrayList<String>> autocomplete(String input) {
ArrayList<ArrayList<String>> queries = null;
// If there's no query, there is nothing to look up
if (input.length() == 0) {
return null;
}
String songQuery = input;
// These two need to be declared outside the try/catch
// so that they can be closed in the finally block.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String queryJsonStr = null;
String part = "id,snippet";
String order = "relevance";
String q = songQuery;
String type = "video";
String categoryID = "kind";
String key = DeveloperKey.DEVELOPER_KEY;
try {
// Construct the URL for the query
final String BASE_URL = "https://www.googleapis.com/youtube/v3/search?";
final String PART_PARAM = "part";
final String ORDER_PARAM = "order";
final String QUERY_PARAM = "q";
final String TYPE_PARAM = "type";
final String CATEGORYID_PARAM = "videoCategoryId";
final String KEY_PARAM = "key";
Uri builtUri = Uri.parse(BASE_URL).buildUpon()
.appendQueryParameter(PART_PARAM, part)
.appendQueryParameter(ORDER_PARAM, order)
.appendQueryParameter(QUERY_PARAM, q)
.appendQueryParameter(TYPE_PARAM, type)
.appendQueryParameter(CATEGORYID_PARAM, categoryID)
.appendQueryParameter(KEY_PARAM, key)
.build();
URL url = new URL(builtUri.toString());
Log.v(LOG_TAG, "BUILT URI: " + builtUri.toString());
// Create the request to YouTube, and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
// But it does make debugging a *lot* easier if you print out the completed
// buffer for debugging.
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
queryJsonStr = buffer.toString();
Log.v(LOG_TAG, "Query JSON String: " + queryJsonStr);
} catch (IOException e) {
Log.e(LOG_TAG, "ERROR ", e);
// If the code didn't successfully get the weather data, there's no point in attempting
// to parse it.
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("PlaceholderFragment", "Error closing stream", e);
}
}
}
try {
JSONObject jsonObject = new JSONObject(queryJsonStr);
QueryJSONParser queryJSONParser = new QueryJSONParser();
// Getting the parsed data as a list construct
queries = queryJSONParser.parse(jsonObject);
} catch (Exception e) {
Log.d("Exception", e.toString());
}
return queries;
}
#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;
}
#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();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Relevant XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<fragment
android:name="com.google.android.youtube.player.YouTubePlayerSupportFragment"
android:id="#+id/youtube_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:orientation="horizontal"
android:gravity="top">
<include
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
layout="#layout/player_controls_container" />
</LinearLayout>
Any help would be greatly appreciated!
LOGCAT:
08-08 19:52:23.404 6040-6040/com.android.youtube V/MainActivity﹕ WE DUN GOOFD PLAYER IS NULL...
08-08 19:52:23.404 6040-6040/com.android.youtube D/AndroidRuntime﹕ Shutting down VM
08-08 19:52:23.404 6040-6040/com.android.youtube W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x41894da0)
08-08 19:52:23.414 6040-6040/com.android.youtube E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.android.youtube, PID: 6040
java.lang.NullPointerException
at com.android.youtube.MainActivity.playVideoAtSelection(MainActivity.java:132)
at com.android.youtube.MainActivity.onItemSelected(MainActivity.java:148)

You are getting NullPointerException because your player variable is not initialized. You have commented this line:
this.player = player;
And for the question what is this.player = player?
this refers to the current object
For example:
public class myClass{
int x;
public myClass(int x){
this.x = x;
}
}
In the above example, you have used this because, you want to assign value of x to the x(attribute of myClass).
PS: If you are confused with this you can easily do the following:
Change your variable name to something else, may be mPlayer
and change
this.player = player to mPlayer = player;
Edited:
You have declared the YouTubePlayer outside the class. Move it inside i.e. Before overriding onCreate(..) method.
Updated:
Since the player is not attribute of the class, it won't know what it is. This is similar to not declaring any variable.

Related

Showing list of elements in recyclerView failed

I am trying to make a news app, data obtained from RSS feed. I get xml response from the feed. And I am using XmlPullParser to parse the xml. The parsing is a success. I can see the values in my log.
But somehow I am not able to fill them in my recyclerView. It's all just blank. My java class is:
public class RssNewsActivity extends AppCompatActivity {
private static final String TAG = RssNewsActivity.class.toString();
RssFeedAdapter adapter;
RecyclerView recyclerView_rssFeed;
SwipeRefreshLayout swipeRefreshLayout;
private List<RssModel> listResponseModel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rss_news);
initialize();
recyclerView_rssFeed.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView_rssFeed.setLayoutManager(linearLayoutManager);
adapter = new RssFeedAdapter(RssNewsActivity.this, listResponseModel);
recyclerView_rssFeed.setAdapter(adapter);
fetchNewsFeed();
//if user swipes the recycler then refresh content page
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
fetchNewsFeed();
}
});
}
private void initialize() {
swipeRefreshLayout = findViewById(R.id.swipeRefresh_rssFeed);
recyclerView_rssFeed = findViewById(R.id.recyclerView_rssFeed);
listResponseModel = new ArrayList<>();
}
private void fetchNewsFeed() {
String url = "here is my news feed url";
StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
listResponseModel.clear();
try {
listResponseModel = parseNewsFeed(response);
} catch (XmlPullParserException | IOException e) {
Log.e(TAG, e.getMessage());
}
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue queue = Volley.newRequestQueue(this);
queue.add(request);
}
private List<RssModel> parseNewsFeed(String response) throws XmlPullParserException,
IOException {
XmlPullParserFactory parserFactory = XmlPullParserFactory.newInstance();
parserFactory.setNamespaceAware(true);
XmlPullParser xmlPullParser = parserFactory.newPullParser();
xmlPullParser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
xmlPullParser.setInput(new StringReader(response));
return processParsing(xmlPullParser);
}
private List<RssModel> processParsing(XmlPullParser xmlPullParser) throws IOException, XmlPullParserException {
List<RssModel> listRssFeed = new ArrayList<>();
int eventType = xmlPullParser.getEventType();
RssModel rssModel = null;
xmlPullParser.nextTag();
while (eventType != XmlPullParser.END_DOCUMENT) {
String eltName;
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
break;
case XmlPullParser.START_TAG:
eltName = xmlPullParser.getName();
if ("item".equals(eltName)) {
rssModel = new RssModel();
} else if (rssModel != null) {
if ("title".equals(eltName)) {
String title = xmlPullParser.nextText();
rssModel.setTitle(title);
Log.d(TAG, "title: " + title);
} else if ("link".equals(eltName)) {
String link = xmlPullParser.nextText();
rssModel.setLink(link);
Log.d(TAG, "link: " + link);
}
}
break;
case XmlPullParser.END_TAG:
eltName = xmlPullParser.getName();
if ("item".equals(eltName) && rssModel != null) {
listRssFeed.add(rssModel);
}
break;
}
eventType = xmlPullParser.next();
}
return listRssFeed;
}
}
my xml design is:
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context="rssnewsfeed.RssNewsActivity">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipeRefresh_rssFeed"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView_rssFeed"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
This is my adapter class
public class RssFeedAdapter extends RecyclerView.Adapter<RssFeedAdapter.RssViewHolder> {
private Context mContext;
private List<RssModel> mRssFeeds;
public RssFeedAdapter(Context mContext, List<RssModel> mRssFeeds) {
this.mContext = mContext;
this.mRssFeeds = mRssFeeds;
}
#NonNull
#Override
public RssViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(mContext).inflate(R.layout.rss_feed_layout, viewGroup, false);
return new RssViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull RssViewHolder rssViewHolder, int i) {
RssModel post = mRssFeeds.get(i);
rssViewHolder.textView_title.setText(post.getTitle());
rssViewHolder.textView_link.setText(post.getLink());
}
#Override
public int getItemCount() {
return mRssFeeds.size();
}
public class RssViewHolder extends RecyclerView.ViewHolder {
private TextView textView_title, textView_link;
public RssViewHolder(#NonNull View itemView) {
super(itemView);
textView_title = itemView.findViewById(R.id.textView_title);
textView_link = itemView.findViewById(R.id.textView_link);
}
}
}
And finally this is my model class:
public class RssModel {
private String title;
private String link;
public RssModel() {
}
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;
}
}
I tried many ways but no success. I don't know what I am missing. I will be grateful for any guidance. Thanks.
Giving " = " will create a new instance of ArrayList apart from which is already binded to RecyclerView adapter.
So, you need to change this,
listResponseModel = parseNewsFeed(response);
to
listResponseModel.addAll(parseNewsFeed(response));
This happens because the Rss list which you're passing to recycler view adapter is null as you mentioned earlier you're successfully getting the values in log so another guaranteed workaround is to set the values into an separate arraylist.
So inside your class simply create arraylist:
private ArrayList<String> title;
private ArrayList<String> post;
This will be your initialize method:
private void initialize()
{
swipeRefreshLayout = findViewById(R.id.swipeRefresh_rssFeed);
recyclerView_rssFeed = findViewById(R.id.recyclerView_rssFeed);
title = new ArrayList<>();
post = new ArrayList<>();
}
Now simply pass your values to arraylist:
title.add(title)
post.add(post)
Now pass those arraylist to adapter:
adapter = new RssFeedAdapter(RssNewsActivity.this, title,post);
recyclerView_rssFeed.setAdapter(adapter);
After this initialize arraylist in adapter and fetch your values!
One more Important thing inside your oncreate() place your fetchNewsFeed(); method before initializing the adapter
initialize();
fetchNewsFeed();
recyclerView_rssFeed.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView_rssFeed.setLayoutManager(linearLayoutManager);
adapter = new RssFeedAdapter(RssNewsActivity.this, listResponseModel);
recyclerView_rssFeed.setAdapter(adapter);

Filter data by input in custom ArrayAdapter displays empty items

I implemented EditText widget to filter items in ListFragment using custom ArrayAdapter.
It works fine but the filtered list contains EMPTY items as well as filtered items.
I found that i should clear the adapter before to repopulate it, right?
Could it be something like
adapter.clear();
listview.getAdapter().notifyDataSetChanged();
Anyway I cannot find working solution.
Any clue to fix this bug, please?
public class CustomListAdapter extends ArrayAdapter<UnitView> {
private static final String TAG = "FRAGMENT TWO";
private final Activity context;
private final UnitView[] dataSource;
private UnitView[] unitViews;
public CustomListAdapter(Activity context, UnitView[] units) {
super(context, R.layout.unit, units);
this.context = context;
this.unitViews = units;
this.dataSource = units;
}
public View getView(int position,View view,ViewGroup parent) {
view = null;
try
{
if (view == null)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.listview_item, null);
UnitView uv = unitViews[position];
view.setTag(uv);
TextView textViewTypeName = (TextView) view.findViewById(R.id.textViewTypeName);
textViewTypeName.setText(uv.getDeviceTypeName());
// Code to populate widgets ....
}
}
catch (Exception ex)
{
Log.d(TAG, ex.getMessage());
}
return view;
};
// Filter input data in ListFragment
public void filter(String charText) {
try
{
charText = charText.toLowerCase(Locale.getDefault());
unitViews = new UnitView[dataSource.length];
if (charText.length() == 0) {
unitViews = Arrays.copyOf(this.dataSource, this.dataSource.length);
}
else
{
List<UnitView> result = new ArrayList<UnitView>();
for (UnitView uv : dataSource)
{
if (uv.getNumber().toLowerCase(Locale.getDefault()).contains(charText))
{
result.add(uv);
}
}
if(result.size() > 0)
{
unitViews = result.toArray(new UnitView[result.size()]);
}
}
notifyDataSetChanged();
}
catch (Exception ex)
{
Log.d(TAG, ex.getMessage());
}
}
public static boolean isBlank(String value) {
return (value == null || value.equals("") || value.equals("null") || value.trim().equals(""));
}
}
FragmentTwo.java
protected void onPostExecute(String s) {
super.onPostExecute(s);
try {
Gson gson = new Gson();
unitViews = gson.fromJson(s, UnitView[].class);
if (unitViews.length > 0) {
ArrayList<String> names = new ArrayList<String>();
for (int i = 0; i < unitViews.length; i++) {
String name = unitViews[i].getName();
names.add(name);
}
String[] values = names.toArray(new String[unitViews.length]);
adapter = new CustomListAdapter(getActivity(), unitViews);
setListAdapter(adapter);
// Locate the EditText in listview_main.xml
editSearch = (EditText)getActivity().findViewById(R.id.editSearch);
// Capture Text in EditText
editSearch.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
String text = editSearch.getText().toString().toLowerCase(Locale.getDefault());
adapter.filter(text);
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
});
Log.d(TAG, s);
}
}
catch (Exception ex)
{
Log.e(TAG, "Error: ", ex);
}
}
Ok, I found solution by relocating filter code to onPostExecute and re-initializing adapter.
protected void onPostExecute(String s) {
super.onPostExecute(s);
try {
Gson gson = new Gson();
unitViews = gson.fromJson(s, UnitView[].class);
if (unitViews.length > 0) {
ArrayList<String> names = new ArrayList<String>();
for (int i = 0; i < unitViews.length; i++) {
String name = unitViews[i].getName();
names.add(name);
}
String[] values = names.toArray(new String[unitViews.length]);
adapter = new CustomListAdapter(getActivity(), unitViews);
setListAdapter(adapter);
// Locate the EditText in listview_main.xml
editSearch = (EditText)getActivity().findViewById(R.id.editSearch);
// Capture Text in EditText
editSearch.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
String text = editSearch.getText().toString().toLowerCase(Locale.getDefault());
// adapter.filter(text);
try
{
text = text.toLowerCase(Locale.getDefault());
UnitView[] resultUnitViews = new UnitView[0];
if (text.length() == 0) {
resultUnitViews = Arrays.copyOf(unitViews, unitViews.length);
}
else
{
List<UnitView> result = new ArrayList<UnitView>();
for (UnitView uv : unitViews)
{
if (uv.getNumber().toLowerCase(Locale.getDefault()).contains(text))
{
result.add(uv);
}
}
if(result.size() > 0)
{
resultUnitViews = result.toArray(new UnitView[result.size()]);
adapter = new CustomListAdapter(getActivity(), resultUnitViews);
setListAdapter(adapter);
}
}
}
catch (Exception ex)
{
Log.d(TAG, ex.getMessage());
}
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
});
Log.d(TAG, s);
}
}
catch (Exception ex)
{
Log.e(TAG, "Error: ", ex);
}
}

I want to retrieve the saved movies data from database and show it to user android

I am building an app for Udacity called popular movies app which will fetch movies info from movieDB and display posters in the first activity than if the user clicked any poster it will take him to detailActivity where all the Movie detail will be displayed.
Now I am done with stage 1, stage 2 I am supposed to give the user the ability to make a favorite movie list which will be displayed in the first activity and deatilActivity and will be fetched from and to a database.
I already created the database and I have data saved there but I do not no how to retrieve it and display it to user kindly help me to do it.
below is my code:
First Activity the gridView for posters:
public class PhotoGrid extends Fragment {
//Create a string array variable for every item that we are going to recive from
// the movieDB
String[] movieId, movieTitle, movieReleaseDate, movieVoteAverage, movieOverview, moviePosterPath;
//use string1 to attach the poster path for every poster with the url so we can call the image
static String[] string1;
// define gridView here so we can use it in onPostexecute()
GridView gridView;
//movieUrl is used for the sortby setting
String movieUrl;
SQLiteDatabase db;
databaseHelper databaseHelper;
Cursor cursor;
ContentProvider contentProvider;
public PhotoGrid() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Add this line in order for this fragment to handle menu events.
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu, menu);
}
#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();
if (id == R.id.action_refresh) {
updateMovie();
return true;
} else if (id == R.id.action_settings) {
//if action_setting clicked SettingActivity will start
Intent intent = new Intent(getActivity(), SettingActivity.class);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
public void updateMovie() {
FetchMoviesPosters movieTask = new FetchMoviesPosters();
//make popularity as the default order or call for movieposters in settings
SharedPreferences sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(getActivity());
String sortBy = sharedPreferences.getString(getString(R.string.pref_sortby_key),
getString(R.string.pref_sortby_default));
movieTask.execute(sortBy);
}
#Override
public void onStart() {
super.onStart();
//update movies list on start
updateMovie();
}
#Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_photo_grid, container, false);
databaseHelper = new databaseHelper(getActivity(),MovieContract.MovieEntry.TABLE_NAME,null,2);
db = databaseHelper.getReadableDatabase();
gridView = (GridView) rootView.findViewById(R.id.grid_view);
updateMovie();
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
//Here handle the on poster click action by assigning the clicked poster info
//to strings and send them to detail activity with different keys to be able to
// control each item alone
String movieIDText = movieId[i];
String movieTitleText = movieTitle[i];
String movieOverViewText = movieOverview[i];
String movieReleaseDateText = movieReleaseDate[i];
String movieRatingText = movieVoteAverage[i];
String movieDetailImage = moviePosterPath[i];
Intent intent = new Intent(getActivity(), DetailActivity.class);
intent.putExtra("movie_id", movieIDText);
intent.putExtra("movie_overview", movieOverViewText);
intent.putExtra("movie_title", movieTitleText);
intent.putExtra("movie_release_date", movieReleaseDateText);
intent.putExtra("movie_rating", movieRatingText);
intent.putExtra("image_path", movieDetailImage);
startActivity(intent);
}
});
return rootView;
}
//ImageAdapter is used to control images dimensions and load them in the
// imageview using Picasso
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private String[] mThumbIds;
public ImageAdapter(Context c, String[] str2) {
mContext = c;
mThumbIds = str2;
}
#Override
public int getCount() {
if (mThumbIds != null) {
return mThumbIds.length;
} else {
return 0;
}
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(700, 1200));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(4, 4, 4, 4);
} else {
imageView = (ImageView) convertView;
}
Picasso.with(mContext).load(mThumbIds[position]).into(imageView);
return imageView;
}
}
public class FetchMoviesPosters extends AsyncTask<String, Void, String[]> {
private final String LOG_TAG = FetchMoviesPosters.class.getSimpleName();
//in this function the different order settings are defined
private String setOrder(String sortBy) {
if (sortBy.equals(getString(R.string.pref_sorting_popularity))) {
movieUrl = "https://api.themoviedb.org/3/movie/popular?";
} else if (sortBy.equals(getString(R.string.pref_sorting_highest_rating))) {
movieUrl = "https://api.themoviedb.org/3/movie/top_rated?";
}
else if (sortBy.equals(getString(R.string.pref_sorting_favorite))){
cursor = databaseHelper.retrieveData(db);
if (cursor.moveToFirst()){
do {
String id, title, overView, releaseDate, rating, posterPath;
id = cursor.getString(0);
title = cursor.getString(1);
overView = cursor.getString(2);
releaseDate = cursor.getString(3);
rating = cursor.getString(4);
posterPath = cursor.getString(5);
contentProvider = new ContentProvider(id , title , overView
, releaseDate, rating , posterPath);
}while (cursor.moveToNext());
}
}
return sortBy;
}
private String[] MoviesJasonPrase(String moviesPosterStr ) throws JSONException {
final String M_Result = "results";
final String M_ID = "id";
final String M_Title = "original_title";
final String M_Release = "release_date";
final String M_Vote = "vote_average";
final String M_OverV = "overview";
final String M_Poster = "poster_path";
JSONObject moviesJson = new JSONObject(moviesPosterStr);
JSONArray resultsArray = moviesJson.getJSONArray(M_Result);
movieId = new String[resultsArray.length()];
movieTitle = new String[resultsArray.length()];
movieReleaseDate = new String[resultsArray.length()];
movieVoteAverage = new String[resultsArray.length()];
movieOverview = new String[resultsArray.length()];
moviePosterPath = new String[resultsArray.length()];
for (int i = 0; i < resultsArray.length(); i++) {
JSONObject movie = resultsArray.getJSONObject(i);
movieId[i] = movie.getString(M_ID);
movieTitle[i] = movie.getString(M_Title);
movieReleaseDate[i] = movie.getString(M_Release);
movieVoteAverage[i] = movie.getString(M_Vote);
movieOverview[i] = movie.getString(M_OverV);
moviePosterPath[i] = movie.getString(M_Poster);
}
return moviePosterPath;
}
#Override
protected String[] doInBackground(String... params) {
if (params.length == 0) {
return null;
}
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String moviePostersJsonStr = null;
try {
SharedPreferences sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(getActivity());
String sortBy = sharedPreferences.getString(getString(R.string.pref_sortby_key),
getString(R.string.pref_sorting_popularity));
setOrder(sortBy);
final String APPID_PARAM = "api_key";
Uri builtUri = Uri.parse(movieUrl).buildUpon()
.appendQueryParameter(APPID_PARAM, BuildConfig.THE_MOVIE_DB)
.build();
URL url = new URL(builtUri.toString());
Log.v(LOG_TAG, "Built URI " + builtUri.toString());
// Create the request to TheMovieDB, and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuilder buffer = new StringBuilder();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line).append("\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
moviePostersJsonStr = buffer.toString();
} catch (IOException e) {
Log.e("PhotoGrid", "Error ", e);
// If the code didn't successfully get the weather data, there's no point in attemping
// to parse it.
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("PhotoGrid", "Error closing stream", e);
}
}
}
try {
return MoviesJasonPrase(moviePostersJsonStr);
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String[] Strings) {
if (Strings != null) {
string1 = new String[Strings.length];
for (int i = 0; i < Strings.length; i++) {
//receive poster images path
String[] getImage = Strings[i].split("-");
//concatenate path to url "http://image.tmdb.org/t/p/w185/"
string1[i] = "http://image.tmdb.org/t/p/w185/" + getImage[0];
}
ImageAdapter imageAdapter = new ImageAdapter(getActivity(), string1);
//put images after going though the adapter in the gridview
gridView.setAdapter(imageAdapter);
}
}
}
}
The detailActivity:
public class DetailFragment extends Fragment {
String ID;
String title;
String overView;
String releaseDate;
String rating;
String posterPath;
String movieKey;
databaseHelper myDB ;
ImageButton favorite;
public DetailFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Add this line in order for this fragment to handle menu events.
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_detail, menu);
}
#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) {
Intent intent = new Intent(getActivity(), SettingActivity.class);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_detail, container, false);
myDB = new databaseHelper(getActivity(), MovieContract.MovieEntry.TABLE_NAME,null,2);
favorite = (ImageButton) rootView.findViewById(R.id.favorite);
final Intent intent = getActivity().getIntent();
// The detail Activity called via intent. Inspect the intent for
// movies data using movie ID.
if (intent != null && intent.hasExtra("movie_id")) {
//if true put each item in a textview and load the poster in imageView
ID = intent.getStringExtra("movie_id");
title = intent.getStringExtra("movie_title");
((TextView) rootView.findViewById(R.id.title_text))
.setText(title);
overView = intent.getStringExtra("movie_overview");
((TextView) rootView.findViewById(R.id.overview_text))
.setText(overView);
releaseDate = intent.getStringExtra("movie_release_date");
((TextView) rootView.findViewById(R.id.release_date_text))
.setText(releaseDate);
rating = intent.getStringExtra("movie_rating");
((TextView) rootView.findViewById(R.id.rating_text))
.setText(rating);
posterPath = intent.getStringExtra("image_path");
String posterImage = "http://image.tmdb.org/t/p/w185/" + posterPath;
ImageView imageView = (ImageView) rootView.findViewById(R.id.detail_image);
Picasso.with(getActivity()).load(posterImage).resize(500, 800).into(imageView);
}
Button button = (Button) rootView.findViewById(R.id.play);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
playTrailer();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(String.valueOf("http://www.youtube.com/watch?v="+ movieKey)));
startActivity(intent);
}
});
Button button1 = (Button) rootView.findViewById(R.id.open_reviews);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String id = ID;
Intent intent1 = new Intent(getActivity(), ReviewActivity.class);
intent1.putExtra("movie_id", id);
startActivity(intent1);
}
});
addData();
return rootView;
}
public void playTrailer() {
FetchMoviesTrailer fetchMoviesTrailer = new FetchMoviesTrailer();
fetchMoviesTrailer.execute(ID);
}
public void addData(){
favorite.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
boolean isInsearted = myDB.insert(ID, title, overView, releaseDate,
rating, posterPath);
if (isInsearted)
Toast.makeText(getActivity(),"Added to Favorite", Toast.LENGTH_SHORT)
.show();
else
Toast.makeText(getActivity(),"Not Added to Favorite", Toast.LENGTH_SHORT)
.show();
}
}
);
}
public class FetchMoviesTrailer extends AsyncTask<String, Void, String[]> {
private final String LOG_TAG = FetchMoviesTrailer.class.getSimpleName();
//in this function the different order settings are defined
private String[] MoviesJasonPrase(String moviesTrailerStr) throws JSONException {
final String T_Result = "results";
final String T_key = "key";
JSONObject moviesJson = new JSONObject(moviesTrailerStr);
JSONArray resultsArray = moviesJson.getJSONArray(T_Result);
String[] strings = new String[resultsArray.length()];
for (int i = 0; i < resultsArray.length(); i++) {
JSONObject movie = resultsArray.getJSONObject(i);
movieKey = movie.getString(T_key);
strings[i] = movieKey;
}
return strings;
}
#Override
protected String[] doInBackground(String... params) {
if (params.length == 0) {
return null;
}
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String movieTrailerJsonStr = null;
try {
final String APPID_PARAM = "api_key";
final String Traile_Url = "http://api.themoviedb.org/3/movie/" + ID
+ "/videos?";
Uri builtUri = Uri.parse(Traile_Url).buildUpon()
.appendQueryParameter(APPID_PARAM, BuildConfig.THE_MOVIE_DB)
.build();
URL url = new URL(builtUri.toString());
Log.v(LOG_TAG, "Built URI " + builtUri.toString());
// Create the request to TheMovieDB, and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuilder buffer = new StringBuilder();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line).append("\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
movieTrailerJsonStr = buffer.toString();
} catch (IOException e) {
Log.e("PhotoGrid", "Error ", e);
// If the code didn't successfully get the weather data, there's no point in attemping
// to parse it.
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("PhotoGrid", "Error closing stream", e);
}
}
}
try {
return MoviesJasonPrase(movieTrailerJsonStr);
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String[] strings) {
super.onPostExecute(strings);
}
}
}
The DataBase Helper:
public class databaseHelper extends SQLiteOpenHelper{
SQLiteDatabase db ;
public static final int DATABASE_VERSION = 2;
public static final String DATABASE_NAME = "FavoriteMovies.db";
public databaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
final String SQL_CREATE_Movie_TABLE = "CREATE TABLE " + MovieEntry.TABLE_NAME + " (" +
MovieEntry.ID_COLUMAN + " TEXT PRIMARY KEY," +
MovieEntry.TITLE_COLUMAN + " TEXT NOT NULL, " +
MovieEntry.OVERVIEW_COLUMAN + " TEXT NOT NULL, " +
MovieEntry.RELEASE_DATE_COLUMAN + " TEXT NOT NULL, " +
MovieEntry.RATING_COLUMAN + " TEXT NOT NULL, " +
MovieEntry.POSTAR_PATH_COLUMAN+ " TEXT NOT NULL " +
" );";
db.execSQL(SQL_CREATE_Movie_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS" + MovieEntry.TABLE_NAME);
onCreate(db);
}
public boolean insert(String id, String title , String overView , String date, String rating,
String poster){
db = super.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(MovieEntry.ID_COLUMAN,id);
contentValues.put(MovieEntry.TITLE_COLUMAN,title);
contentValues.put(MovieEntry.OVERVIEW_COLUMAN,overView);
contentValues.put(MovieEntry.RELEASE_DATE_COLUMAN,date);
contentValues.put(MovieEntry.RATING_COLUMAN,rating);
contentValues.put(MovieEntry.POSTAR_PATH_COLUMAN, poster);
long isAdded = db.insert(MovieEntry.TABLE_NAME, null ,contentValues);
if (isAdded == -1) {
return false;
}
else
return true;
}
public Cursor retrieveData(SQLiteDatabase db){
Cursor cursor;
String[] projection = {MovieEntry.ID_COLUMAN, MovieEntry.TITLE_COLUMAN,
MovieEntry.OVERVIEW_COLUMAN, MovieEntry.RELEASE_DATE_COLUMAN, MovieEntry.RATING_COLUMAN,
MovieEntry.POSTAR_PATH_COLUMAN};
cursor = db.query(MovieEntry.TABLE_NAME, projection, null,null,null,null,null);
return cursor;
}
}
The DataBase Contract:
public class MovieContract {
public MovieContract(){}
public static abstract class MovieEntry implements BaseColumns{
public static final String TABLE_NAME = "favorite";
public static final String ID_COLUMAN = "ID";
public static final String TITLE_COLUMAN = "title";
public static final String OVERVIEW_COLUMAN = "overView";
public static final String RELEASE_DATE_COLUMAN = "releaseDate";
public static final String RATING_COLUMAN = "rating";
public static final String POSTAR_PATH_COLUMAN = "posterPath";
}
}
The content Provider:
public class ContentProvider {
private String id;
private String title;
private String overView;
private String releaseDate;
private String rating;
private String posterPath;
public ContentProvider(String ID, String Title,String OverView, String ReleaseDate,
String Rating, String PosterPath){
this.id = ID;
this.title = Title;
this.overView = OverView;
this.releaseDate = ReleaseDate;
this.rating = Rating;
this.posterPath = PosterPath;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getOverView() {
return overView;
}
public void setOverView(String overView) {
this.overView = overView;
}
public String getReleaseDate() {
return releaseDate;
}
public void setReleaseDate(String releaseDate) {
this.releaseDate = releaseDate;
}
public String getRating() {
return rating;
}
public void setRating(String rating) {
this.rating = rating;
}
public String getPosterPath() {
return posterPath;
}
public void setPosterPath(String posterPath) {
this.posterPath = posterPath;
}
}
This is all covered in the Udacity course. I would suggest reviewing those videos.
However, the basic idea is that you need to create a query() method in your content provider class. The Sunshine example from Udacity looks something like this:
#Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
// Here's the switch statement that, given a URI, will determine what kind of request it is,
// and query the database accordingly.
Cursor retCursor;
switch (sUriMatcher.match(uri)) {
// "weather/*/*"
case WEATHER_WITH_LOCATION_AND_DATE:
{
retCursor = getWeatherByLocationSettingAndDate(uri, projection, sortOrder);
break;
}
// "weather/*"
case WEATHER_WITH_LOCATION: {
retCursor = getWeatherByLocationSetting(uri, projection, sortOrder);
break;
}
// "weather"
case WEATHER: {
retCursor = mOpenHelper.getReadableDatabase().query(
WeatherContract.WeatherEntry.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder
);
break;
}
// "location"
case LOCATION: {
retCursor = mOpenHelper.getReadableDatabase().query(
WeatherContract.LocationEntry.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder
);
break;
}
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
retCursor.setNotificationUri(getContext().getContentResolver(), uri);
return retCursor;
}
From there, if you aren't using a CursorLoader, you need to call the query method on your Content Resolver and pass in your parameters.
Here is an example from Google:
// Queries the user dictionary and returns results
mCursor = getContentResolver().query(
UserDictionary.Words.CONTENT_URI, // The content URI of the words table
mProjection, // The columns to return for each row
mSelectionClause // Selection criteria
mSelectionArgs, // Selection criteria
mSortOrder); // The sort order for the returned rows
I would also take a look at this link to read more about Content Providers.

Can't set the data that is coming out as the response from the server to the CustomListView Adapter

This is the Java code where I am parsing the data-
pDialog = new ProgressDialog(getActivity());
// Showing progress dialog before making http request
pDialog.setMessage("Loading...Please Wait...");
pDialog.show();
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, "http://sikkimexpress.itstunner.com/api/homenewslist/topnews", new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("HomeNews");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject homenews = jsonArray.getJSONObject(i);
Movie movie = new Movie();
String newsId = homenews.getString("NewsId");
String dateTime = homenews.getString("DateTime");
String newsType = homenews.getString("NewsType");
String title = homenews.getString("Title");
String description = homenews.getString("Description");
String mainImageURL = homenews.getString("MainImageThumbnail");
movieList.add(movie);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
System.out.println("Result:- " + newsId + " " + dateTime + " " + newsType + " " + title + " " + description + " " + mainImageURL);
}
} catch (JSONException e) {
e.printStackTrace();
}
// pDialog.hide();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY", error.getMessage());
// pDialog.hide();
}
});
AppController.getInstance().addToRequestQueue(jsonObjectRequest);
This is the Model Class:-
public class Movie {
private String newsId;
private String dateTime;
private String newsType;
private String title;
private String description;
private String thumbnailUrl;
public Movie() {
}
public Movie(String news_id, String date_time, String news_type, String news_title, String news_description, String news_thumbnailUrl) {
this.title = news_title;
this.thumbnailUrl = news_thumbnailUrl;
this.newsId = news_id;
this.dateTime = date_time;
this.newsType = news_type;
this.description = news_description;
}
public String getNewsId() {
return newsId;
}
public void setNewsId(String newsId) {
this.newsId = newsId;
}
public String getDateTime() {
return dateTime;
}
public void setDateTime(String dateTime) {
this.dateTime = dateTime;
}
public String getNewsType() {
return newsType;
}
public void setNewsType(String newsType) {
this.newsType = newsType;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getThumbnailUrl() {
return thumbnailUrl;
}
public void setThumbnailUrl(String thumbnailUrl) {
this.thumbnailUrl = thumbnailUrl;
}
}
The CustomListView Adapter:-
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();
NetworkImageView thumbNail = (NetworkImageView) convertView.findViewById(R.id.thumbnail);
TextView title = (TextView) convertView.findViewById(R.id.title);
TextView desciption = (TextView) convertView.findViewById(R.id.desciption);
Movie m = movieItems.get(position);
thumbNail.setImageUrl(m.getThumbnailUrl(), imageLoader);
title.setText(m.getTitle());
desciption.setText(m.getDescription());
return convertView;
}
}
There is no error while Parsing the data from server. I am getting the actual result. But the Progress Dialog is running after getting the data from the server. The data are not getting set in the CustomListView Adapter. I have already attached the code. Please Help me. I got stuck in it.
You are not closing your Dialog when you have your data.
You should not load data on the "main thread" - use a AsyncTask or something similiar to load your data. There you can show a progress dialog, before you start downloading your data:
From the docs:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
//Once created, a task is executed very simply:
new DownloadFilesTask().execute(url1, url2, url3);
Also, don't set the adapter multiple times to your ListView (unless you use a different adapter), and call notifyDataSetChanged() everytime your underlying data changes. r data, show progress and stop the dialog when you are finished.
But the Progress Dialog is running after getting the data from the server.?
ans: you are not closing the dialog in onResponse method
For listview you are not setting adapter with updated data. Please create a new adapter or follow this How to update listview when back pressed from another activity android?
You need to dismiss progressdialog in this two response method to hide.
#Override public void onResponse(JSONObject response) { pDialog.dismiss(); }
#Override public void onErrorResponse(VolleyError error) { pDialog.dismiss(); }
In onResponse() method after parsing json you need to notify adapter to display data in list.

Custom Adapter with Search Not working

I tried to add textwatcher with filter class but it do not work plz help. I get the json array through the server using the url. the search(filter) doesnt work well.
public class CallDetails extends Activity {
SessionManager session;
ArrayList<Drivers> driverList = new ArrayList<Drivers>();
private List<Drivers> driverlist = null;
ListView listview;
ImageButton btback;
DriverAdapter dadapter;
String uid;
String name;
String email;
String odtyp;
static String oid;
Drivers driver;
private EditText editTextFilter;
private static String OUTBOX_URL ="";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.calldetails);
Intent i = getIntent();
oid =i.getStringExtra("orderId");
odtyp =i.getStringExtra("ordertype");
OUTBOX_URL ="http://www.gdrive.com/api/calldetails.php?id="+oid;
//managing session...
session = new SessionManager(getApplicationContext());
HashMap<String, String> user = session.getUserDetails();
name = user.get(SessionManager.KEY_NAME);
email = user.get(SessionManager.KEY_EMAIL);
uid = user.get(SessionManager.KEY_UID);
btback =(ImageButton)findViewById(R.id.btnBack);
btback.setVisibility(View.INVISIBLE);
// Locate the EditText in listview_main.xml
editTextFilter = (EditText)findViewById(R.id.editTextFilter);
editTextFilter.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable arg0) {
String text = editTextFilter.getText().toString().toLowerCase(Locale.getDefault());
dadapter.filter(text);
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3){ /* to do*/ }
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) { /*to do*/ }
});
//populating view with data...
//driverList = new ArrayList<Drivers>();
new JSONAsyncTask().execute(OUTBOX_URL);
listview = (ListView)findViewById(R.id.drlist);
dadapter = new DriverAdapter(CallDetails.this, R.layout.list_item, driverList);
listview.setItemsCanFocus(false);
listview.setAdapter(dadapter);
//populating list ends
listview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), driverList.get(position).getName(), Toast.LENGTH_LONG).show();
}
});
}
public void back(View v){
Intent back = new Intent(getApplicationContext(), SafetyDrive.class);
startActivity(back);
finish();
}
private class DriverAdapter extends ArrayAdapter<Drivers> {
Context context;
int Resource;
LayoutInflater inflater;
ArrayList<Drivers> driverList = new ArrayList<Drivers>();
public DriverAdapter(Context context, int layoutResourceId,ArrayList<Drivers> drs) {
super(context, layoutResourceId, drs);
//inflater = ((Activity) context).getLayoutInflater();
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Resource = layoutResourceId;
driverList = drs;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//Log.d("in ", "view start");
View item = convertView;
DriverWrapper DriverWrapper = null;
if (item == null) {
DriverWrapper = new DriverWrapper();
item = inflater.inflate(Resource, null);
DriverWrapper.ename = (TextView) item.findViewById(R.id.textName);
DriverWrapper.ephone = (TextView) item.findViewById(R.id.textPhone);
DriverWrapper.mkcall = (ImageButton) item.findViewById(R.id.btnphone);
item.setTag(DriverWrapper);
} else {
DriverWrapper = (DriverWrapper) item.getTag();
}
Drivers driver = driverList.get(position);
DriverWrapper.ename.setText("Name: " + driver.getName());
DriverWrapper.ephone.setText("Phone: " + driver.getPhone());
final String dp = driver.getPhone().trim();
DriverWrapper.mkcall.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//making call..
//Log.e("no is", dp);
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:" +dp));
//callIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(callIntent);
//finish();
}
});
return item;
}
class DriverWrapper {
TextView ename;
TextView ephone;
ImageButton mkcall;
//ImageButton msg;
}
// Filter Class
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
driverList.clear();
if (charText.length() == 0) {
driverList.addAll(driverList);
} else {
for (Drivers driver : driverList) {
if (driver.getName().toLowerCase(Locale.getDefault()).contains(charText)) {
driverList.add(driver);
}
}
}
notifyDataSetChanged();
}
}
class JSONAsyncTask extends AsyncTask {
ProgressDialog dialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(CallDetails.this);
dialog.setMessage("Loading, please wait");
dialog.show();
dialog.setCancelable(false);
}
#Override
protected Boolean doInBackground(String... urls) {
try {
//Log.d("in at-", "asynctask");
HttpGet httppost = new HttpGet(urls[0]);
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httppost);
// StatusLine stat = response.getStatusLine();
int status = response.getStatusLine().getStatusCode();
if (status == 200) {
HttpEntity entity = response.getEntity();
String data = EntityUtils.toString(entity);
JSONObject jsono = new JSONObject(data);
JSONArray jarray = jsono.getJSONArray("drivers");
if(jarray.length()!=0){
for (int i = 0; i < jarray.length(); i++) {
JSONObject object = jarray.getJSONObject(i);
Drivers driver = new Drivers();
driver.setPhone(object.getString("phone"));
driver.setName(object.getString("emp_name"));
driverList.add(driver);
}
}else{
driver = new Drivers();
driver.setPhone(" ");
driver.setName(" No Driver Place yet");
driverList.add(driver);
}
return true;
}
} catch (ParseException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean result) {
dialog.cancel();
btback.setVisibility(View.VISIBLE);
dadapter.notifyDataSetChanged();
if(result == false)
Toast.makeText(getApplicationContext(), "Unable to fetch data from server", Toast.LENGTH_LONG).show();
}
}
}
public class Drivers {
private String name;
private String phone;
public Drivers() {
}
public Drivers(String name, String phone) {
super();
this.name = name;
this.phone = phone;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
actually it wont filter because youve cleared the driverList and then in the else statement you loop to driverList which is already empty. the only thing you can do is create a backup list for the driversList and then use the backup list to get all data for filtering to the driverList.
Example Here:
// here is the backuplist
ArrayList<Drivers> backupList = new ArrayList<Drivers>();
// Filter Class
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
// actually its easy to just clear the backup list
// but due to reasons where users press backspace you have to load backup list only once
if(backupList.isEmpty()) {
backupList.addAll(driverList);
}
driverList.clear();
if (charText.length() == 0) {
driverList.addAll(backupList);
} else {
for (Drivers driver : backupList) {
if (driver.getName().toLowerCase(Locale.getDefault()).contains(charText)) {
driverList.add(driver);
}
}
}
notifyDataSetChanged();
}
Hope it helps :)

Categories