private void onNotify( final SharedPreferences prefs, final Cursor upcomingEpisodes, int count, long latestAirtime) { final Context context = getApplicationContext(); CharSequence tickerText = ""; CharSequence contentTitle = ""; CharSequence contentText = ""; PendingIntent contentIntent = null; // notification sound final String ringtoneUri = NotificationSettings.getNotificationsRingtone(context); // vibration final boolean isVibrating = NotificationSettings.isNotificationVibrating(context); if (count == 1) { // notify in detail about one episode upcomingEpisodes.moveToFirst(); final String showTitle = upcomingEpisodes.getString(NotificationQuery.SHOW_TITLE); final String airs = Utils.formatToTimeAndDay(upcomingEpisodes.getLong(NotificationQuery.FIRSTAIREDMS), this)[ 0]; final String network = upcomingEpisodes.getString(NotificationQuery.NETWORK); tickerText = getString(R.string.upcoming_show, showTitle); contentTitle = showTitle + " " + Utils.getEpisodeNumber( this, upcomingEpisodes.getInt(NotificationQuery.SEASON), upcomingEpisodes.getInt(NotificationQuery.NUMBER)); contentText = getString(R.string.upcoming_show_detailed, airs, network); Intent notificationIntent = new Intent(context, EpisodesActivity.class); notificationIntent.putExtra( EpisodesActivity.InitBundle.EPISODE_TVDBID, upcomingEpisodes.getInt(NotificationQuery._ID)); notificationIntent.putExtra(KEY_EPISODE_CLEARED_TIME, latestAirtime); contentIntent = PendingIntent.getActivity(context, REQUEST_CODE_SINGLE_EPISODE, notificationIntent, 0); } else if (count > 1) { // notify about multiple episodes tickerText = getString(R.string.upcoming_episodes); contentTitle = getString(R.string.upcoming_episodes_number, count); contentText = getString(R.string.upcoming_display); Intent notificationIntent = new Intent(context, UpcomingRecentActivity.class); notificationIntent.putExtra(KEY_EPISODE_CLEARED_TIME, latestAirtime); contentIntent = PendingIntent.getActivity(context, REQUEST_CODE_MULTIPLE_EPISODES, notificationIntent, 0); } final NotificationCompat.Builder nb = new NotificationCompat.Builder(context); if (AndroidUtils.isJellyBeanOrHigher()) { // JELLY BEAN and above if (count == 1) { // single episode upcomingEpisodes.moveToFirst(); final String imagePath = upcomingEpisodes.getString(NotificationQuery.POSTER); nb.setLargeIcon(ImageProvider.getInstance(context).getImage(imagePath, true)); final String episodeTitle = upcomingEpisodes.getString(NotificationQuery.TITLE); final String episodeSummary = upcomingEpisodes.getString(NotificationQuery.OVERVIEW); final SpannableStringBuilder bigText = new SpannableStringBuilder(); bigText.append(episodeTitle); bigText.setSpan(new ForegroundColorSpan(Color.WHITE), 0, bigText.length(), 0); bigText.append("\n"); bigText.append(episodeSummary); nb.setStyle( new NotificationCompat.BigTextStyle().bigText(bigText).setSummaryText(contentText)); // Action button to check in Intent checkInActionIntent = new Intent(context, QuickCheckInActivity.class); checkInActionIntent.putExtra( QuickCheckInActivity.InitBundle.EPISODE_TVDBID, upcomingEpisodes.getInt(NotificationQuery._ID)); PendingIntent checkInIntent = PendingIntent.getActivity(context, REQUEST_CODE_ACTION_CHECKIN, checkInActionIntent, 0); nb.addAction(R.drawable.ic_action_checkin, getString(R.string.checkin), checkInIntent); } else { // multiple episodes NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(); // display at most the first five final int displayCount = Math.min(count, 5); for (int i = 0; i < displayCount; i++) { if (upcomingEpisodes.moveToPosition(i)) { // add show title, air time and network final SpannableStringBuilder lineText = new SpannableStringBuilder(); lineText.append(upcomingEpisodes.getString(NotificationQuery.SHOW_TITLE)); lineText.setSpan(new ForegroundColorSpan(Color.WHITE), 0, lineText.length(), 0); lineText.append(" "); String airs = Utils.formatToTimeAndDay( upcomingEpisodes.getLong(NotificationQuery.FIRSTAIREDMS), this)[0]; String network = upcomingEpisodes.getString(NotificationQuery.NETWORK); lineText.append(getString(R.string.upcoming_show_detailed, airs, network)); inboxStyle.addLine(lineText); } } // tell if we could not display all episodes if (count > 5) { inboxStyle.setSummaryText(getString(R.string.more, count - 5)); } nb.setStyle(inboxStyle); nb.setContentInfo(String.valueOf(count)); } } else { // ICS and below if (count == 1) { // single episode upcomingEpisodes.moveToFirst(); final String posterPath = upcomingEpisodes.getString(NotificationQuery.POSTER); nb.setLargeIcon(ImageProvider.getInstance(context).getImage(posterPath, true)); } } // If the string is empty, the user chose silent... if (ringtoneUri.length() != 0) { // ...otherwise set the specified ringtone nb.setSound(Uri.parse(ringtoneUri)); } if (isVibrating) { nb.setVibrate(VIBRATION_PATTERN); } nb.setDefaults(Notification.DEFAULT_LIGHTS); nb.setWhen(System.currentTimeMillis()); nb.setAutoCancel(true); nb.setTicker(tickerText); nb.setContentTitle(contentTitle); nb.setContentText(contentText); nb.setContentIntent(contentIntent); nb.setSmallIcon(R.drawable.ic_notification); nb.setPriority(NotificationCompat.PRIORITY_DEFAULT); Intent i = new Intent(this, NotificationService.class); i.putExtra(KEY_EPISODE_CLEARED_TIME, latestAirtime); PendingIntent deleteIntent = PendingIntent.getService(this, 1, i, 0); nb.setDeleteIntent(deleteIntent); // build the notification Notification notification = nb.build(); // use string resource id, always unique within app final NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); nm.notify(R.string.upcoming_show, notification); }
@Override public void bindView(View view, Context context, Cursor cursor) { mShowTvdbId = cursor.getInt(DetailsQuery.REF_SHOW_ID); mSeasonNumber = cursor.getInt(DetailsQuery.SEASON); mEpisodeNumber = cursor.getInt(DetailsQuery.NUMBER); final String showTitle = cursor.getString(DetailsQuery.SHOW_TITLE); final String episodeTitle = cursor.getString(DetailsQuery.TITLE); final long airTime = cursor.getLong(DetailsQuery.FIRSTAIREDMS); // Title and description ((TextView) view.findViewById(R.id.title)).setText(cursor.getString(DetailsQuery.TITLE)); ((TextView) view.findViewById(R.id.description)) .setText(cursor.getString(DetailsQuery.OVERVIEW)); // Show title button TextView showtitle = (TextView) view.findViewById(R.id.showTitle); if (!isShowingShowLink()) { showtitle.setVisibility(View.GONE); } else { showtitle.setVisibility(View.VISIBLE); showtitle.setText(showTitle); showtitle.setOnClickListener( new OnClickListener() { public void onClick(View v) { Intent upIntent = new Intent(getActivity(), OverviewActivity.class); upIntent.putExtra(OverviewFragment.InitBundle.SHOW_TVDBID, mShowTvdbId); upIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(upIntent); getActivity() .overridePendingTransition( R.anim.fragment_slide_right_enter, R.anim.fragment_slide_right_exit); getActivity().finish(); } }); } // Show poster background if (getArguments().getBoolean("showposter")) { final ImageView background = (ImageView) getActivity().findViewById(R.id.episodedetails_background); Utils.setPosterBackground( background, cursor.getString(DetailsQuery.SHOW_POSTER), getActivity()); } SpannableStringBuilder airTimeAndNumberText = new SpannableStringBuilder(); // Air day and time TextView airdateText = (TextView) view.findViewById(R.id.airDay); TextView airtimeText = (TextView) view.findViewById(R.id.airTime); if (airTime != -1) { airdateText.setText(Utils.formatToDate(airTime, getActivity())); String[] dayAndTime = Utils.formatToTimeAndDay(airTime, getActivity()); airTimeAndNumberText .append( getString(R.string.release_date_and_day, dayAndTime[2], dayAndTime[1]) .toUpperCase(Locale.getDefault())) .append(" "); } else { airdateText.setText(R.string.unknown); } // number int numberStartIndex = airTimeAndNumberText.length(); airTimeAndNumberText.append( getString(R.string.season_number, mSeasonNumber).toUpperCase(Locale.getDefault())); airTimeAndNumberText.append(" "); airTimeAndNumberText.append( getString(R.string.episode_number, mEpisodeNumber).toUpperCase(Locale.getDefault())); final int episodeAbsoluteNumber = cursor.getInt(DetailsQuery.ABSOLUTE_NUMBER); if (episodeAbsoluteNumber > 0 && episodeAbsoluteNumber != mEpisodeNumber) { airTimeAndNumberText.append(" (").append(String.valueOf(episodeAbsoluteNumber)).append(")"); } airTimeAndNumberText.setSpan( new TextAppearanceSpan(mContext, R.style.TextAppearance_Small_Dim), numberStartIndex, airTimeAndNumberText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); airtimeText.setText(airTimeAndNumberText); // Last edit date TextView lastEdit = (TextView) view.findViewById(R.id.lastEdit); long lastEditRaw = cursor.getLong(DetailsQuery.LASTEDIT); if (lastEditRaw > 0) { lastEdit.setText( DateUtils.formatDateTime( context, lastEditRaw * 1000, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME)); } else { lastEdit.setText(R.string.unknown); } // Guest stars Utils.setLabelValueOrHide( view.findViewById(R.id.labelGuestStars), (TextView) view.findViewById(R.id.guestStars), Utils.splitAndKitTVDBStrings(cursor.getString(DetailsQuery.GUESTSTARS))); // DVD episode number Utils.setLabelValueOrHide( view.findViewById(R.id.labelDvd), (TextView) view.findViewById(R.id.dvdNumber), cursor.getDouble(DetailsQuery.DVDNUMBER)); // Directors String directors = Utils.splitAndKitTVDBStrings(cursor.getString(DetailsQuery.DIRECTORS)); Utils.setValueOrPlaceholder(view.findViewById(R.id.directors), directors); // Writers String writers = Utils.splitAndKitTVDBStrings(cursor.getString(DetailsQuery.WRITERS)); Utils.setValueOrPlaceholder(view.findViewById(R.id.writers), writers); // Episode image FrameLayout imageContainer = (FrameLayout) view.findViewById(R.id.imageContainer); final String imagePath = cursor.getString(DetailsQuery.IMAGE); onLoadImage(imagePath, imageContainer); imageContainer.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Intent fullscreen = new Intent(getActivity(), FullscreenImageActivity.class); fullscreen.putExtra(FullscreenImageActivity.InitBundle.IMAGE_PATH, imagePath); fullscreen.putExtra(FullscreenImageActivity.InitBundle.IMAGE_TITLE, showTitle); fullscreen.putExtra(FullscreenImageActivity.InitBundle.IMAGE_SUBTITLE, episodeTitle); ActivityCompat.startActivity( getActivity(), fullscreen, ActivityOptionsCompat.makeScaleUpAnimation(v, 0, 0, v.getWidth(), v.getHeight()) .toBundle()); } }); mEpisodeFlag = cursor.getInt(DetailsQuery.WATCHED); // Watched button boolean isWatched = EpisodeTools.isWatched(mEpisodeFlag); ImageButton seenButton = (ImageButton) view.findViewById(R.id.imageButtonBarWatched); seenButton.setImageResource( isWatched ? R.drawable.ic_ticked : Utils.resolveAttributeToResourceId(getActivity().getTheme(), R.attr.drawableWatch)); seenButton.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { onToggleWatched(); fireTrackerEvent("Toggle watched"); } }); CheatSheet.setup(seenButton, isWatched ? R.string.unmark_episode : R.string.mark_episode); // skip button boolean isSkipped = EpisodeTools.isSkipped(mEpisodeFlag); ImageButton skipButton = (ImageButton) view.findViewById(R.id.imageButtonBarSkip); skipButton.setVisibility( isWatched ? View.GONE : View.VISIBLE); // if watched do not allow skipping skipButton.setImageResource( isSkipped ? R.drawable.ic_action_playback_next_highlight : Utils.resolveAttributeToResourceId(getActivity().getTheme(), R.attr.drawableSkip)); skipButton.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { onToggleSkipped(); fireTrackerEvent("Toggle skipped"); } }); CheatSheet.setup(skipButton, isSkipped ? R.string.action_dont_skip : R.string.action_skip); // Collected button mCollected = cursor.getInt(DetailsQuery.COLLECTED) == 1; ImageButton collectedButton = (ImageButton) view.findViewById(R.id.imageButtonBarCollected); collectedButton.setImageResource( mCollected ? R.drawable.ic_collected : Utils.resolveAttributeToResourceId( getActivity().getTheme(), R.attr.drawableCollect)); collectedButton.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { onToggleCollected(); fireTrackerEvent("Toggle collected"); } }); CheatSheet.setup(collectedButton, mCollected ? R.string.uncollect : R.string.collect); // menu button View menuButton = view.findViewById(R.id.imageButtonBarMenu); registerForContextMenu(menuButton); menuButton.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { getActivity().openContextMenu(v); } }); // TVDb rating RelativeLayout ratings = (RelativeLayout) view.findViewById(R.id.ratingbar); String ratingText = cursor.getString(DetailsQuery.RATING); if (ratingText != null && ratingText.length() != 0) { TextView ratingValue = (TextView) ratings.findViewById(R.id.textViewRatingsTvdbValue); ratingValue.setText(ratingText); } ratings.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { onRateOnTrakt(); } }); ratings.setFocusable(true); CheatSheet.setup(ratings, R.string.menu_rate_episode); // fetch trakt ratings onLoadTraktRatings(ratings, true); // Google Play button View playButton = view.findViewById(R.id.buttonGooglePlay); ServiceUtils.setUpGooglePlayButton(showTitle + " " + episodeTitle, playButton, TAG); // Amazon button View amazonButton = view.findViewById(R.id.buttonAmazon); ServiceUtils.setUpAmazonButton(showTitle + " " + episodeTitle, amazonButton, TAG); // YouTube button View youtubeButton = view.findViewById(R.id.buttonYouTube); ServiceUtils.setUpYouTubeButton(showTitle + " " + episodeTitle, youtubeButton, TAG); // IMDb button String imdbId = cursor.getString(DetailsQuery.IMDBID); if (TextUtils.isEmpty(imdbId)) { // fall back to show IMDb id imdbId = cursor.getString(DetailsQuery.SHOW_IMDBID); } ServiceUtils.setUpImdbButton( imdbId, view.findViewById(R.id.buttonShowInfoIMDB), TAG, getActivity()); // TVDb button final int seasonTvdbId = cursor.getInt(DetailsQuery.REF_SEASON_ID); ServiceUtils.setUpTvdbButton( mShowTvdbId, seasonTvdbId, getEpisodeTvdbId(), view.findViewById(R.id.buttonTVDB), TAG); // trakt button ServiceUtils.setUpTraktButton( mShowTvdbId, mSeasonNumber, mEpisodeNumber, view.findViewById(R.id.buttonTrakt), TAG); // Web search button View webSearch = view.findViewById(R.id.buttonWebSearch); ServiceUtils.setUpWebSearchButton(showTitle + " " + episodeTitle, webSearch, TAG); // trakt shouts button view.findViewById(R.id.buttonShouts) .setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(getActivity(), TraktShoutsActivity.class); intent.putExtras( TraktShoutsActivity.createInitBundleEpisode( mShowTvdbId, mSeasonNumber, mEpisodeNumber, episodeTitle)); startActivity(intent); fireTrackerEvent("Comments"); } }); // Check in button final int episodeTvdbId = cursor.getInt(DetailsQuery._ID); View checkinButton = view.findViewById(R.id.imageButtonBarCheckin); checkinButton.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { // display a check-in dialog CheckInDialogFragment f = CheckInDialogFragment.newInstance(getActivity(), episodeTvdbId); f.show(getFragmentManager(), "checkin-dialog"); fireTrackerEvent("Check-In"); } }); CheatSheet.setup(checkinButton); }
@Override public View getView(int position, View convertView, ViewGroup parent) { if (!mDataValid) { throw new IllegalStateException("this should only be called when the cursor is valid"); } if (!mCursor.moveToPosition(position)) { throw new IllegalStateException("couldn't move cursor to position " + position); } final ViewHolder viewHolder; if (convertView == null) { convertView = newView(mContext, mCursor, parent); viewHolder = new ViewHolder(); viewHolder.watchedBox = (WatchedBox) convertView.findViewById(R.id.watchedBoxEpisode); viewHolder.episodeTitle = (TextView) convertView.findViewById(R.id.textViewEpisodeTitle); viewHolder.episodeNumber = (TextView) convertView.findViewById(R.id.textViewEpisodeNumber); viewHolder.episodeAirdate = (TextView) convertView.findViewById(R.id.textViewEpisodeAirdate); viewHolder.episodeAlternativeNumbers = (TextView) convertView.findViewById(R.id.textViewEpisodeAlternativeNumbers); viewHolder.collected = (ImageView) convertView.findViewById(R.id.imageViewCollected); viewHolder.contextMenu = (ImageView) convertView.findViewById(R.id.imageViewContextMenu); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } // episode title viewHolder.episodeTitle.setText(mCursor.getString(EpisodesQuery.TITLE)); // number final int episodeNumber = mCursor.getInt(EpisodesQuery.NUMBER); viewHolder.episodeNumber.setText(String.valueOf(episodeNumber)); // watched box viewHolder.watchedBox.setEpisodeFlag(mCursor.getInt(EpisodesQuery.WATCHED)); final int episodeId = mCursor.getInt(EpisodesQuery._ID); viewHolder.watchedBox.setOnClickListener( new OnClickListener() { public void onClick(View v) { WatchedBox box = (WatchedBox) v; mOnFlagListener.onFlagEpisodeWatched( episodeId, episodeNumber, !EpisodeTools.isWatched(box.getEpisodeFlag())); } }); CheatSheet.setup( viewHolder.watchedBox, EpisodeTools.isWatched(viewHolder.watchedBox.getEpisodeFlag()) ? R.string.unmark_episode : R.string.mark_episode); // collected tag viewHolder.collected.setVisibility( mCursor.getInt(EpisodesQuery.COLLECTED) == 1 ? View.VISIBLE : View.INVISIBLE); // alternative numbers StringBuilder altNumbers = new StringBuilder(); int absoluteNumber = mCursor.getInt(EpisodesQuery.ABSOLUTE_NUMBER); if (absoluteNumber > 0) { altNumbers .append(mContext.getString(R.string.episode_number_absolute)) .append(" ") .append(absoluteNumber); } double dvdNumber = mCursor.getDouble(EpisodesQuery.DVDNUMBER); if (dvdNumber > 0) { if (altNumbers.length() != 0) { altNumbers.append(" | "); } altNumbers .append(mContext.getString(R.string.episode_number_disk)) .append(" ") .append(dvdNumber); } viewHolder.episodeAlternativeNumbers.setText(altNumbers); // air date long airtime = mCursor.getLong(EpisodesQuery.FIRSTAIREDMS); if (airtime != -1) { viewHolder.episodeAirdate.setText(Utils.formatToTimeAndDay(airtime, mContext)[2]); } else { viewHolder.episodeAirdate.setText(mContext.getString(R.string.episode_firstaired_unknown)); } // context menu viewHolder.contextMenu.setOnClickListener(mOnClickListener); return convertView; }