com.arantius.tivocommander.Upcoming.java Source code

Java tutorial

Introduction

Here is the source code for com.arantius.tivocommander.Upcoming.java

Source

/*
DVR Commander for TiVo allows control of a TiVo Premiere device.
Copyright (C) 2011  Anthony Lieuallen (arantius@gmail.com)
    
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

package com.arantius.tivocommander;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

import com.arantius.tivocommander.rpc.MindRpc;
import com.arantius.tivocommander.rpc.request.RecordingUpdate;
import com.arantius.tivocommander.rpc.request.UpcomingSearch;
import com.arantius.tivocommander.rpc.response.MindRpcResponse;
import com.arantius.tivocommander.rpc.response.MindRpcResponseListener;
import com.fasterxml.jackson.databind.JsonNode;

public class Upcoming extends ListActivity implements OnItemClickListener, OnItemLongClickListener {
    private class DateInPast extends Throwable {
        private static final long serialVersionUID = -4184008452910054505L;
    }

    protected SimpleAdapter mListAdapter;
    protected JsonNode mShows;

    private final MindRpcResponseListener mUpcomingListener = new MindRpcResponseListener() {
        public void onResponse(MindRpcResponse response) {
            setProgressBarIndeterminateVisibility(false);
            findViewById(android.R.id.empty).setVisibility(View.VISIBLE);

            mShows = response.getBody().path("offer");

            List<HashMap<String, Object>> listItems = new ArrayList<HashMap<String, Object>>();

            for (int i = 0; i < mShows.size(); i++) {
                final JsonNode item = mShows.path(i);
                try {
                    HashMap<String, Object> listItem = new HashMap<String, Object>();

                    String channelNum = item.path("channel").path("channelNumber").asText();
                    String callSign = item.path("channel").path("callSign").asText();
                    String details = String.format("%s  %s %s", formatTime(item), channelNum, callSign);
                    if (item.path("episodic").asBoolean() && item.path("episodeNum").path(0).asInt() > 0
                            && item.path("seasonNumber").asInt() > 0) {
                        details = String.format("(Sea %d Ep %d)  ", item.path("seasonNumber").asInt(),
                                item.path("episodeNum").path(0).asInt()) + details;
                    }
                    listItem.put("icon", R.drawable.blank);
                    if (item.has("recordingForOfferId")) {
                        listItem.put("icon", R.drawable.check);
                    }
                    listItem.put("details", details);
                    listItem.put("title",
                            item.has("subtitle") ? item.path("subtitle").asText() : item.path("title").asText());
                    listItem.put("index", Integer.valueOf(i));
                    listItems.add(listItem);
                } catch (DateInPast e) {
                    // No-op. Just don't show past items.
                }
            }

            final ListView lv = getListView();
            mListAdapter = new SimpleAdapter(Upcoming.this, listItems, R.layout.item_upcoming,
                    new String[] { "details", "icon", "title" },
                    new int[] { R.id.upcoming_details, R.id.upcoming_icon, R.id.upcoming_title });
            lv.setAdapter(mListAdapter);
            lv.setOnItemClickListener(Upcoming.this);
            lv.setLongClickable(true);
            lv.setOnItemLongClickListener(Upcoming.this);
        }
    };

    protected String formatTime(JsonNode item) throws DateInPast {
        String timeIn = item.path("startTime").asText();
        if (timeIn == null) {
            return null;
        }

        Date playTime = Utils.parseDateTimeStr(timeIn);
        if (playTime.before(new Date())) {
            throw new DateInPast();
        }
        SimpleDateFormat dateFormatter = new SimpleDateFormat("EEE M/d hh:mm a", Locale.US);
        dateFormatter.setTimeZone(TimeZone.getDefault());
        return dateFormatter.format(playTime);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle bundle = getIntent().getExtras();
        MindRpc.init(this, bundle);

        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
        setContentView(R.layout.list_empty);
        findViewById(android.R.id.empty).setVisibility(View.GONE);

        String collectionId = null;

        if (bundle != null) {
            collectionId = bundle.getString("collectionId");
            if (collectionId == null) {
                Utils.toast(this, "Oops; missing collection ID", Toast.LENGTH_SHORT);
            } else {
                setProgressBarIndeterminateVisibility(true);
                UpcomingSearch request = new UpcomingSearch(collectionId);
                MindRpc.addRequest(request, mUpcomingListener);
            }
        }

        Utils.log(String.format("Upcoming: collectionId:%s", collectionId));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        Utils.createFullOptionsMenu(menu, this);
        return true;
    }

    protected JsonNode showItemFromListPosition(int position) {
        @SuppressWarnings("unchecked")
        final HashMap<String, Object> listItem = (HashMap<String, Object>) mListAdapter.getItem(position);
        final JsonNode show = mShows.path(((Integer) listItem.get("index")).intValue());
        return show;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // This should only come from a long-press "record" activity finishing.
        // Refresh the whole thing to get the check.  (Lazy and slow, but it works.)
        startActivity(getIntent());
        finish();
    }

    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        final JsonNode show = showItemFromListPosition(position);
        Intent intent = new Intent(Upcoming.this, ExploreTabs.class);
        intent.putExtra("contentId", show.path("contentId").asText());
        intent.putExtra("collectionId", show.path("collectionId").asText());
        intent.putExtra("offerId", show.path("offerId").asText());
        startActivityForResult(intent, 1);
    }

    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
        final JsonNode show = showItemFromListPosition(position);
        final ArrayList<String> choices = new ArrayList<String>();
        if (show.has("recordingForOfferId")) {
            choices.add("Don't Record");
        } else {
            choices.add("Record");
        }
        ArrayAdapter<String> choicesAdapter = new ArrayAdapter<String>(this, android.R.layout.select_dialog_item,
                choices);

        DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int position) {
                final String action = choices.get(position);
                if ("Record".equals(action)) {
                    Intent intent = new Intent(getBaseContext(), SubscribeOffer.class);
                    intent.putExtra("offerId", show.path("offerId").asText());
                    intent.putExtra("contentId", show.path("contentId").asText());
                    startActivityForResult(intent, 1);
                } else if ("Don't Record".equals(action)) {
                    Upcoming.this.setProgressBarIndeterminateVisibility(true);
                    final String recordingId = show.path("recordingForOfferId").path(0).path("recordingId")
                            .asText();
                    MindRpc.addRequest(new RecordingUpdate(recordingId, "cancelled"),
                            new MindRpcResponseListener() {
                                public void onResponse(MindRpcResponse response) {
                                    // Refresh the whole thing, to remove the check.
                                    // (Lazy and slow, but it works.)
                                    startActivity(getIntent());
                                    finish();
                                }
                            });
                }
            }
        };

        Builder dialogBuilder = new AlertDialog.Builder(this);
        dialogBuilder.setTitle("Operation?");
        dialogBuilder.setAdapter(choicesAdapter, onClickListener);
        dialogBuilder.create().show();
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        return Utils.onOptionsItemSelected(item, this, true);
    }

    @Override
    protected void onPause() {
        super.onPause();
        Utils.log("Activity:Pause:Upcoming");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Utils.log("Activity:Resume:Upcoming");
        MindRpc.init(this, getIntent().getExtras());
    }
}