Android : Movie.decodeStream returns null

on Thursday, April 16, 2015


I am new to android and I am trying to display a list of gifs(fetched from giphy apis.. https://github.com/giphy/GiphyAPI) in a recycler grid view. I am using a tutorial by Johannes Borchardt to display gifs (http://droid-blog.net/2011/10/14/tutorial-how-to-use-animated-gifs-in-android-part-1/)


Here is my code:


Fragment code



public static class GiphyFragment extends Fragment {

private RecyclerView mRecyclerView;
private GiphyTestAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;

public GiphyFragment() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_giphy_test, container, false);

mRecyclerView = (RecyclerView) rootView.findViewById(R.id.giphy_recycler_view);
mRecyclerView.setHasFixedSize(true);

// use a grid layout manager
mLayoutManager = new GridLayoutManager(getActivity(),2);
mRecyclerView.setLayoutManager(mLayoutManager);

// specify an adapter
ArrayList<Giphy> giphyDataSet = new ArrayList<Giphy>();
mAdapter = new GiphyTestAdapter(getActivity(),giphyDataSet);
mRecyclerView.setAdapter(mAdapter);

//run async task to fetch list of giphys
GetGiphyListTask task = new GetGiphyListTask();
task.execute(new String[] { "http://api.giphy.com/v1/gifs/trending?api_key=dc6zaTOxFJmzC" });

return rootView;
}

/**
* Async task that fetches the list of giphys
*/
private class GetGiphyListTask extends AsyncTask<String, Void, String> {

private final String LOG_TAG = this.getClass().getSimpleName();

@Override
protected String doInBackground(String... urls) {
StringBuilder outputData = new StringBuilder();
String url = urls[0];
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
InputStream content = null;
BufferedReader reader = null;
try {
HttpResponse response = client.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) {
HttpEntity entity = response.getEntity();
content = entity.getContent();
reader = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = reader.readLine()) != null) {
outputData.append(line);
}
}else{
Log.e(LOG_TAG, "Failed to get giphy");
}

} catch (Exception e) {
Log.e(LOG_TAG, "Failed to get giphy");
}finally {
try {
content.close();
reader.close();
} catch (IOException e) {
Log.e(LOG_TAG, "Error while cleaning up resources");
}
}
return outputData.toString();
}

@Override
protected void onPostExecute(String result) {
try {

//get giphy urls and create giphy objects
JSONObject json = new JSONObject(result);
Log.d(LOG_TAG,json.toString());
JSONArray data = json.getJSONArray("data");
Giphy[] giphyArr = new Giphy[data.length()];
for(int i =0; i < data.length(); i++){
JSONObject giphyObj = new JSONObject(data.get(i).toString());
String giphyUrl = giphyObj.getString("embed_url");
Giphy giphy = new Giphy(giphyUrl);
giphyArr[i] = giphy;
}

//run an async task to fetch individual giphys
GetGiphyTask task = new GetGiphyTask();
task.execute(giphyArr);

} catch (JSONException e) {
Log.e(LOG_TAG, "Failed to get giphy");
} catch ( Exception e){
Log.e(LOG_TAG, "Failed to get giphy");
}
}
}

/**
* Async task that fetches individual giphys
*/
private class GetGiphyTask extends AsyncTask<Giphy, Void, Void> {

private final String LOG_TAG = this.getClass().getSimpleName();

@Override
protected Void doInBackground(Giphy... giphys) {

for(int i =0; i < giphys.length; i++){
Giphy giphy = giphys[i];
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(giphy.getUrl());
try {
HttpResponse response = client.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) {
HttpEntity entity = response.getEntity();
//Have tried number of things here..
BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);
giphy.setInputStream(bufHttpEntity.getContent());
mAdapter.add(i,giphy);
httpGet.abort();
}else{
Log.e(LOG_TAG, "Failed to get giphy from url");
}

} catch (Exception e) {
Log.e(LOG_TAG, "Failed to get giphy from url");
}
}
return null;
}
}
}


Adaptor code



public class GiphyTestAdapter extends RecyclerView.Adapter<GiphyTestAdapter.ViewHolder> {

private final String LOG_TAG = getClass().getSimpleName();
private ArrayList<Giphy> mDataset;
private Context mContext;

public class ViewHolder extends RecyclerView.ViewHolder {
public GiphyView giphyView;

public ViewHolder(View v) {
super(v);
giphyView = (GiphyView) v.findViewById(R.id.giphy_view);
}
}

public void add(int position, Giphy giphyObj) {
mDataset.add(giphyObj);
notifyItemInserted(position);
}

public GiphyTestAdapter(Context context, ArrayList<Giphy> myDataset) {
mContext = context;
mDataset = myDataset;
}

// Create new views (invoked by the layout manager)
@Override
public GiphyTestAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_giphy_item_list, parent, false);
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(v);
return vh;
}

// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final Giphy giphy = mDataset.get(position);
//holder.giphyView.playGif(giphy.getInputStream());
holder.giphyView = new GiphyView(mContext,giphy.getInputStream());
}

@Override
public int getItemCount() {
return mDataset.size();
}
}


View code



public class GiphyView extends View {

private Movie mMovie;
private long mMoviestart;

public GiphyView(Context context,AttributeSet attrs) {
super(context,attrs);
}

public GiphyView(Context context, InputStream stream) {
super(context);
try {
mMovie = Movie.decodeStream(stream);
}catch(Exception e){
Log.d("test", "");
}
mMoviestart = 0;

}

@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.TRANSPARENT);
super.onDraw(canvas);
if(mMovie != null){
final long now = System.currentTimeMillis();
if (mMoviestart == 0){
mMoviestart = now;
}
final int relTime = (int)((now - mMoviestart) % mMovie.duration());
mMovie.setTime(relTime);
mMovie.draw(canvas, 10, 10);
this.invalidate();
}
}
}


I have following questions.



  1. My Movie.decodeStream inside the GridView always returns null.

  2. According to the tutorial I need to call a specific constructor of GridView. How to call it in a recycler RecyclerView.Adapter (right now I m calling it in onBindViewHolder which seems wrong)

  3. I am adding input stream in my custom objects (Giphy obj). What would be a better way to pass input streams to GridView.


I searched online for problem 1. Have tried creating new input stream, reset it. Nothing works. Any idea how to fix this ? Also any suggestions on structural changes in the code will help. Thanks.


0 comments:

Post a Comment