/*
* TV-Browser for Android
* Copyright (C) 2013 René Mach (rene@tvbrowser.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to use, copy, modify or merge the Software,
* furthermore to publish and distribute the Software free of charge without modifications and to
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.tvbrowser.tvbrowser;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.TimeZone;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.GZIPInputStream;
import org.tvbrowser.content.TvBrowserContentProvider;
import org.tvbrowser.devplugin.PluginDefinition;
import org.tvbrowser.devplugin.PluginHandler;
import org.tvbrowser.devplugin.PluginServiceConnection;
import org.tvbrowser.filter.ActivityFilterListEdit;
import org.tvbrowser.filter.FilterValues;
import org.tvbrowser.filter.FilterValuesCategories;
import org.tvbrowser.filter.FilterValuesChannels;
import org.tvbrowser.filter.FilterValuesKeyword;
import org.tvbrowser.settings.PluginPreferencesActivity;
import org.tvbrowser.settings.SettingConstants;
import org.tvbrowser.settings.TvbPreferencesActivity;
import org.tvbrowser.utils.CompatUtils;
import org.tvbrowser.utils.IOUtils;
import org.tvbrowser.utils.PrefUtils;
import org.tvbrowser.utils.ProgramUtils;
import org.tvbrowser.utils.UiUtils;
import org.xml.sax.XMLReader;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.NotificationManager;
import android.app.ProgressDialog;
import android.app.SearchManager;
import android.app.TimePickerDialog;
import android.content.BroadcastReceiver;
import android.content.ContentProviderClient;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources.Theme;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetricsInt;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.util.SparseArrayCompat;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.Tab;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.text.Editable;
import android.text.Html;
import android.text.Html.TagHandler;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.RelativeSizeSpan;
import android.text.style.ReplacementSpan;
import android.text.style.URLSpan;
import android.util.Base64;
import android.util.Log;
import android.util.TypedValue;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.WindowManager.BadTokenException;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.NumberPicker;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.SeekBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
import billing.util.IabHelper;
import billing.util.IabHelper.QueryInventoryFinishedListener;
import billing.util.IabResult;
import billing.util.Inventory;
import billing.util.Purchase;
import billing.util.SkuDetails;
import com.example.android.listviewdragginganimation.DynamicListView;
import com.example.android.listviewdragginganimation.StableArrayAdapter;
import de.epgpaid.EPGpaidDataConnection;
public class TvBrowser extends AppCompatActivity implements
ActionBar.TabListener {
private static final boolean TEST_VERSION = false;
private static final int ID_LINKIFY_DISABLED = 0;
private static final int SHOW_PREFERENCES = 1;
private static final int OPEN_FILTER_EDIT = 2;
private static final int INSTALL_PLUGIN = 3;
private static final int SHOW_PLUGIN_PREFERENCES = 4;
private HashSet<FilterValues> mCurrentFilter;
private Set<String> mCurrentFilterId;
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link android.support.v4.app.FragmentPagerAdapter} derivative, which will
* keep every loaded fragment in memory. If this becomes too memory intensive,
* it may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
private SectionsPagerAdapter mSectionsPagerAdapter;
private boolean updateRunning;
private boolean selectingChannels;
private ActionBar actionBar;
private boolean mSearchExpanded;
/**
* The {@link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
private Handler handler;
private Timer mTimer;
private MenuItem mFilterItem;
private MenuItem mCreateFavorite;
private MenuItem mUpdateItem;
private MenuItem mSendDataUpdateLogItem;
private MenuItem mDeleteDataUpdateLogItem;
private MenuItem mSendReminderLogItem;
private MenuItem mDeleteReminderLogItem;
private MenuItem mSendPluginLogItem;
private MenuItem mDeletePluginLogItem;
private MenuItem mScrollTimeItem;
private MenuItem mPluginPreferencesMenuItem;
private MenuItem mDebugMenuItem;
private MenuItem mPauseReminder;
private MenuItem mContinueReminder;
private static final Calendar mRundate;
private static int[] SCROLL_IDS = new int[0];
private static int[] SCROLL_TIMES;
private boolean mSelectionNumberChanged;
private boolean mIsActive;
private boolean mProgramsListWasShow;
private int mLastSelectedTab;
private static String ALL_VALUE;
private Menu mOptionsMenu;
private Stack<ProgramsListState> mProgamListStateStack;
private BroadcastReceiver mUpdateDoneBroadcastReceiver;
private long mCreateTime;
private long mResumeTime;
private IabHelper mHelper;
private int mProgramListChannelId = FragmentProgramsList.NO_CHANNEL_SELECTION_ID;
private long mProgramListScrollTime = -1;
private long mProgramListScrollEndTime = -1;
// private int mCurrentDay;
static {
mRundate = Calendar.getInstance();
mRundate.set(Calendar.YEAR, 2019);
mRundate.set(Calendar.MONTH, Calendar.DECEMBER);
mRundate.set(Calendar.DAY_OF_MONTH, 31);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean(SettingConstants.UPDATE_RUNNING_KEY, updateRunning);
outState.putBoolean(SettingConstants.SELECTION_CHANNELS_KEY, selectingChannels);
super.onSaveInstanceState(outState);
}
private final boolean addUserColor(SharedPreferences pref, Editor edit, int defaultColorKey, int colorKey, int userColorKey) {
int defaultColor = ContextCompat.getColor(this, defaultColorKey);
int color = pref.getInt(getString(colorKey), defaultColor);
edit.putInt(getString(userColorKey), color);
return defaultColor != color;
}
@Override
protected void onApplyThemeResource(Theme theme, int resid, boolean first) {
PrefUtils.initialize(TvBrowser.this);
if(PrefUtils.getIntValueWithDefaultKey(R.string.OLD_VERSION, R.integer.old_version_default) < 283) {
Editor edit = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this).edit();
edit.putBoolean(getString(R.string.DARK_STYLE), true);
edit.commit();
}
SettingConstants.IS_DARK_THEME = PrefUtils.getBooleanValue(R.string.DARK_STYLE, R.bool.dark_style_default);
resid = UiUtils.getThemeResourceId();
super.onApplyThemeResource(theme, resid, first);
}
private static final int INFO_TYPE_NOTHING = 0;
private static final int INFO_TYPE_VERSION = 1;
private static final int INFO_TYPE_NEWS = 2;
private int mInfoType;
private static final class HandlerWrapper {
private Handler mHandler;
public HandlerWrapper(Handler handler) {
mHandler = handler;
}
public boolean post(Runnable r) {
Log.d("info6", "post: " + r);
StackTraceElement[] els = Thread.currentThread().getStackTrace();
for(StackTraceElement el : els) {
Log.d("info6", el.toString());
}
return mHandler.post(r);
}
public boolean postDelayed(Runnable r, int delayMillis) {
Log.d("info6", "postDelayed: " + r);
return false;//mHandler.postDelayed(r, delayMillis);
}
}
private void checkAppReplacingState() {
Log.d("info6", System.currentTimeMillis()+" checkAppReplacingState START");
if (getResources() == null) {
Log.d("org.tvbrowser.tvbrowser", "app is replacing...kill");
android.os.Process.killProcess(android.os.Process.myPid());
}
Log.d("info6", System.currentTimeMillis()+" checkAppReplacingState END");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
checkAppReplacingState();
handler = new Handler();
mCurrentFilter = new HashSet<FilterValues>();
mCurrentFilterId = new HashSet<String>();
mInfoType = INFO_TYPE_NOTHING;
PrefUtils.initialize(TvBrowser.this);
PrefUtils.updateKnownOpenDate(getApplicationContext());
Intent start = getIntent();
if(start != null && start.hasExtra(SettingConstants.CHANNEL_ID_EXTRA)) {
mProgramListChannelId = start.getIntExtra(SettingConstants.CHANNEL_ID_EXTRA,FragmentProgramsList.NO_CHANNEL_SELECTION_ID);
mProgramListScrollTime = start.getLongExtra(SettingConstants.EXTRA_START_TIME,-1);
mProgramListScrollEndTime = start.getLongExtra(SettingConstants.EXTRA_END_TIME,-1);
}
/*
* Hack to force overflow menu button to be shown from:
* http://stackoverflow.com/questions/9286822/how-to-force-use-of-overflow-menu-on-devices-with-menu-button
*/
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
if(menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
}
} catch (Exception ex) {
// Ignore
}
/*
Editor edit3 = PrefUtils.getSharedPreferences(PrefUtils.TYPE_PREFERENCES_SHARED_GLOBAL, getApplicationContext()).edit();
edit3.remove(getString(R.string.LAST_DATA_UPDATE));
edit3.putInt(getString(R.string.PREF_AUTO_UPDATE_START_TIME), 800);
edit3.putLong(getString(R.string.AUTO_UPDATE_CURRENT_START_TIME), System.currentTimeMillis()+2000*60);
edit3.commit();*/
try {
PackageInfo pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
//PrefUtils.getSharedPreferences(PrefUtils.TYPE_PREFERENCES_SHARED_GLOBAL, getApplicationContext()).edit().remove(getString(R.string.CURRENT_FILTER_ID)).commit();
int oldVersion = PrefUtils.getIntValueWithDefaultKey(R.string.OLD_VERSION, R.integer.old_version_default);
if(oldVersion == 402) {
final SharedPreferences pref = PrefUtils.getSharedPreferences(PrefUtils.TYPE_PREFERENCES_FILTERS, getApplicationContext());
pref.edit().remove(getString(R.string.PREF_REMINDER_AS_ALARM_CLOCK)).commit();
ServiceUpdateReminders.startReminderUpdate(getApplicationContext());
}
if(oldVersion < 339) {
startService(new Intent(TvBrowser.this,ServiceChannelCleaner.class));
}
if(oldVersion < 332) {
PrefUtils.updateDataMetaData(getApplicationContext());
PrefUtils.updateChannelSelectionState(getApplicationContext());
}
if(oldVersion < 322) {
SharedPreferences pref = PrefUtils.getSharedPreferences(PrefUtils.TYPE_PREFERENCES_FILTERS, getApplicationContext());
Editor edit = pref.edit();
Map<String,?> filterMap = pref.getAll();
Set<String> keys = filterMap.keySet();
for(String key : keys) {
if(!key.contains(FilterValues.SEPARATOR_CLASS)) {
String values = (String)filterMap.get(key);
edit.remove(key);
edit.putString(FilterValuesChannels.class.getCanonicalName()+FilterValues.SEPARATOR_CLASS+key, values);
}
}
edit.commit();
}
if(oldVersion > getResources().getInteger(R.integer.old_version_default) && oldVersion < 314) {
new Thread("READ SYNCED PROGRAMS ONCE FOR ICON") {
@Override
public void run() {
if(IOUtils.isDatabaseAccessible(TvBrowser.this)) {
Cursor synced = getContentResolver().query(TvBrowserContentProvider.CONTENT_URI_DATA, new String[] {TvBrowserContentProvider.KEY_ID}, TvBrowserContentProvider.DATA_KEY_MARKING_SYNC, null, TvBrowserContentProvider.KEY_ID);
try {
if(IOUtils.prepareAccess(synced)) {
int idColumn = synced.getColumnIndex(TvBrowserContentProvider.KEY_ID);
ArrayList<String> syncIdList = new ArrayList<String>();
while(synced.moveToNext()) {
syncIdList.add(String.valueOf(synced.getLong(idColumn)));
}
ProgramUtils.addSyncIds(getApplicationContext(), syncIdList);
}
}finally {
IOUtils.close(synced);
}
}
}
}.start();
}
if(oldVersion > getResources().getInteger(R.integer.old_version_default) && oldVersion < 309) {
new Thread("READ REMINDERS ONCE FOR ICON") {
@Override
public void run() {
if(IOUtils.isDatabaseAccessible(TvBrowser.this)) {
Cursor reminders = getContentResolver().query(TvBrowserContentProvider.CONTENT_URI_DATA, new String[] {TvBrowserContentProvider.KEY_ID}, TvBrowserContentProvider.DATA_KEY_MARKING_REMINDER + " OR " + TvBrowserContentProvider.DATA_KEY_MARKING_FAVORITE_REMINDER, null, TvBrowserContentProvider.KEY_ID);
try {
if(IOUtils.prepareAccess(reminders)) {
int idColumn = reminders.getColumnIndex(TvBrowserContentProvider.KEY_ID);
ArrayList<String> reminderIdList = new ArrayList<String>();
while(reminders.moveToNext()) {
reminderIdList.add(String.valueOf(reminders.getLong(idColumn)));
}
ProgramUtils.addReminderIds(getApplicationContext(), reminderIdList);
}
}finally {
IOUtils.close(reminders);
}
}
}
}.start();
}
if(oldVersion < 304) {
Set<String> favoritesSet = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this).getStringSet("FAVORITE_LIST", new HashSet<String>());
int id = 1000;
for(String favorite : favoritesSet) {
Favorite fav = new Favorite(id++,favorite);
if(fav.isValid()) {
fav.save(getApplicationContext());
}
else {
Favorite.handleFavoriteMarking(TvBrowser.this, fav, Favorite.TYPE_MARK_REMOVE);
}
}
Editor edit = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this).edit();
edit.remove("FAVORITE_LIST");
edit.commit();
}
if(oldVersion < 204) {
int firstTime = PrefUtils.getStringValueAsInt(R.string.PREF_REMINDER_TIME, R.string.pref_reminder_time_default);
boolean remindAgain = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this).getBoolean("PREF_REMIND_AGAIN_AT_START", false);
Editor edit = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this).edit();
edit.remove("PREF_REMIND_AGAIN_AT_START");
edit.commit();
if(remindAgain && firstTime > 0) {
edit.putString(getString(R.string.PREF_REMINDER_TIME_SECOND), getString(R.string.pref_reminder_time_default));
edit.commit();
Intent updateAlarmValues = new Intent(UpdateAlarmValue.class.getCanonicalName());
sendBroadcast(updateAlarmValues);
}
}
if(oldVersion < 218) {
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this);
Editor edit = pref.edit();
boolean userDefined = addUserColor(pref,edit,R.color.pref_color_on_air_background_tvb_style_default,R.string.PREF_COLOR_ON_AIR_BACKGROUND,R.string.PREF_COLOR_ON_AIR_BACKGROUND_USER_DEFINED);
userDefined = addUserColor(pref,edit,R.color.pref_color_on_air_progress_tvb_style_default,R.string.PREF_COLOR_ON_AIR_PROGRESS,R.string.PREF_COLOR_ON_AIR_PROGRESS_USER_DEFINED) || userDefined;
userDefined = addUserColor(pref,edit,R.color.pref_color_mark_tvb_style_default,R.string.PREF_COLOR_MARKED,R.string.PREF_COLOR_MARKED_USER_DEFINED) || userDefined;
userDefined = addUserColor(pref,edit,R.color.pref_color_mark_favorite_tvb_style_default,R.string.PREF_COLOR_FAVORITE,R.string.PREF_COLOR_FAVORITE) || userDefined;
userDefined = addUserColor(pref,edit,R.color.pref_color_mark_reminder_tvb_style_default,R.string.PREF_COLOR_REMINDER,R.string.PREF_COLOR_REMINDER_USER_DEFINED) || userDefined;
userDefined = addUserColor(pref,edit,R.color.pref_color_mark_sync_tvb_style_favorite_default,R.string.PREF_COLOR_SYNC,R.string.PREF_COLOR_SYNC_USER_DEFINED) || userDefined;
if(userDefined) {
edit.putString(getString(R.string.PREF_COLOR_STYLE), "0");
}
edit.commit();
}
if(oldVersion < 242) {
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this);
Editor edit = pref.edit();
if(pref.contains("PREF_WIDGET_BACKGROUND_TRANSPARENCY") && !pref.getBoolean("PREF_WIDGET_BACKGROUND_TRANSPARENCY", true)) {
edit.remove("PREF_WIDGET_BACKGROUND_TRANSPARENCY");
edit.putString(getString(R.string.PREF_WIDGET_BACKGROUND_TRANSPARENCY_HEADER), "0");
edit.putString(getString(R.string.PREF_WIDGET_BACKGROUND_TRANSPARENCY_LIST), "0");
edit.putBoolean(getString(R.string.PREF_WIDGET_BACKGROUND_ROUNDED_CORNERS), false);
}
if(pref.contains("SELECTED_TV_CHANNELS_LIST")) {
edit.remove("SELECTED_TV_CHANNELS_LIST");
}
if(pref.contains("SELECTED_RADIO_CHANNELS_LIST")) {
edit.remove("SELECTED_RADIO_CHANNELS_LIST");
}
if(pref.contains("SELECTED_CINEMA_CHANNELS_LIST")) {
edit.remove("SELECTED_CINEMA_CHANNELS_LIST");
}
edit.commit();
}
if(oldVersion < 284 && PrefUtils.getStringValue(R.string.PREF_PROGRAM_LISTS_DIVIDER_SIZE, R.string.pref_program_lists_divider_size_default).equals(getString(R.string.divider_small))) {
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this);
final Editor edit = pref.edit();
edit.remove(getString(R.string.PREF_PROGRAM_LISTS_DIVIDER_SIZE));
edit.commit();
}
if(oldVersion < 287 && PrefUtils.getBooleanValue(R.string.PREF_WIDGET_BACKGROUND_ROUNDED_CORNERS, true)) {
final Editor edit = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this).edit();
edit.remove(getString(R.string.PREF_WIDGET_BACKGROUND_ROUNDED_CORNERS));
edit.commit();
UiUtils.updateImportantProgramsWidget(getApplicationContext());
UiUtils.updateRunningProgramsWidget(getApplicationContext());
}
if(oldVersion < 369) {
final Editor edit = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this).edit();
edit.putBoolean(getString(R.string.PREF_EPGPAID_FIRST_DOWNLOAD_DONE), false);
edit.commit();
}
if(oldVersion < 379) {
final HashSet<String> values = new HashSet<String>();
final String currentFilterId = PrefUtils.getStringValue(R.string.CURRENT_FILTER_ID, null);
if(currentFilterId != null) {
values.add(currentFilterId);
}
final Editor edit = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this).edit();
edit.putStringSet(getString(R.string.CURRENT_FILTER_ID), values);
edit.commit();
}
if(oldVersion > getResources().getInteger(R.integer.old_version_default) && oldVersion < pInfo.versionCode && PrefUtils.getBooleanValue(R.string.PREF_INFO_VERSION_UPDATE_SHOW, R.bool.pref_info_version_update_show_default)) {
mInfoType = INFO_TYPE_VERSION;
/*handler.postDelayed(new Runnable() {
@Override
public void run() {
showVersionInfo(true);
}
}, 2000);*/
}
else if(oldVersion != getResources().getInteger(R.integer.old_version_default) && PrefUtils.getBooleanValue(R.string.PREF_NEWS_SHOW, R.bool.pref_news_show_default)) {
long lastShown = PrefUtils.getLongValue(R.string.NEWS_DATE_LAST_SHOWN, 0);
long lastKnown = PrefUtils.getLongValue(R.string.NEWS_DATE_LAST_KNOWN, 0);
Log.d("info6", "lastShown " + new Date(lastShown) + " " + "lastKnown " + new Date(lastKnown));
if(lastShown < lastKnown) {
mInfoType = INFO_TYPE_NEWS;
}
/*handler.postDelayed(new Runnable() {
@Override
public void run() {
showNews();
}
}, 2000);*/
}
if(oldVersion != pInfo.versionCode) {
Editor edit = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this).edit();
edit.putInt(getString(R.string.OLD_VERSION), pInfo.versionCode);
edit.commit();
}
} catch (NameNotFoundException e) {}
super.onCreate(savedInstanceState);
SettingConstants.initializeLogoMap(TvBrowser.this,false);
setContentView(R.layout.activity_tv_browser);
mProgamListStateStack = new Stack<ProgramsListState>();
ALL_VALUE = getResources().getString(R.string.filter_channel_all);
if(savedInstanceState != null) {
updateRunning = savedInstanceState.getBoolean(SettingConstants.UPDATE_RUNNING_KEY, false);
selectingChannels = savedInstanceState.getBoolean(SettingConstants.SELECTION_CHANNELS_KEY, false);
}
// Set up the action bar.
actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
if(SettingConstants.isReminderPaused(TvBrowser.this)) {
actionBar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#4e0002")));
}
else {
actionBar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#212021")));
}
// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(
getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOffscreenPageLimit(3);
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager
.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
if(position < actionBar.getTabCount()) {
actionBar.setSelectedNavigationItem(position);
Fragment fragment = mSectionsPagerAdapter.getRegisteredFragment(position);
if(fragment instanceof FragmentProgramTable) {
((FragmentProgramTable)fragment).firstLoad(getLayoutInflater());
((FragmentProgramTable)fragment).scrollToTime(0, mScrollTimeItem);
}
if(mFilterItem != null) {
mFilterItem.setVisible(!(fragment instanceof FragmentFavorites) && !mSearchExpanded);
}
if(mCreateFavorite != null) {
mCreateFavorite.setVisible(fragment instanceof FragmentFavorites && !mSearchExpanded);
}
mProgramsListWasShow = false;
if(position != 1) {
mProgamListStateStack.clear();
}
}
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by
// the adapter. Also specify this Activity object, which implements
// the TabListener interface, as the callback (listener) for when
// this tab is selected.
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i)).setTabListener(this));
}
int startTab = Integer.parseInt(PrefUtils.getStringValue(R.string.TAB_TO_SHOW_AT_START, R.string.tab_to_show_at_start_default));
if(mSectionsPagerAdapter.getCount() > startTab) {
mViewPager.setCurrentItem(startTab);
}
mCreateTime = System.currentTimeMillis();
IOUtils.postDelayedInSeparateThread("LOAD PLUGINS WAITING THREAD", new Runnable() {
@Override
public void run() {
PluginHandler.loadPlugins(getApplicationContext());
}
}, 2000);
IOUtils.handleDataUpdatePreferences(TvBrowser.this);
IOUtils.setDataTableRefreshTime(TvBrowser.this);
}
@Override
protected void onPause() {
long timeDiff = System.currentTimeMillis() - mResumeTime + PrefUtils.getLongValueWithDefaultKey(R.string.PREF_RUNNING_TIME, R.integer.pref_running_time_default);
Editor edit = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this).edit();
edit.putLong(getString(R.string.PREF_RUNNING_TIME), timeDiff);
edit.commit();
mIsActive = false;
if(mTimer != null) {
mTimer.cancel();
}
if(mUpdateDoneBroadcastReceiver != null) {
// stupid workaround for not available receiver registered check
try {
TvBrowser.this.unregisterReceiver(mUpdateDoneBroadcastReceiver);
}catch(IllegalArgumentException e) {}
}
super.onPause();
}
private void showTerms() {
if(!PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getBoolean(SettingConstants.EULA_ACCEPTED, false)) {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.terms_of_use);
ScrollView layout = (ScrollView)getLayoutInflater().inflate(R.layout.dialog_terms, getParentViewGroup(), false);
((TextView)layout.findViewById(R.id.terms_license)).setText(Html.fromHtml(getResources().getString(R.string.license)));
builder.setView(layout);
builder.setPositiveButton(R.string.terms_of_use_accept, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Editor edit = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit();
edit.putBoolean(SettingConstants.EULA_ACCEPTED, true);
edit.commit();
handleResume();
}
});
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
System.exit(0);
}
});
builder.setCancelable(false);
showAlertDialog(builder);
}
else {
handleResume();
}
}
@Override
protected void onResume() {
super.onResume();
mResumeTime = System.currentTimeMillis();
mIsActive = true;
if(mUpdateItem != null && !TvDataUpdateService.isRunning()) {
updateProgressIcon(false);
}
if(mResumeTime - mCreateTime > 5000) {
IOUtils.postDelayedInSeparateThread("LOAD PLUGINS WAITING THREAD", new Runnable() {
@Override
public void run() {
PluginHandler.loadPlugins(getApplicationContext());
}
}, 2000);
}
/* if(TEST_VERSION) {
Editor edit = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this).edit();
edit.putLong(getString(R.string.AUTO_UPDATE_CURRENT_START_TIME), System.currentTimeMillis() + 60000);
edit.commit();
IOUtils.handleDataUpdatePreferences(TvBrowser.this);
//R.string.AUTO_UPDATE_CURRENT_START_TIME
}*/
SettingConstants.ORIENTATION = getResources().getConfiguration().orientation;
mUpdateDoneBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//PluginHandler.loadFirstAndLastProgramId(TvBrowser.this.getApplicationContext());
updateProgressIcon(false);
handler.post(new Runnable() {
@Override
public void run() {
showNews();
}
});
}
};
if(PrefUtils.isNewDate(getApplicationContext())) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
Log.d("info6", "SEND DATA UPDATE DONE AFTER DATE CHANGE " + System.currentTimeMillis());
Intent refresh = new Intent(SettingConstants.DATA_UPDATE_DONE);
TvBrowser.this.sendBroadcast(refresh);
}
}, 2000);
PrefUtils.updateKnownOpenDate(getApplicationContext());
}
IntentFilter filter = new IntentFilter(SettingConstants.DATA_UPDATE_DONE);
TvBrowser.this.registerReceiver(mUpdateDoneBroadcastReceiver, filter);
mCurrentFilterId = PrefUtils.getStringSetValue(R.string.CURRENT_FILTER_ID, new HashSet<String>());
mCurrentFilter.clear();
if(!mCurrentFilterId.isEmpty()) {
for(final String currentFilterIds : mCurrentFilterId) {
final FilterValues filterValue = FilterValues.load(currentFilterIds,TvBrowser.this);
if(filterValue != null) {
mCurrentFilter.add(filterValue);
}
}
/*
mCurrentFilter = FilterValues.load(mCurrentFilterId,TvBrowser.this);
if(mCurrentFilter instanceof FilterValuesChannels && mProgramListChannelId != FragmentProgramsList.NO_CHANNEL_SELECTION_ID && !getFilterSelection(true).contains(String.valueOf(mProgramListChannelId)) && !mCurrentFilterId.equals(SettingConstants.ALL_FILTER_ID)) {
mCurrentFilter = FilterValues.load(SettingConstants.ALL_FILTER_ID, TvBrowser.this);
updateChannelFilter(mCurrentFilter,R.drawable.ic_filter_default);
}
if(mCurrentFilter == null) {
mCurrentFilter = FilterValues.load(SettingConstants.ALL_FILTER_ID, TvBrowser.this);
}
mCurrentFilterId = mCurrentFilter.getId();*/
}
updateFilter(false);
/* else {
mCurrentFilter = FilterValues.load(SettingConstants.ALL_FILTER_ID, TvBrowser.this);
}*/
if(mProgramListChannelId != FragmentProgramsList.NO_CHANNEL_SELECTION_ID) {
showProgramsListTab(false);
}
// LogUtils.logProgramData(getApplicationContext(), TvBrowserContentProvider.DATA_KEY_TITLE + " LIKE \"%Sportschau%\"", TvBrowserContentProvider.DATA_KEY_DURATION_IN_MINUTES);
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
showTerms();
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
if(mProgamListStateStack != null) {
mProgamListStateStack.clear();
}
if(intent != null && intent.hasExtra(SettingConstants.CHANNEL_ID_EXTRA)) {
int channelId = intent.getIntExtra(SettingConstants.CHANNEL_ID_EXTRA,0);
if(!getFilterSelection(true).contains(String.valueOf(channelId)) && !mCurrentFilter.isEmpty()) {
clearChannelFilters();
}
final Intent showChannel = new Intent(SettingConstants.SHOW_ALL_PROGRAMS_FOR_CHANNEL_INTENT);
showChannel.putExtra(SettingConstants.CHANNEL_ID_EXTRA, channelId);
showChannel.putExtra(SettingConstants.EXTRA_START_TIME, intent.getLongExtra(SettingConstants.EXTRA_START_TIME,0));
showChannel.putExtra(SettingConstants.EXTRA_END_TIME, intent.getLongExtra(SettingConstants.EXTRA_END_TIME,-1));
showChannel.putExtra(SettingConstants.NO_BACK_STACKUP_EXTRA, true);
handler.postDelayed(new Runnable() {
@Override
public void run() {
LocalBroadcastManager.getInstance(TvBrowser.this).sendBroadcastSync(showChannel);
}
}, 1000);
}
}
private void showAlertDialog(AlertDialog.Builder dialogBuilder) {
showAlertDialog(dialogBuilder, false);
}
private void showAlertDialog(AlertDialog.Builder dialogBuilder, boolean linkifyMessage) {
showAlertDialog(dialogBuilder, linkifyMessage, null);
}
private void showAlertDialog(AlertDialog.Builder dialogBuilder, boolean linkifyMessage, Runnable postShowingRunnable) {
showAlertDialog(dialogBuilder, linkifyMessage, postShowingRunnable, null);
}
private void showAlertDialog(AlertDialog.Builder dialogBuilder, boolean linkifyMessage, Runnable postShowingRunnable, Runnable throwableRunnable) {
showAlertDialog(dialogBuilder, linkifyMessage ? android.R.id.message : ID_LINKIFY_DISABLED, postShowingRunnable, throwableRunnable);
}
private void showAlertDialog(AlertDialog.Builder dialogBuilder, int linkifyId, Runnable postShowingRunnable, Runnable throwableRunnable) {
final AlertDialog dialog = dialogBuilder.create();
showAlertDialog(dialog, linkifyId, postShowingRunnable, throwableRunnable);
}
private void showAlertDialog(AlertDialog dialog) {
showAlertDialog(dialog, false);
}
private void showAlertDialog(AlertDialog dialog, boolean linkifyMessage) {
showAlertDialog(dialog, false, null);
}
private void showAlertDialog(AlertDialog dialog, boolean linkifyMessage, Runnable postShowingRunnable) {
showAlertDialog(dialog, linkifyMessage, postShowingRunnable, null);
}
private void showAlertDialog(AlertDialog dialog, boolean linkifyMessage, Runnable postShowingRunnable, Runnable throwableRunnable) {
showAlertDialog(dialog, linkifyMessage ? android.R.id.message : ID_LINKIFY_DISABLED, postShowingRunnable, throwableRunnable);
}
private void showAlertDialog(AlertDialog dialog, int linkifyId, Runnable postShowingRunnable, Runnable throwableRunnable) {
try {
if(TvBrowser.this.getWindow().getDecorView().isShown()) {
dialog.show();
if(linkifyId != ID_LINKIFY_DISABLED) {
final TextView test = ((TextView)dialog.findViewById(linkifyId));
if(test != null) {
test.setMovementMethod(LinkMovementMethod.getInstance());
}
}
if(postShowingRunnable != null) {
postShowingRunnable.run();
}
}
}catch(Throwable t) {
if(throwableRunnable != null) {
throwableRunnable.run();
}
}
}
private static boolean SHOWING_EPGPAID_INFO = false;
private static boolean SHOWING_DONATION_INFO = false;
private void showEpgPaidInfo() {
Log.d("info6", "showEpgPaidInfo");
final long firstStart = PrefUtils.getLongValue(R.string.PREF_EPGPAID_FIRST_START, -1);
if(firstStart == -1) {
final Editor edit = PrefUtils.getSharedPreferences(PrefUtils.TYPE_PREFERENCES_SHARED_GLOBAL, TvBrowser.this).edit();
edit.putLong(getString(R.string.PREF_EPGPAID_FIRST_START), System.currentTimeMillis());
edit.commit();
} else if(!SHOWING_EPGPAID_INFO && !PrefUtils.getBooleanValue(R.string.PREF_EPGPAID_INFO_SHOWN, R.bool.pref_epgpaid_info_shown_default) && (System.currentTimeMillis() - (9 * 24 * 60 * 60000L)) > firstStart
&& PrefUtils.getStringValue(R.string.PREF_EPGPAID_USER, "").trim().length() == 0 && PrefUtils.getStringValue(R.string.PREF_EPGPAID_PASSWORD, "").trim().length() == 0) {
final AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.dialog_epgpaid_info_title);
String info = getString(R.string.pref_epgpaid_info);
info = "<html><p>" + info.substring(0, info.lastIndexOf("\n\n")).replace("\n\n", "</p><p>").replace("https://www.epgpaid.de", "<a href=\"https://www.epgpaid.de\">https://www.epgpaid.de</a>") + "</p></html>";
Spanned text = Html.fromHtml(info);
builder.setMessage(text);
builder.setCancelable(false);
builder.setPositiveButton(R.string.update_website, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
SHOWING_EPGPAID_INFO = false;
startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://www.epgpaid.de")));
}
});
builder.setNegativeButton(android.R.string.cancel, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
SHOWING_EPGPAID_INFO = false;
}
});
showAlertDialog(builder, true, new Runnable() {
@Override
public void run() {
SHOWING_EPGPAID_INFO = true;
final Editor edit = PrefUtils.getSharedPreferences(PrefUtils.TYPE_PREFERENCES_SHARED_GLOBAL, TvBrowser.this).edit();
edit.putBoolean(getString(R.string.PREF_EPGPAID_INFO_SHOWN), true);
edit.commit();
}
});
} else if(PrefUtils.getStringValue(R.string.PREF_EPGPAID_USER, "").trim().length() > 0 && PrefUtils.getStringValue(R.string.PREF_EPGPAID_PASSWORD, "").trim().length() > 0) {
final long dateUntil = PrefUtils.getLongValueWithDefaultKey(R.string.PREF_EPGPAID_ACCESS_UNTIL, R.integer.pref_epgpaid_access_until_default);
final long expirationShown = PrefUtils.getLongValueWithDefaultKey(R.string.PREF_EPGPAID_EXPIRATION_SHOWN, R.integer.pref_epgpaid_access_until_default);
if(dateUntil != 0 && (dateUntil > System.currentTimeMillis()) && (dateUntil - (14 * 24 * 60 * 60000L)) < System.currentTimeMillis() && (expirationShown + (180 * 24 * 60 * 60000L)) < System.currentTimeMillis()) {
String message = getString(R.string.dialog_epgpaid_info_expiration_message).replace("{0}", DateFormat.getMediumDateFormat(getApplicationContext()).format(new java.util.Date(dateUntil)));
showAlertDialog(getString(R.string.dialog_epgpaid_info_expiration_title), message, null, null, new Runnable() {
@Override
public void run() {
PrefUtils.getSharedPreferences(PrefUtils.TYPE_PREFERENCES_SHARED_GLOBAL, getApplicationContext()).edit().putLong(getString(R.string.PREF_EPGPAID_EXPIRATION_SHOWN), System.currentTimeMillis()).commit();
}
}, null, null, false, true);
}
}
}
private void showEpgDonateInfo() {
Log.d("info6", "showEpgDonateInfo");
int count = 0;
if(!SHOWING_DONATION_INFO) {
final SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this);
//pref.edit().putString(getString(R.string.EPG_DONATE_DONT_SHOW_AGAIN_YEAR), "0").putLong(getString(R.string.EPG_DONATE_LAST_DONATION_INFO_SHOWN), 0).putLong(getString(R.string.EPG_DONATE_FIRST_DATA_DOWNLOAD), 0).commit();
final String year = String.valueOf(Calendar.getInstance().get(Calendar.YEAR));
final int month = Calendar.getInstance().get(Calendar.MONTH);
final long now = System.currentTimeMillis();
final long firstDownload = pref.getLong(getString(R.string.EPG_DONATE_FIRST_DATA_DOWNLOAD), now);
final long lastDownload = pref.getLong(getString(R.string.EPG_DONATE_LAST_DATA_DOWNLOAD), now);
final long lastShown = pref.getLong(getString(R.string.EPG_DONATE_LAST_DONATION_INFO_SHOWN), (now - (60 * 24 * 60 * 60000L)));
final Calendar monthTest = Calendar.getInstance();
monthTest.setTimeInMillis(lastShown);
final int shownMonth = monthTest.get(Calendar.MONTH);
final boolean firstTimeoutReached = (firstDownload + (14 * 24 * 60 * 60000L)) < now;
final boolean lastTimoutReached = lastDownload > (now - ((42 * 24 * 60 * 60000L)));
final boolean alreadyShowTimeoutReached = (lastShown + (14 * 24 * 60 * 60000L) < now);
final boolean alreadyShownThisMonth = shownMonth == month;
final boolean dontShowAgainThisYear = year.equals(pref.getString(getString(R.string.EPG_DONATE_DONT_SHOW_AGAIN_YEAR), "0"));
final boolean radomShow = Math.random() > 0.33;
boolean show = firstTimeoutReached && lastTimoutReached && alreadyShowTimeoutReached && !alreadyShownThisMonth && !dontShowAgainThisYear && radomShow;
Log.d("info6", "firstTimeoutReached (" + ((now - firstDownload)/(24 * 60 * 60000L)) + "): " + firstTimeoutReached + " lastTimoutReached: " + lastTimoutReached + " alreadyShowTimeoutReached: " + alreadyShowTimeoutReached + " alreadyShownThisMonth: " + alreadyShownThisMonth + " dontShowAgainThisYear: " + dontShowAgainThisYear + " randomShow: " + radomShow + " SHOW: " + show);
if(show) {
if((count = getEpgDonateChannelsCount()) > 0) {
final AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
final String title = getString(R.string.epg_donate_name).replace("{0}", String.valueOf(count));
String info = getString(R.string.epg_donate_info);
String amount = getString(R.string.epg_donate_amount);
final String percentInfo = getString(R.string.epg_donate_percent_info);
final String amountValue = pref.getString(getString(R.string.EPG_DONATE_CURRENT_DONATION_AMOUNT_PREFIX)+"_"+year, getString(R.string.epg_donate_current_donation_amount_default));
int percentValue = Integer.parseInt(pref.getString(getString(R.string.EPG_DONATE_CURRENT_DONATION_PERCENT), "-1"));
amount = amount.replace("{0}", year).replace("{1}", amountValue);
info = info.replace("{0}", "<h2>"+amount+"</h2>");
builder.setTitle(title);
builder.setCancelable(false);
final View view = getLayoutInflater().inflate(R.layout.dialog_epg_donate_info, getParentViewGroup(), false);
final TextView message = (TextView)view.findViewById(R.id.dialog_epg_donate_message);
message.setText(Html.fromHtml(info));
message.setMovementMethod(LinkMovementMethod.getInstance());
final TextView percentInfoView = (TextView)view.findViewById(R.id.dialog_epg_donate_percent_info);
percentInfoView.setText(Html.fromHtml(percentInfo, null, new NewsTagHandler()));
final SeekBar percent = (SeekBar)view.findViewById(R.id.dialog_epg_donate_percent);
percent.setEnabled(false);
if(percentValue >= 0) {
percent.setProgress(percentValue);
}
else {
percentInfoView.setVisibility(View.GONE);
percent.setVisibility(View.GONE);
}
final Spinner reason = (Spinner)view.findViewById(R.id.dialog_epg_donate_reason_selection);
reason.setEnabled(false);
final CheckBox dontShowAgain = (CheckBox)view.findViewById(R.id.dialog_epg_donate_dont_show_again);
dontShowAgain.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
reason.setEnabled(isChecked);
}
});
builder.setView(view);
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
SHOWING_DONATION_INFO = false;
final Editor edit = pref.edit();
edit.putLong(getString(R.string.EPG_DONATE_LAST_DONATION_INFO_SHOWN), now);
if(dontShowAgain.isChecked()) {
edit.putString(getString(R.string.EPG_DONATE_DONT_SHOW_AGAIN_YEAR), year);
}
edit.commit();
}
});
showAlertDialog(builder, false, new Runnable() {
@Override
public void run() {
SHOWING_DONATION_INFO = true;
}
});
}
else {
showEpgPaidInfo();
}
if(count == 0) {
pref.edit().putLong(getString(R.string.EPG_DONATE_LAST_DONATION_INFO_SHOWN), now).commit();
}
}
else {
showEpgPaidInfo();
}
}
else if(!SHOWING_DONATION_INFO) {
showEpgPaidInfo();
}
Log.d("info6", "showEpgDonateInfo " + count);
}
private boolean hasChannels() {
boolean result = false;
if(IOUtils.isDatabaseAccessible(TvBrowser.this)) {
Cursor c = getContentResolver().query(TvBrowserContentProvider.CONTENT_URI_CHANNELS, new String[] {TvBrowserContentProvider.KEY_ID}, null, null, null);
try {
result = c != null && c.getCount() > 0;
}finally {
IOUtils.close(c);
}
}
return result;
}
private int getEpgDonateChannelsCount() {
int result = 0;
Log.d("info6", "getEpgDonateChannelsCount");
try {
final String[] projection = new String[] {TvBrowserContentProvider.KEY_ID};
int epgDonateKey = -1;
if(IOUtils.isDatabaseAccessible(TvBrowser.this)) {
Log.d("info6", "groups");
Cursor groups = getContentResolver().query(TvBrowserContentProvider.CONTENT_URI_GROUPS, projection, TvBrowserContentProvider.GROUP_KEY_DATA_SERVICE_ID + "=\"" + SettingConstants.EPG_DONATE_KEY +"\"", null, null);
Log.d("info6", "groups loaded");
try {
if(IOUtils.prepareAccessFirst(groups)) {
epgDonateKey = groups.getInt(groups.getColumnIndex(TvBrowserContentProvider.KEY_ID));
}
} finally {
IOUtils.close(groups);
}
if(epgDonateKey != -1 && IOUtils.isDatabaseAccessible(TvBrowser.this)) {
Log.d("info6", "epgDonateSubscribedChannels");
Cursor epgDonateSubscribedChannels = getContentResolver().query(TvBrowserContentProvider.CONTENT_URI_CHANNELS, projection, " ( " + TvBrowserContentProvider.GROUP_KEY_GROUP_ID + "=" + epgDonateKey + " ) AND " + TvBrowserContentProvider.CHANNEL_KEY_SELECTION, null, null);
Log.d("info6", "epgDonateSubscribedChannels loaded");
try {
result = epgDonateSubscribedChannels != null ? epgDonateSubscribedChannels.getCount() : 0;
} finally {
IOUtils.close(epgDonateSubscribedChannels);
}
}
}
}catch(Throwable t) {Log.d("info6", "", t);}
return result;
}
private boolean hasEpgDonateChannelsSubscribed() {
return getEpgDonateChannelsCount() > 0;
}
private void handleResume() {
/*new Thread() {
public void run() {
Calendar cal2 = Calendar.getInstance();
cal2.add(Calendar.DAY_OF_YEAR, -2);
long daysSince1970 = cal2.getTimeInMillis() / 24 / 60 / 60000;
try {
getContentResolver().delete(TvBrowserContentProvider.CONTENT_URI_DATA, TvBrowserContentProvider.DATA_KEY_STARTTIME + "<" + cal2.getTimeInMillis(), null);
}catch(IllegalArgumentException e) {}
try {
getContentResolver().delete(TvBrowserContentProvider.CONTENT_URI_DATA_VERSION, TvBrowserContentProvider.VERSION_KEY_DAYS_SINCE_1970 + "<" + daysSince1970, null);
}catch(IllegalArgumentException e) {}
}
}.start();
*/
// Don't allow use of version after date
if(mRundate.getTimeInMillis() < System.currentTimeMillis()) {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.versionExpired);
Calendar test = (Calendar)mRundate.clone();
test.add(Calendar.DAY_OF_YEAR, 7);
final int diff = (int)((test.getTimeInMillis() - System.currentTimeMillis()) / (24 * 60 * 60000));
String expiredMessage = diff == 0 ? getString(R.string.versionExpiredMsgLast) : getString(R.string.versionExpiredMsg);
expiredMessage = expiredMessage.replace("{0}", String.valueOf(diff));
String updateText = SettingConstants.GOOGLE_PLAY ? getString(R.string.update_google_play) : getString(R.string.update_website);
builder.setMessage(expiredMessage);
builder.setPositiveButton(updateText, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(SettingConstants.GOOGLE_PLAY) {
final String appPackageName = getPackageName(); // getPackageName() from Context or Activity object
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName)));
} catch (android.content.ActivityNotFoundException anfe) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=" + appPackageName)));
}
}
else {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://android.tvbrowser.org/index.php?id=download")));
}
System.exit(0);
}
});
builder.setNegativeButton(R.string.update_not_now, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(diff < 0) {
System.exit(0);
}
}
});
builder.setCancelable(false);
showAlertDialog(builder);
}
else {
Log.d("info6", "selectingChannels " + selectingChannels + " " + PrefUtils.getChannelsSelected(getApplicationContext()));
if(!selectingChannels && !PrefUtils.getChannelsSelected(getApplicationContext())) {
askChannelDownload(R.string.select_channels);
}
else if(PrefUtils.getLongValueWithDefaultKey(R.string.META_DATA_DATE_LAST_KNOWN, R.integer.meta_data_date_known_default) < System.currentTimeMillis()) {
if(isOnline()) {
checkTermsAcceptedInUIThread();
}
}
mTimer = new Timer();
mTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(SettingConstants.REFRESH_VIEWS));
}
}, new Date((((long)(System.currentTimeMillis() / 60000L)) * 60000) + 62000), 60000);
final int infoType = mInfoType;
mInfoType = INFO_TYPE_NOTHING;
IOUtils.postDelayedInSeparateThread("INFO WAITING THREAD", new Runnable() {
@Override
public void run() {
try {
Log.d("info6", "infoType " + infoType);
handler.post(new Runnable() {
@Override
public void run() {
Log.d("info6", "Runnable " + infoType);
if(infoType == INFO_TYPE_NOTHING) {
showChannelUpdateInfo();
}
else if(infoType == INFO_TYPE_VERSION) {
showVersionInfo(true);
}
else if(infoType == INFO_TYPE_NEWS) {
showNews();
}
}
});
}catch(BadTokenException e) {}
}
}, 3000);
}
}
private void askChannelDownload(int positiveButton) {
Log.d("info6", "askChannelDownload");
selectingChannels = true;
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setMessage(R.string.no_channels);
builder.setPositiveButton(positiveButton, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
selectChannels(false);
}
});
builder.setNegativeButton(R.string.dont_select_channels, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
showAlertDialog(builder);
}
private void showChannelSelection() {
if(PrefUtils.getStringValue(R.string.PREF_AUTO_CHANNEL_UPDATE_CHANNELS_INSERTED, null) != null ||
PrefUtils.getStringValue(R.string.PREF_AUTO_CHANNEL_UPDATE_CHANNELS_UPDATED, null) != null) {
showChannelUpdateInfo();
}
else {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.synchronize_title);
builder.setMessage(R.string.synchronize_text);
builder.setCancelable(false);
builder.setPositiveButton(R.string.synchronize_ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
final SharedPreferences pref = getSharedPreferences("transportation", Context.MODE_PRIVATE);
if(pref.getString(SettingConstants.USER_NAME, "").trim().length() == 0 || pref.getString(SettingConstants.USER_PASSWORD, "").trim().length() == 0) {
showUserSetting(true);
}
else {
syncronizeChannels();
}
}
});
builder.setNegativeButton(R.string.synchronize_cancel, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
handler.post(new Runnable() {
@Override
public void run() {
showChannelSelectionInternal();
}
});
}
});
showAlertDialog(builder,true);
}
}
private void updateProgramListChannelBar() {
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(TvBrowser.this);
localBroadcastManager.sendBroadcast(new Intent(SettingConstants.CHANNEL_UPDATE_DONE));
}
private void syncronizeChannels() {
if(IOUtils.isDatabaseAccessible(TvBrowser.this)) {
Cursor test = getContentResolver().query(TvBrowserContentProvider.CONTENT_URI_CHANNELS, new String[] {TvBrowserContentProvider.CHANNEL_KEY_SELECTION}, TvBrowserContentProvider.CHANNEL_KEY_SELECTION + "=1 ", null, null);
int count = 0;
try {
if(test != null) {
count = test.getCount();
}
}finally {
IOUtils.close(test);
}
if(count > 0) {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.synchronize_replace_add_title);
builder.setMessage(R.string.synchronize_replace_add_text);
builder.setPositiveButton(R.string.synchronize_add, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
synchronizeChannels(false);
}
});
builder.setNegativeButton(R.string.synchronize_replace, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
synchronizeChannels(true);
}
});
showAlertDialog(builder);
}
else {
synchronizeChannels(false);
}
}
}
private void synchronizeChannels(final boolean replace) {
if(IOUtils.isDatabaseAccessible(TvBrowser.this)) {
AsyncTask<Void, Void, Void> synchronize = new AsyncTask<Void, Void, Void>() {
private ProgressDialog mProgress;
@Override
protected void onPreExecute() {
mProgress = new ProgressDialog(TvBrowser.this);
mProgress.setMessage(getString(R.string.synchronizing_channels));
mProgress.show();
}
@Override
protected Void doInBackground(Void... params) {
boolean somethingSynchonized = false;
if(replace) {
ContentValues values = new ContentValues();
values.put(TvBrowserContentProvider.CHANNEL_KEY_SELECTION, 0);
values.put(TvBrowserContentProvider.CHANNEL_KEY_ORDER_NUMBER, 0);
getContentResolver().delete(TvBrowserContentProvider.CONTENT_URI_DATA, TvBrowserContentProvider.KEY_ID + " >= 0 " , null);
getContentResolver().delete(TvBrowserContentProvider.CONTENT_URI_DATA_VERSION, TvBrowserContentProvider.KEY_ID + " >= 0", null);
if(getContentResolver().update(TvBrowserContentProvider.CONTENT_URI_CHANNELS, values, TvBrowserContentProvider.CHANNEL_KEY_SELECTION + "=1", null) > 0) {
somethingSynchonized = true;
}
}
URLConnection connection = null;
try {
URL documentUrl = new URL(SettingConstants.URL_SYNC_BASE + "data/scripts/syncDown.php?type=channelsFromDesktop");
connection = documentUrl.openConnection();
IOUtils.setConnectionTimeoutDefault(connection);
SharedPreferences pref = getSharedPreferences("transportation", Context.MODE_PRIVATE);
String car = pref.getString(SettingConstants.USER_NAME, null);
String bicycle = pref.getString(SettingConstants.USER_PASSWORD, null);
if(car != null && bicycle != null) {
String userpass = car + ":" + bicycle;
String basicAuth = "basic " + Base64.encodeToString(userpass.getBytes(), Base64.NO_WRAP);
connection.setRequestProperty ("Authorization", basicAuth);
BufferedReader read = new BufferedReader(new InputStreamReader(new GZIPInputStream(connection.getInputStream()),"UTF-8"));
String line = null;
int sort = 1;
final String[] projection = {TvBrowserContentProvider.KEY_ID};
final ContentResolver resolver = getContentResolver();
HashMap<String, Integer> groupMap = new HashMap<String, Integer>();
Cursor group = resolver.query(TvBrowserContentProvider.CONTENT_URI_GROUPS, null, null, null, null);
try {
if(IOUtils.prepareAccess(group)) {
int keyIndex = group.getColumnIndex(TvBrowserContentProvider.KEY_ID);
int groupIdIndex = group.getColumnIndex(TvBrowserContentProvider.GROUP_KEY_GROUP_ID);
int dataServiceIdIndex = group.getColumnIndex(TvBrowserContentProvider.GROUP_KEY_DATA_SERVICE_ID);
while(group.moveToNext()) {
String dataServiceId = group.getString(dataServiceIdIndex);
String groupId = group.getString(groupIdIndex);
int key = group.getInt(keyIndex);
groupMap.put(dataServiceId+";"+groupId, key);
}
}
}finally {
IOUtils.close(group);
}
ArrayList<ContentProviderOperation> updateList = new ArrayList<ContentProviderOperation>();
while((line = read.readLine()) != null) {
if(line.trim().length() > 0) {
if(line.contains(":")) {
String[] parts = line.split(":");
String dataService = null;
String groupKey = null;
String channelId = null;
String sortNumber = null;
if(parts[0].equals(SettingConstants.getNumberForDataServiceKey(SettingConstants.EPG_FREE_KEY))) {
dataService = SettingConstants.EPG_FREE_KEY;
groupKey = parts[1];
channelId = parts[2];
if(parts.length > 3) {
sortNumber = parts[3];
}
}
else if(parts[0].equals(SettingConstants.getNumberForDataServiceKey(SettingConstants.EPG_DONATE_KEY))) {
dataService = SettingConstants.EPG_DONATE_KEY;
groupKey = SettingConstants.EPG_DONATE_GROUP_KEY;
channelId = parts[1];
if(parts.length > 2) {
sortNumber = parts[2];
}
}
if(dataService != null) {
Integer groupId = groupMap.get(dataService+";"+groupKey);
if(groupId != null) {
String where = " ( " + TvBrowserContentProvider.GROUP_KEY_GROUP_ID + "=" + groupId + " ) AND ( " + TvBrowserContentProvider.CHANNEL_KEY_CHANNEL_ID + "='" + channelId + "' ) ";
ContentValues values = new ContentValues();
if(sortNumber != null) {
try {
sort = Integer.parseInt(sortNumber);
}catch(NumberFormatException e) {}
}
values.put(TvBrowserContentProvider.CHANNEL_KEY_SELECTION, 1);
values.put(TvBrowserContentProvider.CHANNEL_KEY_ORDER_NUMBER, sort);
Cursor channelIdCursor = resolver.query(TvBrowserContentProvider.CONTENT_URI_CHANNELS, projection, where, null, TvBrowserContentProvider.KEY_ID + " ASC LIMIT 1");
try {
if(IOUtils.prepareAccessFirst(channelIdCursor)) {
int id = channelIdCursor.getInt(channelIdCursor.getColumnIndex(TvBrowserContentProvider.KEY_ID));
updateList.add(ContentProviderOperation.newUpdate(ContentUris.withAppendedId(TvBrowserContentProvider.CONTENT_URI_CHANNELS,id)).withValues(values).build());
}
}finally {
IOUtils.close(channelIdCursor);
}
}
sort++;
}
}
}
}
if(!updateList.isEmpty()) {
ContentProviderResult[] result = getContentResolver().applyBatch(TvBrowserContentProvider.AUTHORITY, updateList);
somethingSynchonized = result.length > 0;
}
if(somethingSynchonized) {
handler.post(new Runnable() {
@Override
public void run() {
SettingConstants.initializeLogoMap(TvBrowser.this, true);
updateProgramListChannelBar();
PrefUtils.updateChannelSelectionState(getApplicationContext());
Toast.makeText(getApplicationContext(), R.string.synchronize_done, Toast.LENGTH_LONG).show();
checkTermsAccepted();
}
});
}
else {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), R.string.synchronize_error, Toast.LENGTH_LONG).show();
showChannelSelectionInternal();
}
});
}
}
else {
handler.post(new Runnable() {
@Override
public void run() {
showChannelSelectionInternal();
}
});
}
} catch (Exception e) {
handler.post(new Runnable() {
@Override
public void run() {
showChannelSelectionInternal();
}
});
} finally {
IOUtils.disconnect(connection);
}
selectingChannels = false;
return null;
}
protected void onPostExecute(Void result) {
if(mProgress != null) {
mProgress.dismiss();
}
}
};
synchronize.execute();
}
}
private void synchronizeDontWantToSee(final boolean replace) {
new Thread() {
public void run() {
if(!SettingConstants.UPDATING_FILTER && IOUtils.isDatabaseAccessible(TvBrowser.this)) {
SettingConstants.UPDATING_FILTER = true;
Context applicationContext = getApplicationContext();
NotificationCompat.Builder builder;
builder = new NotificationCompat.Builder(TvBrowser.this);
builder.setSmallIcon(R.drawable.ic_stat_notify);
builder.setOngoing(true);
builder.setContentTitle(getResources().getText(R.string.action_dont_want_to_see));
builder.setContentText(getResources().getText(R.string.dont_want_to_see_notification_text));
builder.setProgress(0, 0, true);
int notifyID = 2;
NotificationManager notification = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notification.notify(notifyID, builder.build());
updateProgressIcon(true);
URLConnection connection = null;
try {
URL documentUrl = new URL(SettingConstants.URL_SYNC_BASE + "data/scripts/syncDown.php?type=dontWantToSee");
connection = documentUrl.openConnection();
IOUtils.setConnectionTimeoutDefault(connection);
SharedPreferences pref = getSharedPreferences("transportation", Context.MODE_PRIVATE);
String car = pref.getString(SettingConstants.USER_NAME, null);
String bicycle = pref.getString(SettingConstants.USER_PASSWORD, null);
if(car != null && bicycle != null) {
String userpass = car + ":" + bicycle;
String basicAuth = "basic " + Base64.encodeToString(userpass.getBytes(), Base64.NO_WRAP);
connection.setRequestProperty ("Authorization", basicAuth);
BufferedReader read = new BufferedReader(new InputStreamReader(new GZIPInputStream(connection.getInputStream()),"UTF-8"));
String line = null;
StringBuilder exclusionBuilder = new StringBuilder();
HashSet<String> exclusions = new HashSet<String>();
HashSet<String> newExclusions = new HashSet<String>();
while((line = read.readLine()) != null) {
if(line.contains(";;") && line.trim().length() > 0) {
exclusions.add(line);
newExclusions.add(line);
exclusionBuilder.append(line).append("\n");
}
}
String key = getString(R.string.I_DONT_WANT_TO_SEE_ENTRIES);
SharedPreferences pref1 = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this);
Set<String> oldValues = pref1.getStringSet(key, null);
if(exclusions.size() > 0) {
if(!replace && oldValues != null) {
for(String old : oldValues) {
if(!exclusions.contains(old)) {
exclusions.add(old);
exclusionBuilder.append(old).append("\n");
}
else {
newExclusions.remove(old);
}
}
}
ArrayList<DontWantToSeeExclusion> exclusionList = new ArrayList<DontWantToSeeExclusion>();
for(String exclusion : newExclusions) {
exclusionList.add(new DontWantToSeeExclusion(exclusion));
}
Editor edit = pref1.edit();
edit.putStringSet(key, exclusions);
edit.commit();
DontWantToSeeExclusion[] exclusionArr = exclusionList.toArray(new DontWantToSeeExclusion[exclusionList.size()]);
if(exclusionArr.length > 0) {
String where = null;
if(!replace) {
where = "NOT " + TvBrowserContentProvider.DATA_KEY_DONT_WANT_TO_SEE;
}
MemorySizeConstrictedDatabaseOperation dontWantToSeeUpdate = new MemorySizeConstrictedDatabaseOperation(TvBrowser.this, null);
//ArrayList<ContentProviderOperation> updateValuesList = new ArrayList<ContentProviderOperation>();
Cursor c = getContentResolver().query(TvBrowserContentProvider.CONTENT_URI_DATA, new String[] {TvBrowserContentProvider.KEY_ID,TvBrowserContentProvider.DATA_KEY_TITLE}, where, null, TvBrowserContentProvider.KEY_ID);
try {
int count = 0;
if(IOUtils.prepareAccess(c)) {
count = c.getCount()/10;
builder.setProgress(count, 0, false);
notification.notify(notifyID, builder.build());
int keyColumn = c.getColumnIndex(TvBrowserContentProvider.KEY_ID);
int titleColumn = c.getColumnIndex(TvBrowserContentProvider.DATA_KEY_TITLE);
while(c.moveToNext()) {
int position = c.getPosition();
if(position % 10 == 0) {
builder.setProgress(count, position/10, false);
notification.notify(notifyID, builder.build());
}
String title = c.getString(titleColumn);
boolean filter = UiUtils.filter(getApplicationContext(), title, exclusionArr);
long progID = c.getLong(keyColumn);
ContentValues values = new ContentValues();
values.put(TvBrowserContentProvider.DATA_KEY_DONT_WANT_TO_SEE, filter ? 1 : 0);
ContentProviderOperation.Builder opBuilder = ContentProviderOperation.newUpdate(ContentUris.withAppendedId(TvBrowserContentProvider.CONTENT_URI_DATA_UPDATE, progID));
opBuilder.withValues(values);
dontWantToSeeUpdate.addUpdate(opBuilder.build());
//updateValuesList.add(opBuilder.build());
}
}
}finally {
IOUtils.close(c);
}
builder.setProgress(0, 0, true);
notification.notify(notifyID, builder.build());
if(dontWantToSeeUpdate.operationsAvailable()) {
dontWantToSeeUpdate.finish();
//getContentResolver().applyBatch(TvBrowserContentProvider.AUTHORITY, updateValuesList);
UiUtils.sendDontWantToSeeChangedBroadcast(applicationContext,true);
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), R.string.dont_want_to_see_sync_success, Toast.LENGTH_LONG).show();
}
});
}
else {
dontWantToSeeUpdate.cancel();
}
}
else if(newExclusions.isEmpty()) {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), R.string.dont_want_to_see_sync_success, Toast.LENGTH_LONG).show();
}
});
}
if(!replace && exclusionBuilder.length() > 0) {
startSynchronizeUp(false, exclusionBuilder.toString(), SettingConstants.URL_SYNC_BASE + "data/scripts/syncUp.php?type=dontWantToSee", null, null);
}
}
else {
if(!replace && oldValues != null && !oldValues.isEmpty()) {
for(String old : oldValues) {
exclusionBuilder.append(old).append("\n");
}
startSynchronizeUp(false, exclusionBuilder.toString(), SettingConstants.URL_SYNC_BASE + "data/scripts/syncUp.php?type=dontWantToSee", null, null);
}
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), R.string.no_dont_want_to_see_sync, Toast.LENGTH_LONG).show();
}
});
}
}
}catch(Throwable t) {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), R.string.no_dont_want_to_see_sync, Toast.LENGTH_LONG).show();
}
});
} finally {
IOUtils.disconnect(connection);
}
notification.cancel(notifyID);
updateProgressIcon(false);
SettingConstants.UPDATING_FILTER = false;
}
}
}.start();
}
private void backupPreferences() {
if(isOnline()) {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.action_backup_preferences_save);
builder.setMessage(R.string.backup_preferences_save_text);
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
Map<String,?> preferences = pref.getAll();
StringBuilder backup = new StringBuilder();
Set<String> keys = preferences.keySet();
for(String key : keys) {
Object value = preferences.get(key);
if(value instanceof Boolean) {
if(!getString(R.string.PREF_EPGPAID_INFO_SHOWN).equals(key) || !getString(R.string.PREF_RATING_DONATION_INFO_SHOWN).equals(key) || (Boolean) value) {
backup.append("boolean:").append(key).append("=").append(value).append("\n");
}
}
else if(value instanceof Integer) {
if(!getString(R.string.OLD_VERSION).equals(key)) {
backup.append("int:").append(key).append("=").append(value).append("\n");
}
}
else if(value instanceof Float) {
backup.append("float:").append(key).append("=").append(value).append("\n");
}
else if(value instanceof Long) {
backup.append("long:").append(key).append("=").append(value).append("\n");
}
else if(value instanceof String && value != null && ((String)value).trim().length() > 0
&& !getString(R.string.PREF_EPGPAID_USER).equals(key) && !getString(R.string.PREF_EPGPAID_PASSWORD).equals(key)) {
backup.append("string:").append(key).append("=").append(value).append("\n");
}
else if(value instanceof Set<?>){
if(!key.equals(getString(R.string.I_DONT_WANT_TO_SEE_ENTRIES))) {
Set<String> valueSet = (Set<String>)value;
backup.append("set:").append(key).append("=");
backup.append(TextUtils.join("#,#", valueSet));
backup.append("\n");
}
}
}
Favorite[] favorites = Favorite.getAllFavorites(getApplicationContext());
for(Favorite favorite : favorites) {
backup.append("favorite:");
backup.append(favorite.getFavoriteId());
backup.append("=");
backup.append(favorite.getSaveString(TvBrowser.this).replace("\n", "\\n"));
backup.append("\n");
}
startSynchronizeUp(true, backup.toString(), SettingConstants.URL_SYNC_BASE + "data/scripts/syncUp.php?type=preferencesBackup", SettingConstants.SYNCHRONIZE_UP_DONE, getString(R.string.backup_preferences_success));
}
});
builder.setNegativeButton(android.R.string.cancel,null);
showAlertDialog(builder);
}
else {
showNoInternetConnection(getString(R.string.no_network_info_data_pref_backup), null);
}
}
private void restorePreferencesInternal() {
handler.post(new Runnable() {
@Override
public void run() {
mViewPager.setCurrentItem(0,true);
for(int i = mSectionsPagerAdapter.getCount()-1; i >= 0; i--) {
mSectionsPagerAdapter.destroyItem(mViewPager, i, mSectionsPagerAdapter.getRegisteredFragment(i));
mSectionsPagerAdapter.notifyDataSetChanged();
try {
actionBar.removeTabAt(i);
}catch(NullPointerException npe) {
}
}
actionBar.addTab(actionBar.newTab().setText(getString(R.string.tab_restoring_name)).setTabListener(new ActionBar.TabListener() {
@Override
public void onTabUnselected(Tab arg0, FragmentTransaction arg1) {}
@Override
public void onTabSelected(Tab arg0, FragmentTransaction arg1) {}
@Override
public void onTabReselected(Tab arg0, FragmentTransaction arg1) {}
}));
new Thread("RESTORE PREFERENCES") {
@Override
public void run() {
updateProgressIcon(true);
URLConnection connection = null;
BufferedReader read = null;
boolean restored = false;
try {
URL documentUrl = new URL(SettingConstants.URL_SYNC_BASE + "data/scripts/syncDown.php?type=preferencesBackup");
connection = documentUrl.openConnection();
IOUtils.setConnectionTimeoutDefault(connection);
SharedPreferences pref = getSharedPreferences("transportation", Context.MODE_PRIVATE);
String car = pref.getString(SettingConstants.USER_NAME, null);
String bicycle = pref.getString(SettingConstants.USER_PASSWORD, null);
if(car != null && bicycle != null) {
String userpass = car + ":" + bicycle;
String basicAuth = "basic " + Base64.encodeToString(userpass.getBytes(), Base64.NO_WRAP);
connection.setRequestProperty ("Authorization", basicAuth);
read = new BufferedReader(new InputStreamReader(new GZIPInputStream(connection.getInputStream()),"UTF-8"));
String line = null;
Editor edit = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit();
TvBrowserContentProvider.INFORM_FOR_CHANGES = false;
final Favorite[] existingFavorites = Favorite.getAllFavorites(getApplicationContext());
while((line = read.readLine()) != null) {
int index = line.indexOf(":");
if(index > 0) {
restored = true;
String type = line.substring(0,index);
String[] parts = line.substring(index+1).split("=");
if(parts != null && parts.length > 1) {
if(type.equals("boolean")) {
boolean boolValue = Boolean.valueOf(parts[1].trim());
if(!getString(R.string.PREF_RATING_DONATION_INFO_SHOWN).equals(parts[0]) || boolValue) {
edit.putBoolean(parts[0], boolValue);
}
}
else if(type.equals("int")) {
if(!getString(R.string.OLD_VERSION).equals(parts[0])) {
edit.putInt(parts[0], Integer.valueOf(parts[1].trim()));
}
}
else if(type.equals("float")) {
edit.putFloat(parts[0], Float.valueOf(parts[1].trim()));
}
else if(type.equals("long")) {
edit.putLong(parts[0], Long.valueOf(parts[1].trim()));
}
else if(type.equals("string")) {
if(getString(R.string.CURRENT_FILTER_ID).equals(parts[0])) {
HashSet<String> set = new HashSet<String>();
set.add(parts[1].trim());
edit.putStringSet(parts[0], set);
}
else if(getString(R.string.PREF_DATABASE_PATH).equals(parts[0])) {
final File test = new File(parts[1].trim());
if(test.isFile()) {
edit.putString(parts[0], parts[1].trim());
}
}
else {
edit.putString(parts[0], parts[1].trim());
}
}
else if(type.equals("set")) {
HashSet<String> set = new HashSet<String>();
String[] setParts = parts[1].split("#,#");
if(setParts != null && setParts.length > 0) {
if(parts[0].equals("FAVORITE_LIST")) {
Favorite.deleteAllFavorites(getApplicationContext());
int id = 1000;
for(String setPart : setParts) {
Favorite favorite = new Favorite(id++,setPart);
favorite.loadChannelRestrictionIdsFromUniqueChannelRestriction(getApplicationContext());
Favorite.handleFavoriteMarking(getApplicationContext(), favorite, Favorite.TYPE_MARK_ADD);
}
}
else {
Collections.addAll(set, setParts);
edit.putStringSet(parts[0], set);
}
}
}
else if(type.equals("favorite")) {
Favorite favorite = new Favorite(Long.parseLong(parts[0]),parts[1].replace("\\n", "\n"));
for(Favorite test : existingFavorites) {
if(test.getFavoriteId() == favorite.getFavoriteId()) {
Favorite.deleteFavorite(getApplicationContext(), favorite);
break;
}
}
favorite.loadChannelRestrictionIdsFromUniqueChannelRestriction(getApplicationContext());
Favorite.handleFavoriteMarking(getApplicationContext(), favorite, Favorite.TYPE_MARK_ADD);
}
}
}
}
TvBrowserContentProvider.INFORM_FOR_CHANGES = true;
if(restored) {
edit.commit();
handler.post(new Runnable() {
@Override
public void run() {
updateFromPreferences(true);
}
});
IOUtils.handleDataUpdatePreferences(getApplicationContext());
}
}
}catch(Exception e) {
Log.d("info22", "", e);
restored = false;
}
finally {
IOUtils.close(read);
IOUtils.disconnect(connection);
}
if(restored) {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(TvBrowser.this, getString(R.string.backup_preferences_restore_success), Toast.LENGTH_LONG).show();
}
});
}
else {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(TvBrowser.this, getString(R.string.backup_preferences_restore_failure), Toast.LENGTH_LONG).show();
}
});
}
updateProgressIcon(false);
}
}.start();
}
});
}
private void restorePreferences() {
if(isOnline()) {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.action_backup_preferences_restore);
builder.setMessage(R.string.backup_preferences_restore_text);
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
restorePreferencesInternal();
}
});
builder.setNegativeButton(android.R.string.cancel,null);
showAlertDialog(builder);
}
else {
showNoInternetConnection(getString(R.string.no_network_info_data_pref_restore), null);
}
}
private void uploadChannels() {
if(IOUtils.isDatabaseAccessible(TvBrowser.this)) {
String[] projection = {
TvBrowserContentProvider.GROUP_KEY_GROUP_ID,
TvBrowserContentProvider.CHANNEL_KEY_CHANNEL_ID,
TvBrowserContentProvider.CHANNEL_KEY_ORDER_NUMBER
};
SparseArrayCompat<String> groupKeys = new SparseArrayCompat<String>();
StringBuilder uploadChannels = new StringBuilder();
Cursor channels = null;
try {
channels = getContentResolver().query(TvBrowserContentProvider.CONTENT_URI_CHANNELS, projection, TvBrowserContentProvider.CHANNEL_KEY_SELECTION, null, TvBrowserContentProvider.CHANNEL_KEY_ORDER_NUMBER);
if(IOUtils.prepareAccess(channels)) {
assert channels != null;
int groupKeyColumn = channels.getColumnIndex(TvBrowserContentProvider.GROUP_KEY_GROUP_ID);
int channelKeyColumn = channels.getColumnIndex(TvBrowserContentProvider.CHANNEL_KEY_CHANNEL_ID);
int channelKeyOrderNumberColumn = channels.getColumnIndex(TvBrowserContentProvider.CHANNEL_KEY_ORDER_NUMBER);
while(channels.moveToNext()) {
int groupKey = channels.getInt(groupKeyColumn);
String channelId = channels.getString(channelKeyColumn);
int orderNumber = channels.getInt(channelKeyOrderNumberColumn);
String groupId = groupKeys.get(groupKey);
if(groupId == null) {
String[] groupProjection = {
TvBrowserContentProvider.GROUP_KEY_GROUP_ID,
TvBrowserContentProvider.GROUP_KEY_DATA_SERVICE_ID
};
Cursor groups = null;
try {
groups = getContentResolver().query(TvBrowserContentProvider.CONTENT_URI_GROUPS, groupProjection, TvBrowserContentProvider.KEY_ID + "=" + groupKey, null, null);
if(IOUtils.prepareAccessFirst(groups)) {
assert groups != null;
String dataServiceId = groups.getString(groups.getColumnIndex(TvBrowserContentProvider.GROUP_KEY_DATA_SERVICE_ID));
String goupIdValue = groups.getString(groups.getColumnIndex(TvBrowserContentProvider.GROUP_KEY_GROUP_ID));
String dataServiceIdNumber = SettingConstants.getNumberForDataServiceKey(dataServiceId);
if(dataServiceIdNumber != null) {
if(dataServiceId.equals(SettingConstants.EPG_FREE_KEY)) {
groupId = dataServiceIdNumber + ":"+goupIdValue+":";
}
else if(dataServiceId.equals(SettingConstants.EPG_DONATE_KEY)) {
groupId = dataServiceIdNumber + ":";
}
groupKeys.put(groupKey, groupId);
}
}
}finally {
IOUtils.close(groups);
}
}
uploadChannels.append(groupId).append(channelId);
if(orderNumber > 0) {
uploadChannels.append(":").append(orderNumber);
}
uploadChannels.append("\n");
}
}
}finally {
IOUtils.close(channels);
}
if(uploadChannels.toString().trim().length() > 0) {
startSynchronizeUp(true, uploadChannels.toString().trim(), SettingConstants.URL_SYNC_BASE + "data/scripts/syncUp.php?type=channelsFromDesktop", SettingConstants.SYNCHRONIZE_UP_DONE, getString(R.string.backup_channels_success));
}
}
}
private void startSynchronizeUp(boolean info, String value, String address, String receiveDone, final String userInfo) {
Intent synchronizeUp = new Intent(TvBrowser.this, TvDataUpdateService.class);
synchronizeUp.putExtra(SettingConstants.EXTRA_DATA_UPDATE_TYPE, TvDataUpdateService.TYPE_UPDATE_MANUELL);
synchronizeUp.putExtra(TvDataUpdateService.KEY_TYPE, TvDataUpdateService.TYPE_SYNCHRONIZE_UP);
synchronizeUp.putExtra(SettingConstants.SYNCHRONIZE_SHOW_INFO_EXTRA, info);
synchronizeUp.putExtra(SettingConstants.SYNCHRONIZE_UP_URL_EXTRA, address);
if(value != null) {
synchronizeUp.putExtra(SettingConstants.SYNCHRONIZE_UP_VALUE_EXTRA, value);
}
if(receiveDone != null) {
updateProgressIcon(true);
IntentFilter filter = new IntentFilter(receiveDone);
BroadcastReceiver refreshIcon = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateProgressIcon(false);
LocalBroadcastManager.getInstance(TvBrowser.this).unregisterReceiver(this);
if(userInfo != null) {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(TvBrowser.this, userInfo, Toast.LENGTH_LONG).show();
}
});
}
}
};
LocalBroadcastManager.getInstance(TvBrowser.this).registerReceiver(refreshIcon, filter);
}
startService(synchronizeUp);
}
private void startSynchronizeRemindersDown() {
updateProgressIcon(true);
Intent synchronizeRemindersDown = new Intent(TvBrowser.this, TvDataUpdateService.class);
synchronizeRemindersDown.putExtra(SettingConstants.EXTRA_DATA_UPDATE_TYPE, TvDataUpdateService.TYPE_UPDATE_MANUELL);
synchronizeRemindersDown.putExtra(TvDataUpdateService.KEY_TYPE, TvDataUpdateService.TYPE_REMINDER_DOWN);
synchronizeRemindersDown.putExtra(SettingConstants.SYNCHRONIZE_SHOW_INFO_EXTRA, true);
IntentFilter remindersDownFilter = new IntentFilter(SettingConstants.REMINDER_DOWN_DONE);
BroadcastReceiver remindersDownDone = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateProgressIcon(false);
LocalBroadcastManager.getInstance(TvBrowser.this).unregisterReceiver(this);
}
};
LocalBroadcastManager.getInstance(TvBrowser.this).registerReceiver(remindersDownDone, remindersDownFilter);
startService(synchronizeRemindersDown);
}
private static final class ChannelSelection {
private int mChannelID;
private int mCategory;
private Bitmap mChannelLogo;
private String mCountry;
private String mName;
private boolean mIsSelected;
private boolean mWasSelected;
private boolean mIsEpgDonateChannel;
public ChannelSelection(int channelID, String name, int category, String country, Bitmap channelLogo, boolean isSelected, boolean isEpgDonateChannel) {
mChannelID = channelID;
mCategory = category;
mCountry = country;
mChannelLogo = channelLogo;
mName = name;
mWasSelected = mIsSelected = isSelected;
mIsEpgDonateChannel = isEpgDonateChannel;
}
public boolean isCategory(int category) {
return category == 0 || (mCategory & category) == category;
}
public boolean isCountry(String value) {
return value == null || mCountry.toLowerCase().contains(value.toLowerCase());
}
public boolean isSelected() {
return mIsSelected;
}
public boolean wasSelected() {
return mWasSelected;
}
public void setSelected(boolean value) {
mIsSelected = value;
}
public Bitmap getLogo() {
return mChannelLogo;
}
public String toString() {
return mName;
}
public boolean isEpgDonateChannel() {
return mIsEpgDonateChannel;
}
public int getChannelID() {
return mChannelID;
}
}
/**
* View holder for custom array adapter of channel selection.
*
* @author René Mach
*/
private static final class ViewHolder {
CheckBox mCheckBox;
TextView mTextView;
TextView mSortNumber;
ImageView mLogo;
}
/**
* Class for wrapping array list to support
* filtering channel selection for country and
* category.
*
* @author René Mach
*/
private static class ArrayListWrapper extends ArrayList<ChannelSelection> {
Integer[] mValueMap = null;
@Override
public ChannelSelection get(int index) {
if(mValueMap != null) {
if(mValueMap.length >= 0 && index < mValueMap.length) {
return super.get(mValueMap[index]);
}
throw new ArrayIndexOutOfBoundsException(index);
}
return super.get(index);
}
public void setFilter(ChannelFilter filter) {
ArrayList<Integer> map = new ArrayList<Integer>();
for(int i = 0; i < super.size(); i++) {
ChannelSelection selection = super.get(i);
if(selection.isCategory(filter.mCategory) && selection.isCountry(filter.mCountry)) {
map.add(i);
}
}
mValueMap = map.toArray(new Integer[map.size()]);
}
@Override
public int size() {
if(mValueMap != null) {
return mValueMap.length;
}
return super.size();
}
private ChannelSelection superGet(int index) {
return super.get(index);
}
public Iterator<ChannelSelection> superIterator() {
return super.iterator();
}
@Override
public Iterator<ChannelSelection> iterator() {
if(mValueMap != null) {
return new Iterator<ChannelSelection>() {
private int mCurrentIndex = 0;
private ChannelSelection mCurrent = null;
@Override
public boolean hasNext() {
return mCurrentIndex < mValueMap.length-1;
}
@Override
public ChannelSelection next() {
mCurrent = superGet(mValueMap[++mCurrentIndex]);
return mCurrent;
}
@Override
public void remove() {
mCurrent = null;
}
};
}
return super.iterator();
}
}
/**
* Class for filtering of country and category for channel selection.
*
* @author René Mach
*/
private final static class ChannelFilter {
public int mCategory;
public String mCountry;
public ChannelFilter(int category, String country) {
mCategory = category;
mCountry = country;
}
}
/**
* Class for country filtering of channel selecton.
*
* @author René Mach
*/
private final static class Country {
public Locale mLocale;
public Country(Locale locale) {
mLocale = locale;
}
public String toString() {
if(mLocale == null) {
return ALL_VALUE;
}
return mLocale.getDisplayCountry();
}
public String getCountry() {
if(mLocale == null) {
return null;
}
return mLocale.getCountry();
}
@Override
public boolean equals(Object o) {
if(o instanceof Country) {
return mLocale.getCountry().equals(((Country)o).mLocale.getCountry());
}
return super.equals(o);
}
}
private void showChannelSelectionInternal() {
showChannelSelectionInternal(null,null,null,false);
}
private void showChannelSelectionInternal(final String selection, final String title, final String help, final boolean delete) {
if(IOUtils.isDatabaseAccessible(TvBrowser.this)) {
final String[] projection = {
TvBrowserContentProvider.CHANNEL_TABLE+"."+TvBrowserContentProvider.KEY_ID +" AS "+TvBrowserContentProvider.KEY_ID,
TvBrowserContentProvider.GROUP_KEY_DATA_SERVICE_ID,
TvBrowserContentProvider.CHANNEL_KEY_NAME,
TvBrowserContentProvider.CHANNEL_KEY_SELECTION,
TvBrowserContentProvider.CHANNEL_KEY_CATEGORY,
TvBrowserContentProvider.CHANNEL_KEY_LOGO,
TvBrowserContentProvider.CHANNEL_KEY_ALL_COUNTRIES
};
ContentResolver cr = getContentResolver();
Cursor channels = cr.query(TvBrowserContentProvider.CONTENT_URI_CHANNELS_WITH_GROUP, projection, selection, null, TvBrowserContentProvider.CHANNEL_KEY_NAME);
final ArrayListWrapper channelSelectionList = new ArrayListWrapper();
ArrayList<Country> countryList = new ArrayList<Country>();
try {
if(IOUtils.prepareAccess(channels)) {
// populate array list with all available channels
int channelIdColumn = channels.getColumnIndex(TvBrowserContentProvider.KEY_ID);
int categoryColumn = channels.getColumnIndex(TvBrowserContentProvider.CHANNEL_KEY_CATEGORY);
int logoColumn = channels.getColumnIndex(TvBrowserContentProvider.CHANNEL_KEY_LOGO);
int dataServiceColumn = channels.getColumnIndex(TvBrowserContentProvider.GROUP_KEY_DATA_SERVICE_ID);
int nameColumn = channels.getColumnIndex(TvBrowserContentProvider.CHANNEL_KEY_NAME);
int countyColumn = channels.getColumnIndex(TvBrowserContentProvider.CHANNEL_KEY_ALL_COUNTRIES);
int selectionColumn = channels.getColumnIndex(TvBrowserContentProvider.CHANNEL_KEY_SELECTION);
while(channels.moveToNext()) {
int channelID = channels.getInt(channelIdColumn);
int category = channels.getInt(categoryColumn);
byte[] logo = channels.getBlob(logoColumn);
String dataService = channels.getString(dataServiceColumn);
String name = channels.getString(nameColumn);
String countries = channels.getString(countyColumn);
boolean isSelected = channels.getInt(selectionColumn) == 1 && !delete;
if(countries.contains("$")) {
String[] values = countries.split("\\$");
for(String country : values) {
Country test = new Country(new Locale(country, country));
if(!countryList.contains(test) && test.mLocale.getDisplayCountry().trim().length() > 0) {
countryList.add(test);
}
}
}
else {
Country test = new Country(new Locale(countries, countries));
if(!countryList.contains(test) && test.mLocale.getDisplayCountry().trim().length() > 0) {
countryList.add(test);
}
}
Bitmap channelLogo = UiUtils.createBitmapFromByteArray(logo);
if(channelLogo != null) {
BitmapDrawable l = new BitmapDrawable(getResources(), channelLogo);
ColorDrawable background = new ColorDrawable(SettingConstants.LOGO_BACKGROUND_COLOR);
background.setBounds(0, 0, channelLogo.getWidth()+2,channelLogo.getHeight()+2);
LayerDrawable logoDrawable = new LayerDrawable(new Drawable[] {background,l});
logoDrawable.setBounds(background.getBounds());
l.setBounds(2, 2, channelLogo.getWidth(), channelLogo.getHeight());
channelLogo = UiUtils.drawableToBitmap(logoDrawable);
}
channelSelectionList.add(new ChannelSelection(channelID, name, category, countries, channelLogo, isSelected, SettingConstants.EPG_DONATE_KEY.equals(dataService)));
}
// sort countries for filtering
Collections.sort(countryList, new Comparator<Country>() {
@Override
public int compare(Country lhs, Country rhs) {
return lhs.toString().compareToIgnoreCase(rhs.toString());
}
});
countryList.add(0,new Country(null));
}
}finally {
IOUtils.close(channels);
}
// create filter for filtering of category and country
final ChannelFilter filter = new ChannelFilter(SettingConstants.TV_CATEGORY, null);
// create default logo for channels without logo
final Bitmap defaultLogo = BitmapFactory.decodeResource( getResources(), R.drawable.ic_launcher);
final Set<String> firstDeletedChannels = PrefUtils.getStringSetValue(R.string.PREF_FIRST_DELETED_CHANNELS, new HashSet<String>());
final Set<String> keptDeletedChannels = PrefUtils.getStringSetValue(R.string.PREF_KEPT_DELETED_CHANNELS, new HashSet<String>());
final int firstDeletedColor = ContextCompat.getColor(this, R.color.pref_first_deleted_channels);
final int keptDeletedColor = ContextCompat.getColor(this, R.color.pref_kept_deleted_channels);
// Custom array adapter for channel selection
final ArrayAdapter<ChannelSelection> channelSelectionAdapter = new ArrayAdapter<ChannelSelection>(TvBrowser.this, R.layout.channel_row, channelSelectionList) {
public View getView(int position, View convertView, ViewGroup parent) {
ChannelSelection value = getItem(position);
ViewHolder holder = null;
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.channel_row, getParentViewGroup(), false);
holder.mTextView = (TextView)convertView.findViewById(R.id.row_of_channel_text);
holder.mCheckBox = (CheckBox)convertView.findViewById(R.id.row_of_channel_selection);
holder.mLogo = (ImageView)convertView.findViewById(R.id.row_of_channel_icon);
convertView.setTag(holder);
}
else {
holder = (ViewHolder)convertView.getTag();
}
SpannableStringBuilder nameBuilder = new SpannableStringBuilder(value.toString());
String channelID = String.valueOf(value.getChannelID());
if(keptDeletedChannels.contains(channelID)) {
nameBuilder.setSpan(new ForegroundColorSpan(keptDeletedColor), 0, value.toString().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
else if(firstDeletedChannels.contains(channelID)) {
nameBuilder.setSpan(new ForegroundColorSpan(firstDeletedColor), 0, value.toString().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if(value.isEpgDonateChannel()) {
nameBuilder.append("\n(EPGdonate)");
nameBuilder.setSpan(new RelativeSizeSpan(0.65f), value.toString().length(), nameBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
holder.mTextView.setText(nameBuilder);
holder.mCheckBox.setChecked(value.isSelected());
Bitmap logo = value.getLogo();
if(logo != null) {
holder.mLogo.setImageBitmap(logo);
}
else {
holder.mLogo.setImageBitmap(defaultLogo);
}
return convertView;
}
};
// inflate channel selection view
View channelSelectionView = getLayoutInflater().inflate(R.layout.dialog_channel_selection_list, getParentViewGroup(), false);
channelSelectionView.findViewById(R.id.channel_selection_selection_buttons).setVisibility(View.GONE);
channelSelectionView.findViewById(R.id.channel_selection_input_id_name).setVisibility(View.GONE);
TextView infoView = (TextView)channelSelectionView.findViewById(R.id.channel_selection_label_id_name);
if(help != null) {
infoView.setText(help);
infoView.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.epg_donate_info_font_size));
}
else {
infoView.setVisibility(View.GONE);
}
// get spinner for country filtering and create array adapter with all available countries
Spinner country = (Spinner)channelSelectionView.findViewById(R.id.channel_country_value);
final ArrayAdapter<Country> countryListAdapter = new ArrayAdapter<Country>(this, android.R.layout.simple_spinner_item, countryList);
countryListAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
country.setAdapter(countryListAdapter);
// add item selection listener to react of user setting filter for country
country.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected (AdapterView<?> parent, View view, int position, long id) {
Country country = countryListAdapter.getItem(position);
filter.mCountry = country.getCountry();
channelSelectionList.setFilter(filter);
channelSelectionAdapter.notifyDataSetChanged();
}
@Override
public void onNothingSelected (AdapterView<?> parent) {}
});
// get spinner for category selection and add listener to react to user category selection
Spinner category = (Spinner)channelSelectionView.findViewById(R.id.channel_category_value);
category.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected (AdapterView<?> parent, View view, int position, long id) {
switch(position) {
case 1: filter.mCategory = SettingConstants.TV_CATEGORY;break;
case 2: filter.mCategory = SettingConstants.RADIO_CATEGORY;break;
case 3: filter.mCategory = SettingConstants.CINEMA_CATEGORY;break;
default: filter.mCategory = SettingConstants.NO_CATEGORY;break;
}
channelSelectionList.setFilter(filter);
channelSelectionAdapter.notifyDataSetChanged();
}
@Override
public void onNothingSelected (AdapterView<?> parent) {}
});
if(delete) {
channelSelectionView.findViewById(R.id.channel_country_label).setVisibility(View.GONE);
channelSelectionView.findViewById(R.id.channel_category_label).setVisibility(View.GONE);
country.setVisibility(View.GONE);
category.setVisibility(View.GONE);
}
// get the list view of the layout and add adapter with available channels
ListView list = (ListView)channelSelectionView.findViewById(R.id.channel_selection_list);
list.setAdapter(channelSelectionAdapter);
// add listener to react to user selection of channels
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
CheckBox check = (CheckBox)view.findViewById(R.id.row_of_channel_selection);
if(check != null) {
check.setChecked(!check.isChecked());
channelSelectionAdapter.getItem(position).setSelected(check.isChecked());
}
}
});
// show dialog only if channels are available
if(!channelSelectionList.isEmpty()) {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
if(title == null) {
builder.setTitle(R.string.select_channels);
}
else {
builder.setTitle(title);
}
builder.setView(channelSelectionView);
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
boolean somethingSelected = false;
boolean somethingChanged = false;
Iterator<ChannelSelection> it = channelSelectionList.superIterator();
StringBuilder deleteWhere = new StringBuilder();
HashSet<String> keep = new HashSet<String>();
while(it.hasNext()) {
ChannelSelection sel = it.next();
if(sel.isSelected() && !sel.wasSelected()) {
somethingChanged = somethingSelected = true;
if(delete) {
if(deleteWhere.length() > 0) {
deleteWhere.append(", ");
}
deleteWhere.append(sel.getChannelID());
}
else {
ContentValues values = new ContentValues();
values.put(TvBrowserContentProvider.CHANNEL_KEY_SELECTION, 1);
getContentResolver().update(ContentUris.withAppendedId(TvBrowserContentProvider.CONTENT_URI_CHANNELS, sel.getChannelID()), values, null, null);
}
}
else if(!sel.isSelected() && sel.wasSelected()) {
somethingChanged = true;
ContentValues values = new ContentValues();
values.put(TvBrowserContentProvider.CHANNEL_KEY_SELECTION, 0);
getContentResolver().update(ContentUris.withAppendedId(TvBrowserContentProvider.CONTENT_URI_CHANNELS, sel.getChannelID()), values, null, null);
getContentResolver().delete(TvBrowserContentProvider.CONTENT_URI_DATA_VERSION, TvBrowserContentProvider.CHANNEL_KEY_CHANNEL_ID + "=" + sel.getChannelID(), null);
getContentResolver().delete(TvBrowserContentProvider.CONTENT_URI_DATA, TvBrowserContentProvider.CHANNEL_KEY_CHANNEL_ID + "=" + sel.getChannelID(), null);
}
else if(delete && !sel.isSelected()) {
keep.add(String.valueOf(sel.getChannelID()));
}
}
if(delete) {
if(deleteWhere.length() > 0) {
deleteWhere.insert(0, TvBrowserContentProvider.KEY_ID + " IN ( ");
deleteWhere.append(" ) ");
Log.d("info2", "DELETE WHERE FOR REMOVED CHANNELS " + deleteWhere.toString());
int count = getContentResolver().delete(TvBrowserContentProvider.CONTENT_URI_CHANNELS, deleteWhere.toString(), null);
Log.d("info2", "REMOVED CHANNELS COUNT " + count);
}
Editor edit = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this).edit();
edit.putStringSet(getString(R.string.PREF_KEPT_DELETED_CHANNELS), keep);
edit.commit();
}
// if something was changed we need to update channel list bar in program list and the complete program table
if(somethingChanged) {
SettingConstants.initializeLogoMap(TvBrowser.this, true);
updateProgramListChannelBar();
PrefUtils.updateChannelSelectionState(getApplicationContext());
}
// if something was selected we need to download new data
if(somethingSelected && !delete) {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.dialog_info_channels_sort_title);
builder.setMessage(R.string.dialog_info_channels_sort_message);
builder.setPositiveButton(R.string.dialog_info_channels_sort_ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
sortChannels(true);
}
});
builder.setNegativeButton(getString(R.string.not_now).replace("{0}", ""), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
checkTermsAccepted();
}
});
showAlertDialog(builder);
}
}
});
builder.setNegativeButton(android.R.string.cancel, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(delete) {
HashSet<String> keep = new HashSet<String>();
Iterator<ChannelSelection> it = channelSelectionList.superIterator();
while(it.hasNext()) {
ChannelSelection sel = it.next();
keep.add(String.valueOf(sel.getChannelID()));
}
Editor edit = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this).edit();
edit.putStringSet(getString(R.string.PREF_KEPT_DELETED_CHANNELS), keep);
edit.commit();
}
}
});
showAlertDialog(builder);
}
}
selectingChannels = false;
}
private static class ChannelSort implements SortInterface {
private String mName;
private int mKey;
private int mSortNumber;
private int mOldSortNumber;
private Bitmap mChannelLogo;
private boolean mIsEpgDonateChannel;
public ChannelSort(int key, String name, int sortNumber, Bitmap channelLogo, String dataServiceId) {
mKey = key;
mName = name;
mOldSortNumber = mSortNumber = sortNumber;
mChannelLogo = channelLogo;
mIsEpgDonateChannel = SettingConstants.EPG_DONATE_KEY.equals(dataServiceId);
}
public int getKey() {
return mKey;
}
@Override
public void setSortNumber(int value) {
mSortNumber = value;
}
@Override
public int getSortNumber() {
return mSortNumber;
}
public String toString() {
return (mSortNumber == 0 ? "-" : mSortNumber) + ". " + mName;
}
@Override
public String getName() {
return mName;
}
public Bitmap getLogo() {
return mChannelLogo;
}
public boolean wasChanged() {
return mOldSortNumber != mSortNumber;
}
public boolean isEpgDonateChannel() {
return mIsEpgDonateChannel;
}
}
private void runChannelDownload() {
if(!TvDataUpdateService.isRunning()) {
Intent updateChannels = new Intent(TvBrowser.this, TvDataUpdateService.class);
updateChannels.putExtra(SettingConstants.EXTRA_DATA_UPDATE_TYPE, TvDataUpdateService.TYPE_UPDATE_MANUELL);
updateChannels.putExtra(TvDataUpdateService.KEY_TYPE, TvDataUpdateService.TYPE_CHANNEL);
final IntentFilter filter = new IntentFilter(SettingConstants.CHANNEL_DOWNLOAD_COMPLETE);
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateProgressIcon(false);
LocalBroadcastManager.getInstance(TvBrowser.this).unregisterReceiver(this);
boolean success = intent.getBooleanExtra(SettingConstants.EXTRA_CHANNEL_DOWNLOAD_SUCCESSFULLY, false);
if(mIsActive) {
if(success) {
handler.post(new Runnable() {
@Override
public void run() {
showChannelSelection();
}
});
}
else {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.channel_download_warning_title);
builder.setMessage(R.string.channel_download_warning_text);
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
handler.post(new Runnable() {
@Override
public void run() {
showChannelSelection();
}
});
}
});
showAlertDialog(builder);
}
}
}
};
LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter);
updateProgressIcon(true);
startService(updateChannels);
}
}
private void selectChannels(boolean loadAgain) {
if(IOUtils.isDatabaseAccessible(TvBrowser.this)) {
final Cursor channels = getContentResolver().query(TvBrowserContentProvider.CONTENT_URI_CHANNELS, null, null, null, null);
try {
if(loadAgain || channels == null || (channels != null && channels.getCount() < 1)) {
if(isOnline()) {
runChannelDownload();
}
else {
showNoInternetConnection(getString(R.string.no_network_info_data_channel_download), new Runnable() {
@Override
public void run() {
checkTermsAccepted();
}
});
}
}
else {
handler.post(new Runnable() {
@Override
public void run() {
showChannelSelection();
}
});
}
}finally {
IOUtils.close(channels);
}
}
}
private void sortChannels(final boolean showDownload) {
if(IOUtils.isDatabaseAccessible(TvBrowser.this)) {
ContentResolver cr = getContentResolver();
StringBuilder where = new StringBuilder(TvBrowserContentProvider.CHANNEL_KEY_SELECTION);
where.append("=1");
LinearLayout main = (LinearLayout)getLayoutInflater().inflate(R.layout.channel_sort_list, getParentViewGroup(), false);
Button sortAlphabetically = (Button)main.findViewById(R.id.channel_sort_alpabetically);
final DynamicListView channelSort = (DynamicListView)main.findViewById(R.id.channel_sort);
final String[] projection = {
TvBrowserContentProvider.CHANNEL_TABLE+"."+TvBrowserContentProvider.KEY_ID +" AS "+TvBrowserContentProvider.KEY_ID,
TvBrowserContentProvider.GROUP_KEY_DATA_SERVICE_ID,
TvBrowserContentProvider.CHANNEL_KEY_NAME,
TvBrowserContentProvider.CHANNEL_KEY_SELECTION,
TvBrowserContentProvider.CHANNEL_KEY_LOGO,
TvBrowserContentProvider.CHANNEL_KEY_ORDER_NUMBER
};
final ArrayList<SortInterface> channelSource = new ArrayList<SortInterface>();
Cursor channels = cr.query(TvBrowserContentProvider.CONTENT_URI_CHANNELS_WITH_GROUP, projection, where.toString(), null, TvBrowserContentProvider.CHANNEL_KEY_ORDER_NUMBER);
try {
if(IOUtils.prepareAccessFirst(channels)) {
final int indexIndex = channels.getColumnIndex(TvBrowserContentProvider.KEY_ID);
final int indexName = channels.getColumnIndex(TvBrowserContentProvider.CHANNEL_KEY_NAME);
final int indexOrder = channels.getColumnIndex(TvBrowserContentProvider.CHANNEL_KEY_ORDER_NUMBER);
final int indexLogo = channels.getColumnIndex(TvBrowserContentProvider.CHANNEL_KEY_LOGO);
final int indexDataService = channels.getColumnIndex(TvBrowserContentProvider.GROUP_KEY_DATA_SERVICE_ID);
do {
final int key = channels.getInt(indexIndex);
final String name = channels.getString(indexName);
int order = 0;
if(!channels.isNull(indexOrder)) {
order = channels.getInt(indexOrder);
}
Bitmap channelLogo = UiUtils.createBitmapFromByteArray(channels.getBlob(indexLogo));
if(channelLogo != null) {
BitmapDrawable l = new BitmapDrawable(getResources(), channelLogo);
ColorDrawable background = new ColorDrawable(SettingConstants.LOGO_BACKGROUND_COLOR);
background.setBounds(0, 0, channelLogo.getWidth()+2,channelLogo.getHeight()+2);
LayerDrawable logoDrawable = new LayerDrawable(new Drawable[] {background,l});
logoDrawable.setBounds(background.getBounds());
l.setBounds(2, 2, channelLogo.getWidth(), channelLogo.getHeight());
channelLogo = UiUtils.drawableToBitmap(logoDrawable);
}
channelSource.add(new ChannelSort(key, name, order, channelLogo, channels.getString(indexDataService)));
} while(channels.moveToNext());
final Comparator<SortInterface> sortComparator = new Comparator<SortInterface>() {
@Override
public int compare(SortInterface lhs, SortInterface rhs) {
if(lhs.getSortNumber() < rhs.getSortNumber()) {
return -1;
}
else if(lhs.getSortNumber() > rhs.getSortNumber()) {
return 1;
}
return 0;
}
};
Collections.sort(channelSource, sortComparator);
// create default logo for channels without logo
final Bitmap defaultLogo = BitmapFactory.decodeResource( getResources(), R.drawable.ic_launcher);
final StableArrayAdapter<SortInterface> aa = new StableArrayAdapter<SortInterface>(TvBrowser.this, R.layout.channel_sort_row, channelSource) {
public View getView(int position, View convertView, ViewGroup parent) {
final ChannelSort value = (ChannelSort)getItem(position);
ViewHolder holder = null;
if (convertView == null) {
final LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.channel_sort_row, getParentViewGroup(), false);
holder.mTextView = (TextView)convertView.findViewById(R.id.row_of_channel_sort_text);
holder.mSortNumber = (TextView)convertView.findViewById(R.id.row_of_channel_sort_number);
holder.mLogo = (ImageView)convertView.findViewById(R.id.row_of_channel_sort_icon);
convertView.setTag(holder);
}
else {
holder = (ViewHolder)convertView.getTag();
}
final SpannableStringBuilder nameBuilder = new SpannableStringBuilder(value.getName());
if(value.isEpgDonateChannel()) {
nameBuilder.append("\n(EPGdonate)");
nameBuilder.setSpan(new RelativeSizeSpan(0.65f), value.getName().length(), nameBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
holder.mTextView.setText(nameBuilder);
String sortNumber = String.valueOf(value.getSortNumber());
if(value.getSortNumber() == 0) {
sortNumber = "-";
}
sortNumber += ".";
holder.mSortNumber.setText(sortNumber);
final Bitmap logo = value.getLogo();
if(logo != null) {
holder.mLogo.setImageBitmap(logo);
}
else {
holder.mLogo.setImageBitmap(defaultLogo);
}
return convertView;
}
};
channelSort.setAdapter(aa);
channelSort.setArrayList(channelSource);
channelSort.setSortDropListener(new SortDropListener() {
@Override
public void dropped(int originalPosition, int position) {
int startIndex = originalPosition;
int endIndex = position;
if(originalPosition > position) {
startIndex = position;
endIndex = originalPosition;
}
int previousNumber = 0;
if(startIndex > 0) {
previousNumber = aa.getItem(startIndex-1).getSortNumber();
}
int firstVisible = channelSort.getFirstVisiblePosition();
boolean changed = false;
for(int i = startIndex; i <= endIndex; i++) {
if(i == position || aa.getItem(i).getSortNumber() != 0) {
changed = true;
aa.getItem(i).setSortNumber(++previousNumber);
if(i >= firstVisible) {
View line = channelSort.getChildAt(i-firstVisible);
if(line != null) {
((TextView)line.findViewById(R.id.row_of_channel_sort_number)).setText(String.valueOf(previousNumber)+".");
}
}
}
}
if(!changed) {
aa.getItem(position).setSortNumber(position+1);
}
}
});
channelSort.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(final AdapterView<?> adapterView, final View view, final int position,
long id) {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
LinearLayout numberSelection = (LinearLayout)getLayoutInflater().inflate(R.layout.sort_number_selection, getParentViewGroup(), false);
mSelectionNumberChanged = false;
final NumberPicker number = (NumberPicker)numberSelection.findViewById(R.id.sort_picker);
number.setMinValue(1);
number.setMaxValue(channelSource.size());
number.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
number.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
mSelectionNumberChanged = true;
}
});
final EditText numberAlternative = (EditText)numberSelection.findViewById(R.id.sort_entered_number);
builder.setView(numberSelection);
final ChannelSort selection = (ChannelSort)channelSource.get(position);
TextView name = (TextView)numberSelection.findViewById(R.id.sort_picker_channel_name);
name.setText(selection.getName());
if(selection.getSortNumber() > 0) {
if(selection.getSortNumber() < channelSource.size()+1) {
number.setValue(selection.getSortNumber());
}
else {
numberAlternative.setText(String.valueOf(selection.getSortNumber()));
}
}
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String test = numberAlternative.getText().toString().trim();
if(test.length() == 0 || mSelectionNumberChanged) {
selection.setSortNumber(number.getValue());
}
else {
try {
selection.setSortNumber(Integer.parseInt(test));
}catch(NumberFormatException e1) {}
}
Collections.sort(channelSource, sortComparator);
aa.notifyDataSetChanged();
}
});
builder.setNegativeButton(android.R.string.cancel, null);
showAlertDialog(builder);
}
});
sortAlphabetically.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setCancelable(false);
builder.setTitle(getString(R.string.sort_alphabetically)+"?");
builder.setMessage(R.string.dialog_sort_alphabetically_message);
builder.setPositiveButton(android.R.string.yes, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Collections.sort(channelSource, new Comparator<SortInterface>() {
@Override
public int compare(SortInterface lhs, SortInterface rhs) {
return lhs.getName().compareToIgnoreCase(rhs.getName());
}
});
for(int i = 0; i < channelSource.size(); i++) {
channelSource.get(i).setSortNumber(i+1);
}
aa.notifyDataSetChanged();
}
});
builder.setNegativeButton(android.R.string.cancel, null);
showAlertDialog(builder);
}
});
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.action_sort_channels);
builder.setView(main);
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
boolean somethingChanged = false;
for(SortInterface selection : channelSource) {
if(((ChannelSort)selection).wasChanged()) {
somethingChanged = true;
ContentValues values = new ContentValues();
values.put(TvBrowserContentProvider.CHANNEL_KEY_ORDER_NUMBER, selection.getSortNumber());
getContentResolver().update(ContentUris.withAppendedId(TvBrowserContentProvider.CONTENT_URI_CHANNELS, ((ChannelSort)selection).getKey()), values, null, null);
}
}
if(somethingChanged) {
updateProgramListChannelBar();
}
if(showDownload) {
checkTermsAccepted();
}
}
});
builder.setNegativeButton(android.R.string.cancel, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(showDownload) {
checkTermsAccepted();
}
}
});
showAlertDialog(builder);
}
}finally {
IOUtils.close(channels);
}
}
}
public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if(netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}
return false;
}
private void updateTvData(boolean checkBatterie) {
if(checkBatterie && !IOUtils.isBatterySufficient(TvBrowser.this)) {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.data_update_battery_insufficient_title);
builder.setMessage(R.string.data_update_battery_insufficient_message);
builder.setPositiveButton(R.string.data_update_battery_insufficient_ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
updateTvData(false);
}
});
builder.setNegativeButton(android.R.string.cancel, null);
showAlertDialog(builder);
}
else if(!TvDataUpdateService.isRunning() && IOUtils.isDatabaseAccessible(TvBrowser.this)) {
Cursor test = getContentResolver().query(TvBrowserContentProvider.CONTENT_URI_CHANNELS, null, TvBrowserContentProvider.CHANNEL_KEY_SELECTION + "=1", null, null);
try {
if(IOUtils.prepareAccess(test)) {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
RelativeLayout dataDownload = (RelativeLayout)getLayoutInflater().inflate(R.layout.dialog_data_update_selection, getParentViewGroup(), false);
final Spinner days = (Spinner)dataDownload.findViewById(R.id.dialog_data_update_selection_download_days);
final CheckBox pictures = (CheckBox)dataDownload.findViewById(R.id.dialog_data_update_selection_download_picture);
final Spinner autoUpdate = (Spinner)dataDownload.findViewById(R.id.dialog_data_update_preferences_auto_update_selection_type);
final Spinner frequency = (Spinner)dataDownload.findViewById(R.id.dialog_data_update_preferences_auto_update_selection_frequency);
final CheckBox onlyWiFi = (CheckBox)dataDownload.findViewById(R.id.dialog_data_update_preferences_auto_update_selection_type_connection);
final TextView timeLabel = (TextView)dataDownload.findViewById(R.id.dialog_data_update_preferences_auto_update_selection_time_label);
final TextView time = (TextView)dataDownload.findViewById(R.id.dialog_data_update_preferences_auto_update_selection_time);
time.setTextColor(onlyWiFi.getTextColors());
String currentDownloadDays = PrefUtils.getStringValue(R.string.DAYS_TO_DOWNLOAD, R.string.days_to_download_default);
final String[] possibleDownloadDays = getResources().getStringArray(R.array.download_days);
for(int i = 0; i < possibleDownloadDays.length; i++) {
if(currentDownloadDays.equals(possibleDownloadDays[i])) {
days.setSelection(i);
break;
}
}
pictures.setChecked(PrefUtils.getBooleanValue(R.string.LOAD_PICTURE_DATA, R.bool.load_picture_data_default));
String currentAutoUpdateValue = PrefUtils.getStringValue(R.string.PREF_AUTO_UPDATE_TYPE, R.string.pref_auto_update_type_default);
String currentAutoUpdateFrequency = PrefUtils.getStringValue(R.string.PREF_AUTO_UPDATE_FREQUENCY, R.string.pref_auto_update_frequency_default);
if(currentAutoUpdateValue.equals("0")) {
frequency.setEnabled(false);
onlyWiFi.setEnabled(false);
timeLabel.setEnabled(false);
time.setEnabled(false);
frequency.setVisibility(View.GONE);
onlyWiFi.setVisibility(View.GONE);
timeLabel.setVisibility(View.GONE);
time.setVisibility(View.GONE);
}
else if(currentAutoUpdateValue.equals("1")) {
autoUpdate.setSelection(1);
timeLabel.setEnabled(false);
time.setEnabled(false);
timeLabel.setVisibility(View.GONE);
time.setVisibility(View.GONE);
}
else if(currentAutoUpdateValue.equals("2")) {
autoUpdate.setSelection(2);
}
final String[] autoFrequencyPossibleValues = getResources().getStringArray(R.array.pref_auto_update_frequency_values);
for(int i = 0; i < autoFrequencyPossibleValues.length; i++) {
if(autoFrequencyPossibleValues[i].equals(currentAutoUpdateFrequency)) {
frequency.setSelection(i);
break;
}
}
onlyWiFi.setChecked(PrefUtils.getBooleanValue(R.string.PREF_AUTO_UPDATE_ONLY_WIFI, R.bool.pref_auto_update_only_wifi_default));
final AtomicInteger currentAutoUpdateTime = new AtomicInteger(PrefUtils.getIntValue(R.string.PREF_AUTO_UPDATE_START_TIME, R.integer.pref_auto_update_start_time_default));
Calendar now = Calendar.getInstance();
now.set(Calendar.HOUR_OF_DAY, currentAutoUpdateTime.get()/60);
now.set(Calendar.MINUTE, currentAutoUpdateTime.get()%60);
now.set(Calendar.SECOND, 0);
now.set(Calendar.MILLISECOND, 0);
time.setText(DateFormat.getTimeFormat(TvBrowser.this).format(now.getTime()));
autoUpdate.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
frequency.setEnabled(position != 0);
onlyWiFi.setEnabled(position != 0);
if(position != 0) {
frequency.setVisibility(View.VISIBLE);
onlyWiFi.setVisibility(View.VISIBLE);
}
else {
frequency.setVisibility(View.GONE);
onlyWiFi.setVisibility(View.GONE);
}
timeLabel.setEnabled(position == 2);
time.setEnabled(position == 2);
if(position == 2) {
timeLabel.setVisibility(View.VISIBLE);
time.setVisibility(View.VISIBLE);
}
else {
timeLabel.setVisibility(View.GONE);
time.setVisibility(View.GONE);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder b2 = new AlertDialog.Builder(TvBrowser.this);
LinearLayout timeSelection = (LinearLayout)getLayoutInflater().inflate(R.layout.dialog_data_update_selection_auto_update_time, getParentViewGroup(), false);
final TimePicker timePick = (TimePicker)timeSelection.findViewById(R.id.dialog_data_update_selection_auto_update_selection_time);
timePick.setIs24HourView(DateFormat.is24HourFormat(TvBrowser.this));
CompatUtils.setTimePickerHour(timePick, currentAutoUpdateTime.get()/60);
CompatUtils.setTimePickerMinute(timePick, currentAutoUpdateTime.get()%60);
b2.setView(timeSelection);
b2.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
currentAutoUpdateTime.set(CompatUtils.getTimePickerHour(timePick) * 60 + CompatUtils.getTimePickerMinute(timePick));
Calendar now = Calendar.getInstance();
now.set(Calendar.HOUR_OF_DAY, currentAutoUpdateTime.get()/60);
now.set(Calendar.MINUTE, currentAutoUpdateTime.get()%60);
now.set(Calendar.SECOND, 0);
now.set(Calendar.MILLISECOND, 0);
time.setText(DateFormat.getTimeFormat(TvBrowser.this).format(now.getTime()));
}
});
b2.setNegativeButton(android.R.string.cancel, null);
showAlertDialog(b2);
}
};
time.setOnClickListener(onClickListener);
timeLabel.setOnClickListener(onClickListener);
builder.setTitle(R.string.download_data);
builder.setView(dataDownload);
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String value = possibleDownloadDays[days.getSelectedItemPosition()];
Editor settings = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this).edit();
if(PrefUtils.getStringValueAsInt(R.string.PREF_AUTO_UPDATE_RANGE, R.string.pref_auto_update_range_default) < Integer.parseInt(value)) {
settings.putString(getString(R.string.PREF_AUTO_UPDATE_RANGE), value);
}
settings.putString(getString(R.string.DAYS_TO_DOWNLOAD), value);
settings.putBoolean(getString(R.string.LOAD_PICTURE_DATA), pictures.isChecked());
settings.putString(getString(R.string.PREF_AUTO_UPDATE_TYPE), String.valueOf(autoUpdate.getSelectedItemPosition()));
if(autoUpdate.getSelectedItemPosition() == 1 || autoUpdate.getSelectedItemPosition() == 2) {
settings.putString(getString(R.string.PREF_AUTO_UPDATE_FREQUENCY), autoFrequencyPossibleValues[frequency.getSelectedItemPosition()]);
settings.putBoolean(getString(R.string.PREF_AUTO_UPDATE_ONLY_WIFI), onlyWiFi.isChecked());
if(autoUpdate.getSelectedItemPosition() == 2) {
settings.putInt(getString(R.string.PREF_AUTO_UPDATE_START_TIME), currentAutoUpdateTime.get());
}
}
settings.commit();
IOUtils.handleDataUpdatePreferences(TvBrowser.this);
Intent startDownload = new Intent(TvBrowser.this, TvDataUpdateService.class);
startDownload.putExtra(SettingConstants.EXTRA_DATA_UPDATE_TYPE, TvDataUpdateService.TYPE_UPDATE_MANUELL);
startDownload.putExtra(TvDataUpdateService.KEY_TYPE, TvDataUpdateService.TYPE_TV_DATA);
startDownload.putExtra(getResources().getString(R.string.DAYS_TO_DOWNLOAD), Integer.parseInt(value));
startService(startDownload);
updateProgressIcon(true);
}
});
builder.setNegativeButton(android.R.string.cancel, null);
showAlertDialog(builder);
}
else {
Cursor test2 = getContentResolver().query(TvBrowserContentProvider.CONTENT_URI_CHANNELS, null, null, null, null);
boolean loadAgain = true;
try {
loadAgain = (test2 == null || test2.getCount() < 1);
}finally {
IOUtils.close(test2);
}
selectChannels(loadAgain);
}
}finally {
IOUtils.close(test);
}
}
}
private void storeUserName(final String userName, final String password, final boolean syncChannels) {
Editor edit = getSharedPreferences("transportation", Context.MODE_PRIVATE).edit();
edit.putString(SettingConstants.USER_NAME, userName);
edit.putString(SettingConstants.USER_PASSWORD, password);
edit.commit();
Fragment fragment = mSectionsPagerAdapter.getRegisteredFragment(2);
if(fragment instanceof FragmentFavorites) {
((FragmentFavorites)fragment).updateSynchroButton(null);
}
if(syncChannels) {
syncronizeChannels();
}
updateSynchroMenu();
}
private void showUserError(final String userName, final String password, final boolean syncChannels) {
handler.post(new Runnable() {
@Override
public void run() {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.userpass_error_title);
builder.setMessage(R.string.userpass_error);
builder.setPositiveButton(getResources().getString(R.string.userpass_reenter), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
handler.post(new Runnable() {
@Override
public void run() {
showUserSetting(userName,password,syncChannels);
}
});
}
});
builder.setNegativeButton(getResources().getString(R.string.userpass_save_anyway), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
storeUserName(userName,password,syncChannels);
}
});
showAlertDialog(builder);
}
});
}
private void setUserName(final String userName, final String password, final boolean syncChannels) {
if(userName != null && password != null) {
new Thread() {
public void run() {
URLConnection connection = null;
try {
URL documentUrl = new URL(SettingConstants.URL_SYNC_BASE + "data/scripts/testMyAccount.php");
connection = documentUrl.openConnection();
IOUtils.setConnectionTimeoutDefault(connection);
String userpass = userName + ":" + password;
String basicAuth = "basic " + Base64.encodeToString(userpass.getBytes(), Base64.NO_WRAP);
connection.setRequestProperty ("Authorization", basicAuth);
if(((HttpURLConnection)connection).getResponseCode() != 200) {
showUserError(userName,password,syncChannels);
}
else {
handler.post(new Runnable() {
@Override
public void run() {
storeUserName(userName,password,syncChannels);
}
});
}
}catch(Throwable t) {
showUserError(userName,password,syncChannels);
} finally {
IOUtils.disconnect(connection);
}
}
}.start();
}
else if(syncChannels) {
syncronizeChannels();
}
}
private void showUserSetting(final boolean syncChannels) {
showUserSetting(null,null,syncChannels);
}
private void showUserSetting(final String initiateUserName, final String initiatePassword, final boolean syncChannels) {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setCancelable(false);
RelativeLayout username_password_setup = (RelativeLayout)getLayoutInflater().inflate(R.layout.username_password_setup, getParentViewGroup(), false);
final SharedPreferences pref = getSharedPreferences("transportation", Context.MODE_PRIVATE);
final EditText userName = (EditText)username_password_setup.findViewById(R.id.username_entry);
final EditText password = (EditText)username_password_setup.findViewById(R.id.password_entry);
userName.setText(pref.getString(SettingConstants.USER_NAME, initiateUserName != null ? initiateUserName : ""));
password.setText(pref.getString(SettingConstants.USER_PASSWORD, initiatePassword != null? initiatePassword : ""));
builder.setView(username_password_setup);
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
setUserName(userName.getText().toString().trim(), password.getText().toString().trim(), syncChannels);
}
});
builder.setNegativeButton(android.R.string.cancel, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(syncChannels) {
handler.post(new Runnable() {
@Override
public void run() {
showChannelSelectionInternal();
}
});
}
}
});
showAlertDialog(builder,R.id.user_pw_sync_info,null,null);
}
private void showNoInternetConnection(String type, final Runnable callback) {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.no_network);
builder.setMessage(getString(R.string.no_network_info).replace("{0}", type));
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(callback != null && isOnline()) {
callback.run();
}
}
});
showAlertDialog(builder);
}
private void checkTermsAccepted() {
handler.post(new Runnable() {
@Override
public void run() {
checkTermsAcceptedInUIThread();
}
});
}
private void checkTermsAcceptedInUIThread() {
final SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String terms = pref.getString(SettingConstants.TERMS_ACCEPTED, "");
if(terms.contains("EPG_FREE")) {
updateTvData(true);
}
else {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.terms_of_use_data);
builder.setMessage(R.string.terms_of_use_text);
builder.setPositiveButton(R.string.terms_of_use_accept, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Editor edit = pref.edit();
edit.putString(SettingConstants.TERMS_ACCEPTED, "EPG_FREE");
edit.commit();
updateTvData(true);
}
});
builder.setNegativeButton(android.R.string.cancel, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
showAlertDialog(builder, true);
}
}
private static final class ExclusionEdit implements Comparable<ExclusionEdit> {
String mExclusion;
boolean mIsCaseSensitive;
public ExclusionEdit(String exclusion) {
String[] parts = exclusion.split(";;");
mExclusion = parts[0];
mIsCaseSensitive = parts[1].equals("1");
}
@Override
public String toString() {
return mExclusion;
}
@Override
public int compareTo(ExclusionEdit another) {
return mExclusion.replace("*", "").compareToIgnoreCase(another.mExclusion.replace("*", ""));
}
public String getExclusion() {
return mExclusion + ";;" + (mIsCaseSensitive ? "1" : "0");
}
}
private void editDontWantToSee() {
if(!SettingConstants.UPDATING_FILTER) {
Set<String> currentExclusions = PrefUtils.getStringSetValue(R.string.I_DONT_WANT_TO_SEE_ENTRIES, null);
final ArrayList<ExclusionEdit> mCurrentExclusionList = new ArrayList<TvBrowser.ExclusionEdit>();
if(currentExclusions != null && !currentExclusions.isEmpty()) {
for(String exclusion : currentExclusions) {
mCurrentExclusionList.add(new ExclusionEdit(exclusion));
}
}
Collections.sort(mCurrentExclusionList);
final ArrayAdapter<ExclusionEdit> exclusionAdapter = new ArrayAdapter<TvBrowser.ExclusionEdit>(TvBrowser.this, android.R.layout.simple_list_item_1, mCurrentExclusionList);
View view = getLayoutInflater().inflate(R.layout.dont_want_to_see_exclusion_edit_list, getParentViewGroup(), false);
ListView list = (ListView)view.findViewById(R.id.dont_want_to_see_exclusion_list);
list.setAdapter(exclusionAdapter);
final Runnable cancel = new Runnable() {
@Override
public void run() {}
};
AdapterView.OnItemClickListener onClickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final ExclusionEdit edit = exclusionAdapter.getItem(position);
View editView = getLayoutInflater().inflate(R.layout.dont_want_to_see_edit, getParentViewGroup(), false);
final TextView exclusion = (TextView)editView.findViewById(R.id.dont_want_to_see_value);
final CheckBox caseSensitive = (CheckBox)editView.findViewById(R.id.dont_want_to_see_case_sensitve);
exclusion.setText(edit.mExclusion);
caseSensitive.setSelected(edit.mIsCaseSensitive);
Runnable editPositive = new Runnable() {
@Override
public void run() {
if(exclusion.getText().toString().trim().length() > 0) {
edit.mExclusion = exclusion.getText().toString();
edit.mIsCaseSensitive = caseSensitive.isSelected();
exclusionAdapter.notifyDataSetChanged();
}
}
};
showAlertDialog(getString(R.string.action_dont_want_to_see), null, editView, null, editPositive, null, cancel, false, false);
}
};
list.setOnItemClickListener(onClickListener);
list.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
getMenuInflater().inflate(R.menu.don_want_to_see_context, menu);
MenuItem item = menu.findItem(R.id.dont_want_to_see_delete);
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
ExclusionEdit edit = exclusionAdapter.getItem(((AdapterView.AdapterContextMenuInfo)item.getMenuInfo()).position);
exclusionAdapter.remove(edit);
exclusionAdapter.notifyDataSetChanged();
return true;
}
});
}
});
Thread positive = new Thread() {
@Override
public void run() {
SettingConstants.UPDATING_FILTER = true;
final NotificationCompat.Builder builder = new NotificationCompat.Builder(TvBrowser.this);
builder.setSmallIcon(R.drawable.ic_stat_notify);
builder.setOngoing(true);
builder.setContentTitle(getResources().getText(R.string.action_dont_want_to_see));
builder.setContentText(getResources().getText(R.string.dont_want_to_see_refresh_notification_text));
builder.setProgress(0, 0, true);
final int notifyID = 2;
final NotificationManager notification = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notification.notify(notifyID, builder.build());
updateProgressIcon(true);
HashSet<String> newExclusions = new HashSet<String>();
final ArrayList<DontWantToSeeExclusion> exclusionList = new ArrayList<DontWantToSeeExclusion>();
for(ExclusionEdit edit : mCurrentExclusionList) {
String exclusion = edit.getExclusion();
newExclusions.add(exclusion);
exclusionList.add(new DontWantToSeeExclusion(exclusion));
}
new Thread() {
public void run() {
if(IOUtils.isDatabaseAccessible(TvBrowser.this)) {
MemorySizeConstrictedDatabaseOperation dontWantToSeeUpdate = new MemorySizeConstrictedDatabaseOperation(TvBrowser.this, null);
//ArrayList<ContentProviderOperation> updateValuesList = new ArrayList<ContentProviderOperation>();
Cursor programs = getContentResolver().query(TvBrowserContentProvider.CONTENT_URI_DATA, new String[] {TvBrowserContentProvider.KEY_ID,TvBrowserContentProvider.DATA_KEY_TITLE}, null, null, TvBrowserContentProvider.KEY_ID);
try {
if(IOUtils.prepareAccess(programs)) {
int count = programs.getCount()/10;
builder.setProgress(count, 0, false);
notification.notify(notifyID, builder.build());
int keyColumn = programs.getColumnIndex(TvBrowserContentProvider.KEY_ID);
int titleColumn = programs.getColumnIndex(TvBrowserContentProvider.DATA_KEY_TITLE);
DontWantToSeeExclusion[] exclusionArr = exclusionList.toArray(new DontWantToSeeExclusion[exclusionList.size()]);
while(programs.moveToNext()) {
int position = programs.getPosition();
if(position % 10 == 0) {
builder.setProgress(count, position/10, false);
notification.notify(notifyID, builder.build());
}
String title = programs.getString(titleColumn);
boolean filter = UiUtils.filter(getApplicationContext(), title, exclusionArr);
long progID = programs.getLong(keyColumn);
ContentValues values = new ContentValues();
values.put(TvBrowserContentProvider.DATA_KEY_DONT_WANT_TO_SEE, filter ? 1 : 0);
ContentProviderOperation.Builder opBuilder = ContentProviderOperation.newUpdate(ContentUris.withAppendedId(TvBrowserContentProvider.CONTENT_URI_DATA_UPDATE, progID));
opBuilder.withValues(values);
dontWantToSeeUpdate.addUpdate(opBuilder.build());
//updateValuesList.add(opBuilder.build());
}
notification.cancel(notifyID);
}
}finally {
IOUtils.close(programs);
}
if(dontWantToSeeUpdate.operationsAvailable()) {
dontWantToSeeUpdate.finish();
//getContentResolver().applyBatch(TvBrowserContentProvider.AUTHORITY, updateValuesList);
UiUtils.sendDontWantToSeeChangedBroadcast(getApplicationContext(),true);
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), R.string.dont_want_to_see_sync_success, Toast.LENGTH_LONG).show();
}
});
}
else {
dontWantToSeeUpdate.cancel();
}
updateProgressIcon(false);
SettingConstants.UPDATING_FILTER = false;
}
}
}.start();
Editor edit = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit();
edit.putStringSet(getString(R.string.I_DONT_WANT_TO_SEE_ENTRIES), newExclusions);
edit.commit();
}
};
showAlertDialog(getString(R.string.action_dont_want_to_see_edit), null, view, null, positive, null, cancel, false, true);
}
}
public void showAlertDialog(String title, String message, View view, String positiveText, final Runnable positive, String negativeText, final Runnable negative, boolean link, boolean notCancelable) {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setCancelable(!notCancelable);
if(title != null) {
builder.setTitle(title);
}
if(message != null) {
builder.setMessage(message);
}
else if(view != null) {
builder.setView(view);
}
if(positive != null) {
if(positiveText == null) {
positiveText = getString(android.R.string.ok);
}
builder.setPositiveButton(positiveText, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(positive != null) {
positive.run();
}
}
});
}
if(negative != null) {
if(negativeText == null) {
negativeText = getString(android.R.string.cancel);
}
builder.setNegativeButton(negativeText, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(negative != null) {
negative.run();
}
}
});
}
showAlertDialog(builder, link);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Pass on the activity result to the helper for handling
if(mHelper != null) {
if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
// not handled, so handle it ourselves (here's where you'd
// perform any handling of activity results not related to in-app
// billing...
super.onActivityResult(requestCode, resultCode, data);
}
else {
Log.d("info", "onActivityResult handled by IABUtil.");
}
}
else {
super.onActivityResult(requestCode, resultCode, data);
}
if(requestCode == SHOW_PREFERENCES) {
updateFromPreferences(false);
}
else if(requestCode == OPEN_FILTER_EDIT) {
updateFromFilterEdit();
sendChannelFilterUpdate();
}
else if(requestCode == INSTALL_PLUGIN && mCurrentDownloadPlugin != null && mCurrentDownloadPlugin.isFile()) {
if(!mCurrentDownloadPlugin.delete()) {
mCurrentDownloadPlugin.deleteOnExit();
}
}
else if(requestCode == SHOW_PLUGIN_PREFERENCES) {
PluginPreferencesActivity.clearPlugins();
PluginServiceConnection[] plugins = PluginHandler.getAvailablePlugins();
if(plugins != null) {
for(PluginServiceConnection plugin : plugins) {
plugin.loadIcon();
}
}
}
}
private void updateFromPreferences(boolean finish) {
SettingConstants.initializeLogoMap(getApplicationContext(), true);
Fragment test1 = mSectionsPagerAdapter.getRegisteredFragment(1);
if(test1 instanceof FragmentProgramsList) {
((FragmentProgramsList)test1).updateChannels();
}
Fragment fragment = mSectionsPagerAdapter.getRegisteredFragment(2);
if(fragment instanceof FragmentFavorites) {
((FragmentFavorites)fragment).updateSynchroButton(null);
((FragmentFavorites)fragment).updateProgramsList();
}
boolean programTableActivated = PrefUtils.getBooleanValue(R.string.PROG_TABLE_ACTIVATED, R.bool.prog_table_activated_default);
Fragment test = mSectionsPagerAdapter.getRegisteredFragment(3);
if(!programTableActivated && test instanceof FragmentProgramTable) {
((FragmentProgramTable)test).removed();
mSectionsPagerAdapter.destroyItem(mViewPager, 3, mSectionsPagerAdapter.getRegisteredFragment(3));
mSectionsPagerAdapter.notifyDataSetChanged();
actionBar.removeTabAt(3);
}
else if(!(test instanceof FragmentProgramTable) && programTableActivated) {
try {
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(3)).setTabListener(this));
mSectionsPagerAdapter.notifyDataSetChanged();
mSectionsPagerAdapter.instantiateItem(mViewPager, 3);
}catch(Throwable t) {}
}
else if(test instanceof FragmentProgramTable) {
if(!((FragmentProgramTable)test).checkTimeBlockSize() && !((FragmentProgramTable)test).updateTable()) {
((FragmentProgramTable)test).updateChannelBar();
((FragmentProgramTable)test).updateMarkings();
}
}
if(mDebugMenuItem != null) {
boolean dataUpdateLogEnabled = PrefUtils.getBooleanValue(R.string.WRITE_DATA_UPDATE_LOG, R.bool.write_data_update_log_default);
boolean reminderLogEnabled = PrefUtils.getBooleanValue(R.string.WRITE_REMINDER_LOG, R.bool.write_reminder_log_default);
boolean pluginLogEnabled = PrefUtils.getBooleanValue(R.string.LOG_WRITE_PLUGIN_LOG, R.bool.log_write_plugin_log_default);
mDebugMenuItem.setVisible(dataUpdateLogEnabled || reminderLogEnabled || pluginLogEnabled);
mSendReminderLogItem.setEnabled(reminderLogEnabled);
mDeleteReminderLogItem.setEnabled(reminderLogEnabled);
mSendPluginLogItem.setEnabled(pluginLogEnabled);
mDeletePluginLogItem.setEnabled(pluginLogEnabled);
}
UiUtils.updateImportantProgramsWidget(getApplicationContext());
UiUtils.updateRunningProgramsWidget(getApplicationContext());
LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(SettingConstants.UPDATE_TIME_BUTTONS));
updateScrollMenu();
if(mUpdateItem != null && !TvDataUpdateService.isRunning()) {
if(PrefUtils.getStringValue(R.string.PREF_AUTO_UPDATE_TYPE, R.string.pref_auto_update_type_default).equals("0")) {
mUpdateItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
}
else {
mUpdateItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
invalidateOptionsMenu();
}
}
new UpdateAlarmValue().onReceive(TvBrowser.this, null);
if(PrefUtils.getBooleanValue(R.string.DARK_STYLE, R.bool.dark_style_default) != SettingConstants.IS_DARK_THEME) {
SettingConstants.IS_DARK_THEME = PrefUtils.getBooleanValue(R.string.DARK_STYLE, R.bool.dark_style_default);
Favorite.resetMarkIcons(SettingConstants.IS_DARK_THEME);
ProgramUtils.resetReminderAndSyncMarkIcon(SettingConstants.IS_DARK_THEME);
PluginServiceConnection[] plugins = PluginHandler.getAvailablePlugins();
if(plugins != null) {
for(PluginServiceConnection plugin : plugins) {
plugin.loadIcon();
}
}
finish = true;
}
final String databasePath = PrefUtils.getStringValue(R.string.PREF_DATABASE_PATH, R.string.pref_database_path_default);
final String oldPath = PrefUtils.getStringValue(R.string.PREF_DATABASE_OLD_PATH, R.string.pref_database_path_default);
if(!oldPath.equals(databasePath)) {
File source = null;
File target = null;
if(oldPath.equals(getString(R.string.pref_database_path_default))) {
source = getDatabasePath(TvBrowserContentProvider.DATABASE_TVB_NAME);
}
else {
source = new File(oldPath, TvBrowserContentProvider.DATABASE_TVB_NAME);
}
if(databasePath.equals(getString(R.string.pref_database_path_default))) {
target = getDatabasePath(TvBrowserContentProvider.DATABASE_TVB_NAME);
}
else {
target = new File(databasePath, TvBrowserContentProvider.DATABASE_TVB_NAME);
}
final SharedPreferences pref = PrefUtils.getSharedPreferences(PrefUtils.TYPE_PREFERENCES_SHARED_GLOBAL, TvBrowser.this);
if(target.getParentFile().canWrite()) {
final boolean finish2 = finish;
final ContentProviderClient client = getContentResolver().acquireContentProviderClient(TvBrowserContentProvider.AUTHORITY);
if(client != null) {
AsyncTask<File, Void, Boolean> copy = new AsyncTask<File, Void, Boolean>() {
private ProgressDialog mProgress;
private File mSource;
@Override
protected void onPreExecute() {
mProgress = ProgressDialog.show(TvBrowser.this, "Copying database", "Please wait...", true);
}
@Override
protected Boolean doInBackground(File... params) {
mSource = params[0];
return !params[0].isFile() || IOUtils.copyFile(params[0], params[1]);
}
@Override
protected void onPostExecute(Boolean result) {
if(mProgress != null) {
mProgress.dismiss();
}
if(result) {
pref.edit().putString(getString(R.string.PREF_DATABASE_OLD_PATH), databasePath).commit();
TvBrowserContentProvider provider = (TvBrowserContentProvider)client.getLocalContentProvider();
provider.updateDatabasePath();
client.release();
if(mSource != null) {
if(!mSource.delete()) {
mSource.deleteOnExit();
}
File journal = new File(mSource.getAbsolutePath()+"-journal");
if(journal.isFile() && !journal.delete()) {
journal.deleteOnExit();
}
}
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(SettingConstants.REFRESH_VIEWS));
UiUtils.reloadWidgets(getApplicationContext());
}
else {
pref.edit().putString(getString(R.string.PREF_DATABASE_PATH), oldPath).commit();
}
if(finish2) {
finish();
}
}
};
copy.execute(source,target);
}
}
else {
pref.edit().putString(getString(R.string.PREF_DATABASE_PATH), oldPath).commit();
}
}
else if(finish) {
finish();
}
else {
new Thread("CHECK EPGPAID CREDENTIALS") {
public void run() {
final String userName = PrefUtils.getStringValue(R.string.PREF_EPGPAID_USER, null);
final String password = PrefUtils.getStringValue(R.string.PREF_EPGPAID_PASSWORD, null);
if(userName != null && password != null && userName.trim().length() > 0 && password.trim().length() > 0) {
final EPGpaidDataConnection epgPaidTest = new EPGpaidDataConnection();
if(epgPaidTest.login(userName, password, getApplicationContext())) {
epgPaidTest.logout();
}
else {
handler.post(new Runnable() {
@Override
public void run() {
final AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.dialog_epgpaid_invalid_title);
builder.setMessage(R.string.dialog_epgpaid_invalid_message);
builder.setPositiveButton(android.R.string.ok, null);
showAlertDialog(builder);
}
});
}
}
}
}.start();
}
}
/*
private boolean updateTheme(boolean finish) {
return finish;
}*/
private void showVersionInfo(final boolean showDisable) {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.info_version);
builder.setMessage(Html.fromHtml(getString(R.string.info_version_new)));
builder.setPositiveButton(android.R.string.ok, null);
if(showDisable) {
builder.setNegativeButton(R.string.info_version_dont_show_again, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Editor edit = PrefUtils.getSharedPreferences(PrefUtils.TYPE_PREFERENCES_SHARED_GLOBAL, TvBrowser.this).edit();
edit.putBoolean(getString(R.string.PREF_INFO_VERSION_UPDATE_SHOW), false);
edit.commit();
}
});
}
showAlertDialog(builder, false, null, new Runnable() {
@Override
public void run() {
Editor edit = PrefUtils.getSharedPreferences(PrefUtils.TYPE_PREFERENCES_SHARED_GLOBAL, TvBrowser.this).edit();
edit.putBoolean(getString(R.string.PREF_INFO_VERSION_UPDATE_SHOW), false);
edit.commit();
}
});
}
private void showPrivacyStatement() {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(SettingConstants.URL_SYNC_BASE + "index.php?id=privacystatement")));
}
private void showAbout() {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
RelativeLayout about = (RelativeLayout)getLayoutInflater().inflate(R.layout.dialog_about, getParentViewGroup(), false);
try {
PackageInfo pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
TextView version = (TextView)about.findViewById(R.id.version);
version.setText(pInfo.versionName);
} catch (NameNotFoundException e) {
e.printStackTrace();
}
((TextView)about.findViewById(R.id.license)).setText(Html.fromHtml(getResources().getString(R.string.license)));
TextView androidVersion = (TextView)about.findViewById(R.id.android_version);
androidVersion.setText(Build.VERSION.RELEASE);
TextView lastUpdate = (TextView)about.findViewById(R.id.data_update);
lastUpdate.setText(DateFormat.getLongDateFormat(TvBrowser.this).format(new Date(PrefUtils.getLongValue(R.string.LAST_DATA_UPDATE, 0))));
TextView nextUpdate = (TextView)about.findViewById(R.id.next_data_update);
switch(Integer.parseInt(PrefUtils.getStringValue(R.string.PREF_AUTO_UPDATE_TYPE, R.string.pref_auto_update_type_default))) {
case 0: nextUpdate.setText(R.string.next_data_update_manually);break;
case 1: nextUpdate.setText(R.string.next_data_update_connection);break;
case 2: {
Date date = new Date(PrefUtils.getLongValue(R.string.AUTO_UPDATE_CURRENT_START_TIME, 0));
nextUpdate.setText(DateFormat.getMediumDateFormat(TvBrowser.this).format(date) + " " + DateFormat.getTimeFormat(TvBrowser.this).format(date));
} break;
}
TextView dataRange = (TextView)about.findViewById(R.id.data_range);
dataRange.setText(DateFormat.getMediumDateFormat(TvBrowser.this).format(new Date(PrefUtils.getLongValueWithDefaultKey(R.string.META_DATA_DATE_FIRST_KNOWN, R.integer.meta_data_date_known_default))) + " - " + DateFormat.getMediumDateFormat(TvBrowser.this).format(new Date(PrefUtils.getLongValueWithDefaultKey(R.string.META_DATA_DATE_LAST_KNOWN, R.integer.meta_data_date_known_default))));
((TextView)about.findViewById(R.id.rundate_value)).setText(DateFormat.getLongDateFormat(getApplicationContext()).format(mRundate.getTime()));
builder.setTitle(R.string.action_about);
builder.setView(about);
builder.setPositiveButton(android.R.string.ok, null);
builder.setNegativeButton(R.string.info_version_show, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
handler.post(new Runnable() {
@Override
public void run() {
showVersionInfo(false);
}
});
}
});
showAlertDialog(builder);
}
private void synchronizeDontWantToSee() {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.synchronize_replace_add_title);
builder.setMessage(R.string.synchronize_replace_exclusion_add_text);
builder.setPositiveButton(R.string.synchronize_add_exclusion, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
synchronizeDontWantToSee(false);
}
});
builder.setNegativeButton(R.string.synchronize_replace_exclusion, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
synchronizeDontWantToSee(true);
}
});
showAlertDialog(builder);
}
private void pauseReminder() {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.action_pause_reminder);
if(PrefUtils.getBooleanValue(R.string.PREF_REMINDER_STATE_KEEP, R.bool.pref_reminder_state_keep_default)) {
builder.setMessage(R.string.action_reminder_disable_text);
}
else {
builder.setMessage(R.string.action_pause_reminder_text);
}
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
SettingConstants.setReminderPaused(TvBrowser.this, true);
mPauseReminder.setVisible(false);
mContinueReminder.setVisible(true);
actionBar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#4e0002")));
UiUtils.updateToggleReminderStateWidget(getApplicationContext());
}
});
builder.setNegativeButton(android.R.string.cancel, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
showAlertDialog(builder);
}
private void sendLogMail(String file, String type) {
final File path = IOUtils.getDownloadDirectory(getApplicationContext());
File logFile = new File(path,file);
if(logFile.isFile()) {
Intent sendMail = new Intent(Intent.ACTION_SEND);
String subject = getString(R.string.log_send_mail_subject).replace("{0}", type);
String text = getString(R.string.log_send_mail_content).replace("{0}", type);
sendMail.putExtra(Intent.EXTRA_EMAIL, new String[]{"android@tvbrowser.org"});
sendMail.putExtra(Intent.EXTRA_SUBJECT, subject);
sendMail.putExtra(Intent.EXTRA_TEXT,text + " " + new Date().toString());
sendMail.setType("text/rtf");
sendMail.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + logFile.getAbsolutePath()));
startActivity(Intent.createChooser(sendMail, getResources().getString(R.string.log_send_mail)));
}
else {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.no_log_file_title);
builder.setMessage(R.string.no_log_file_message);
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {}
});
showAlertDialog(builder);
}
}
private void deleteLog(String type) {
final File path = IOUtils.getDownloadDirectory(getApplicationContext());
File logFile = new File(path,type);
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
if(logFile.isFile()) {
if(logFile.delete()) {
builder.setTitle(R.string.log_file_delete_title);
builder.setMessage(R.string.log_file_delete_message);
}
else {
builder.setTitle(R.string.log_file_no_delete_title);
builder.setMessage(R.string.log_file_no_delete_message);
logFile.deleteOnExit();
}
}
else {
builder.setTitle(R.string.no_log_file_title);
builder.setMessage(R.string.no_log_file_delete_message);
}
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {}
});
showAlertDialog(builder);
}
private void openFilterEdit() {
Intent startFilterEdit = new Intent(this, ActivityFilterListEdit.class);
startActivityForResult(startFilterEdit, OPEN_FILTER_EDIT);
}
private void sendChannelFilterUpdate() {
Intent refresh = new Intent(SettingConstants.DATA_UPDATE_DONE);
TvBrowser.this.sendBroadcast(refresh);
UiUtils.updateRunningProgramsWidget(TvBrowser.this);
updateProgramListChannelBar();
}
private void updateFilter(boolean sendUpdate) {
updateCurrentFilterPreference();
if(mFilterItem != null) {
if(mCurrentFilter.isEmpty()) {
mFilterItem.setIcon(R.drawable.ic_filter_default);
}
else {
mFilterItem.setIcon(R.drawable.ic_filter_on);
}
}
if(sendUpdate) {
sendChannelFilterUpdate();
}
}
private void clearChannelFilters() {
final FilterValues[] filterValues = mCurrentFilter.toArray(new FilterValues[mCurrentFilter.size()]);
for(FilterValues filterValue : filterValues) {
if(filterValue instanceof FilterValuesChannels) {
mCurrentFilter.remove(filterValue);
mCurrentFilterId.remove(filterValue.getId());
}
}
updateCurrentFilterPreference();
if(mCurrentFilter.isEmpty()) {
mFilterItem.setIcon(R.drawable.ic_filter_default);
}
else {
mFilterItem.setIcon(R.drawable.ic_filter_on);
}
sendChannelFilterUpdate();
}
private static final class SpecialSpan extends ReplacementSpan {
final static int RIGHT_TYPE = 0;
final static int LINE_TYPE = 1;
private int mWidth;
private int mSpanType;
public SpecialSpan(int type) {
mSpanType = type;
}
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
if(mSpanType == LINE_TYPE) {
canvas.drawLine(canvas.getClipBounds().left, top + (bottom-top)/2, canvas.getClipBounds().right, top + (bottom-top)/2, paint);
}
else if(mSpanType == RIGHT_TYPE) {
canvas.drawText(text.toString().substring(start, end), canvas.getClipBounds().right-mWidth, y, paint);
}
}
@Override
public int getSize(Paint paint, CharSequence text, int start, int end, FontMetricsInt fm) {
mWidth = (int)paint.measureText(text,start,end);
return mWidth;
}
}
private static final class NewsTagHandler implements TagHandler {
@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
if(tag.equals("right")) {
doSpecial(opening,output,SpecialSpan.RIGHT_TYPE);
}
else if(tag.equals("line")) {
doSpecial(opening,output,SpecialSpan.LINE_TYPE);
}
}
private void doSpecial(boolean opening, Editable output, int type) {
int len = output.length();
ReplacementSpan span = new SpecialSpan(type);
if(opening) {
output.setSpan(span, len, len, Spannable.SPAN_MARK_MARK);
} else {
Object obj = getLast(output, SpecialSpan.class);
int where = output.getSpanStart(obj);
output.removeSpan(obj);
if (where != len) {
output.setSpan(span, where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
private Object getLast(Editable text, Class<?> kind) {
Object[] objs = text.getSpans(0, text.length(), kind);
if (objs.length == 0) {
return null;
} else {
for(int i = objs.length;i>0;i--) {
if(text.getSpanFlags(objs[i-1]) == Spannable.SPAN_MARK_MARK) {
return objs[i-1];
}
}
return null;
}
}
}
private void showNews() {
if(!selectingChannels) {
final SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this);
if(pref.getBoolean(getString(R.string.PREF_NEWS_SHOW), getResources().getBoolean(R.bool.pref_news_show_default))) {
long lastShown = pref.getLong(getString(R.string.NEWS_DATE_LAST_SHOWN), 0);
long lastKnown = pref.getLong(getString(R.string.NEWS_DATE_LAST_KNOWN), 0);
final String news = pref.getString(getString(R.string.NEWS_TEXT), "");
if(lastShown < lastKnown && news.trim().length() > 0) {
final AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.title_news);
builder.setCancelable(false);
builder.setMessage(Html.fromHtml(news,null,new NewsTagHandler()));
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
pref.edit().putLong(getString(R.string.NEWS_DATE_LAST_SHOWN), System.currentTimeMillis()).commit();
showPluginInfo();
}
});
showAlertDialog(builder, true);
}
else {
if(news.trim().isEmpty() && lastKnown != 0) {
pref.edit().putLong(getString(R.string.NEWS_DATE_LAST_SHOWN), System.currentTimeMillis()).commit();
}
showPluginInfo();
}
}
else {
showPluginInfo();
}
}
}
private void showPluginInfo() {
Log.d("info6", "showPluginInfo");
if(!PrefUtils.getBooleanValue(R.string.PLUGIN_INFO_SHOWN, false)) {
final AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.plugin_info_title);
builder.setCancelable(false);
builder.setMessage(R.string.plugin_info_message);
builder.setPositiveButton(R.string.plugin_info_load, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
savePluginInfoShown();
if(isOnline()) {
searchPlugins(true);
}
else {
showNoInternetConnection(getString(R.string.no_network_info_data_search_plugins),new Runnable() {
@Override
public void run() {
searchPlugins(true);
}
});
}
}
});
builder.setNegativeButton(getString(R.string.not_now).replace("{0}", ""), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
savePluginInfoShown();
showChannelUpdateInfo();
}
});
showAlertDialog(builder);
}
else {
showChannelUpdateInfo();
}
}
private void showChannelUpdateInfo() {
Log.d("info6", "showChannelUpdateInfo ");
/*runOnUiThread(new Runnable() {
@Override
public void run() {*/try {
Log.d("info6", "showChannelUpdateInfo RUN");
StringBuilder selection = new StringBuilder();
String insertedChannels = PrefUtils.getStringValue(R.string.PREF_AUTO_CHANNEL_UPDATE_CHANNELS_INSERTED, null);
String updateChannels = PrefUtils.getStringValue(R.string.PREF_AUTO_CHANNEL_UPDATE_CHANNELS_UPDATED, null);
Editor edit = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this).edit();
if(insertedChannels != null) {
selection.append(insertedChannels);
edit.remove(getString(R.string.PREF_AUTO_CHANNEL_UPDATE_CHANNELS_INSERTED));
}
if(updateChannels != null) {
if(selection.length() > 0) {
selection.append(",");
}
selection.append(updateChannels);
edit.remove(getString(R.string.PREF_AUTO_CHANNEL_UPDATE_CHANNELS_UPDATED));
}
Log.d("info6", "showChannelUpdateInfo selection " + selection);
if(selection.toString().trim().length() > 0) {
edit.commit();
selection.insert(0, TvBrowserContentProvider.CHANNEL_TABLE+"."+TvBrowserContentProvider.KEY_ID + " IN ( ");
selection.append(" ) ");
showChannelSelectionInternal(selection.toString(), getString(R.string.dialog_select_channels_update_title), getString(R.string.dialog_select_channels_update_help), false);
}
else if(IOUtils.isDatabaseAccessible(TvBrowser.this)) {
Set<String> deletedChannels = PrefUtils.getStringSetValue(R.string.PREF_SECOND_DELETED_CHANNELS, new HashSet<String>());
edit.remove(getString(R.string.PREF_SECOND_DELETED_CHANNELS));
edit.commit();
StringBuilder askToDelete = new StringBuilder();
final String[] projection = {TvBrowserContentProvider.KEY_ID};
for(String deleted : deletedChannels) {
Cursor test = getContentResolver().query(TvBrowserContentProvider.CONTENT_URI_DATA, projection, TvBrowserContentProvider.CHANNEL_KEY_CHANNEL_ID + "=" + deleted, null, null);
try {
if(test == null || test.getCount() == 0) {
if(askToDelete.length() > 0) {
askToDelete.append(", ");
}
askToDelete.append(deleted);
}
}finally {
IOUtils.close(test);
}
}
Log.d("info6", "showChannelUpdateInfo askToDelete " + askToDelete.length());
if(askToDelete.length() > 0) {
askToDelete.insert(0, TvBrowserContentProvider.CHANNEL_TABLE+"."+TvBrowserContentProvider.KEY_ID + " IN ( ");
askToDelete.append(" ) ");
Log.d("info2", "ASK TO DELETE CHANNELS WHERE " + askToDelete.toString());
showChannelSelectionInternal(askToDelete.toString(), getString(R.string.dialog_select_channels_delete_title), getString(R.string.dialog_select_channels_delete_help), true);
}
else {
testTimeZone();
}
}
else {
showEpgDonateInfo();
}
}catch(Throwable t) {
Log.d("info6", "", t);
}
/* }
});*/
}
private void testTimeZone() {
Log.d("info6", "testTimeZone");
if(PrefUtils.getBooleanValue(R.string.PREF_WARNING_TIMEZONE_SHOW, R.bool.pref_warning_timezone_show_default) && "de".equals(Locale.getDefault().getLanguage()) && TimeZone.getDefault().getRawOffset() != TimeZone.getTimeZone("CET").getRawOffset()) {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(R.string.dialog_warning_timezone_title);
builder.setMessage(R.string.dialog_warning_timezone_message);
builder.setPositiveButton(R.string.dialog_warning_timezone_change, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(android.provider.Settings.ACTION_DATE_SETTINGS));
finish();
}
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.setNeutralButton(R.string.info_version_dont_show_again, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Editor edit = PrefUtils.getSharedPreferences(PrefUtils.TYPE_PREFERENCES_SHARED_GLOBAL, TvBrowser.this).edit();
edit.putBoolean(getString(R.string.PREF_WARNING_TIMEZONE_SHOW), false);
edit.commit();
}
});
showAlertDialog(builder);
}
else {
showEpgDonateInfo();
}
}
private void savePluginInfoShown() {
Editor edit = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this).edit();
edit.putBoolean(getString(R.string.PLUGIN_INFO_SHOWN), true);
edit.commit();
}
private int FILTER_MAX_ID = 0;
private synchronized void updateFromFilterEdit() {
if(mFilterItem != null) {
final SubMenu filters = mFilterItem.getSubMenu();
for(int i = 0; i < FILTER_MAX_ID; i++) {
filters.removeItem(i);
}
ArrayList<FilterValues> channelFilterList = new ArrayList<FilterValues>();
SharedPreferences filterPreferences = PrefUtils.getSharedPreferences(PrefUtils.TYPE_PREFERENCES_FILTERS, TvBrowser.this);
Map<String,?> filterValues = filterPreferences.getAll();
for(String key : filterValues.keySet()) {
Object values = filterValues.get(key);
Log.d("info2", "key " + key);
if(key.contains("filter.") && values instanceof String && values != null) {
FilterValues filter = FilterValues.load(key, (String)values);
Log.d("info2", "filter " + filter + " " + values);
if(filter != null) {
channelFilterList.add(filter);
}
}
}
Collections.sort(channelFilterList, FilterValues.COMPARATOR_FILTER_VALUES);
int groupId = 3;
int id = 1;
MenuItem all = filters.add(groupId, id++, groupId, getString(R.string.activity_edit_filter_list_text_all));
all.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
mCurrentFilterId.clear();
mCurrentFilter.clear();
for(int i = 0; i < FILTER_MAX_ID; i++) {
final MenuItem filterItem = filters.findItem(i);
if(filterItem != null) {
filterItem.setChecked(false);
}
}
updateFilter(true);
return true;
}
});
boolean isActiveFilter = false;
for(final FilterValues filter : channelFilterList) {
final MenuItem item = filters.add(Menu.NONE, id++, groupId, filter.toString());
item.setCheckable(true);
if(mCurrentFilterId.contains(filter.getId())) {
item.setChecked(true);
isActiveFilter = true;
}
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if(item.isChecked()) {
mCurrentFilterId.remove(filter.getId());
mCurrentFilter.remove(filter);
}
else {
mCurrentFilterId.add(filter.getId());
mCurrentFilter.add(filter);
}
item.setChecked(!item.isChecked());
updateFilter(true);
return true;
}
});
}
if(isActiveFilter) {
mFilterItem.setIcon(R.drawable.ic_filter_on);
}
else {
mFilterItem.setIcon(R.drawable.ic_filter_default);
}
FILTER_MAX_ID = id;
}
}
private void updateCurrentFilterPreference() {
if(mCurrentFilterId != null) {
Editor edit = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this).edit();
edit.putStringSet(getString(R.string.CURRENT_FILTER_ID), mCurrentFilterId);
edit.commit();
}
}
private void searchPlugins(final boolean showChannelUpdateInfo) {
if(isOnline()) {
new Thread("SEARCH FOR PLUGINS THREAD") {
@Override
public void run() {
updateProgressIcon(true);
PluginDefinition[] availablePlugins = PluginDefinition.loadAvailablePluginDefinitions();
final ArrayList<PluginDefinition> newPlugins = new ArrayList<PluginDefinition>();
final PluginServiceConnection[] connections = PluginHandler.getAvailablePlugins();
for(PluginDefinition def : availablePlugins) {
if(Build.VERSION.SDK_INT >= def.getMinApiVersion()) {
String packageName = def.getPackageName();
String[] services = def.getServices();
for(String service : services) {
if(service.startsWith(".")) {
service = packageName + service;
}
String[] parts = service.split(":");
boolean wasAdded = false;
boolean wasFound = false;
if(connections != null && connections.length > 0) {
for(PluginServiceConnection connection : connections) {
if(connection.getId().equals(parts[0])) {
wasFound = true;
String currentVersion = connection.getPluginVersion();
if(currentVersion != null && !currentVersion.equals(parts[1])) {
newPlugins.add(def);
def.setIsUpdate();
wasAdded = true;
break;
}
}
}
}
if(wasAdded) {
break;
}
else if(!wasFound) {
newPlugins.add(def);
}
}
}
}
StringBuilder pluginsText = new StringBuilder();
Collections.sort(newPlugins);
for(PluginDefinition news : newPlugins) {
if(pluginsText.length() > 0) {
pluginsText.append("<line>LINE</line>");
}
pluginsText.append("<h3>");
pluginsText.append(news.getName());
if(news.isUpdate()) {
pluginsText.append(" <i>(Update)</i>");
}
pluginsText.append("</h3>");
pluginsText.append(news.getDescription());
pluginsText.append("<p><i>");
pluginsText.append(getString(R.string.author)).append(" ");
pluginsText.append(news.getAuthor());
pluginsText.append(" <right>").append(getString(R.string.version)).append(" ");
pluginsText.append(news.getVersion());
pluginsText.append("</i></right></p>");
if(news.isOnGooglePlay()) {
pluginsText.append("<p><a href=\"http://play.google.com/store/apps/details?id=");
pluginsText.append(news.getPackageName());
pluginsText.append("\">").append(getString(R.string.plugin_open_google_play)).append("</a></p>");
}
if(news.getDownloadLink() != null && news.getDownloadLink().trim().length() > 0) {
pluginsText.append("<p><a href=\"");
pluginsText.append(news.getDownloadLink().replace("http://", "plugin://").replace("https://", "plugins://"));
pluginsText.append("\">").append(getString(R.string.plugin_download_manually)).append("</a></p>");
}
}
String title = getString(R.string.plugin_available_title);
if(newPlugins.isEmpty()) {
title = getString(R.string.plugin_available_not_title);
pluginsText.append(getString(R.string.plugin_available_not_message));
}
final AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle(title);
builder.setCancelable(false);
builder.setMessage(getClickableText(Html.fromHtml(pluginsText.toString(),null,new NewsTagHandler())));
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(!newPlugins.isEmpty()) {
PluginHandler.shutdownPlugins(TvBrowser.this);
handler.postDelayed(new Runnable() {
@Override
public void run() {
PluginHandler.loadPlugins(getApplicationContext());
if(mPluginPreferencesMenuItem != null) {
mPluginPreferencesMenuItem.setEnabled(PluginHandler.hasPlugins());
}
}
}, 2000);
}
if(showChannelUpdateInfo) {
handler.post(new Runnable() {
@Override
public void run() {
showChannelUpdateInfo();
}
});
}
}
});
handler.post(new Runnable() {
@Override
public void run() {
showAlertDialog(builder,true);
}
});
updateProgressIcon(false);
}
}.start();
}
}
private boolean mLoadingPlugin = false;
private File mCurrentDownloadPlugin;
private void makeLinkClickable(SpannableStringBuilder strBuilder, final URLSpan span)
{
int start = strBuilder.getSpanStart(span);
int end = strBuilder.getSpanEnd(span);
int flags = strBuilder.getSpanFlags(span);
ClickableSpan clickable = new ClickableSpan() {
public void onClick(View view) {
if(!mLoadingPlugin) {
mLoadingPlugin = true;
String url = span.getURL();
if(url.startsWith("http://play.google.com/store/apps/details?id=")) {
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url.replace("http://play.google.com/store/apps", "market:/"))));
} catch (android.content.ActivityNotFoundException anfe) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
}
mLoadingPlugin = false;
}
else if(url.startsWith("plugin://") || url.startsWith("plugins://")) {
final File path = IOUtils.getDownloadDirectory(getApplicationContext());
if(!path.isDirectory()) {
path.mkdirs();
}
if(url.startsWith("plugin://")) {
url = url.replace("plugin://", "http://");
}
else if(url.startsWith("plugins://")) {
url = url.replace("plugins://", "https://");
}
String name = url.substring(url.lastIndexOf("/")+1);
mCurrentDownloadPlugin = new File(path, name);
if(mCurrentDownloadPlugin.isFile()) {
mCurrentDownloadPlugin.delete();
}
final String downloadUrl = url;
handler.post(new Runnable() {
@Override
public void run() {
AsyncTask<String, Void, Boolean> async = new AsyncTask<String, Void, Boolean>() {
private ProgressDialog mProgress;
private File mPluginFile;
protected void onPreExecute() {
mProgress = new ProgressDialog(TvBrowser.this);
mProgress.setMessage(getString(R.string.plugin_info_donwload).replace("{0}", mCurrentDownloadPlugin.getName()));
mProgress.show();
}
@Override
protected Boolean doInBackground(String... params) {
mPluginFile = new File(params[0]);
return IOUtils.saveUrl(params[0], params[1], 15000);
}
protected void onPostExecute(Boolean result) {
mProgress.dismiss();
if(result) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(mPluginFile),"application/vnd.android.package-archive");
TvBrowser.this.startActivityForResult(intent, INSTALL_PLUGIN);
}
mLoadingPlugin = false;
}
};
async.execute(mCurrentDownloadPlugin.toString(), downloadUrl);
}
});
}
else {
mLoadingPlugin = false;
}
}
}
};
strBuilder.setSpan(clickable, start, end, flags);
strBuilder.removeSpan(span);
}
private SpannableStringBuilder getClickableText(CharSequence sequence)
{
SpannableStringBuilder strBuilder = new SpannableStringBuilder(sequence);
URLSpan[] urls = strBuilder.getSpans(0, sequence.length(), URLSpan.class);
for(URLSpan span : urls) {
makeLinkClickable(strBuilder, span);
}
return strBuilder;
}
private void editFavorite() {
Fragment favorites = mSectionsPagerAdapter.getRegisteredFragment(2);
if(favorites instanceof FragmentFavorites) {
((FragmentFavorites) favorites).editSelectedFavorite();
}
}
private void deleteFavorite() {
Fragment favorites = mSectionsPagerAdapter.getRegisteredFragment(2);
if(favorites instanceof FragmentFavorites) {
((FragmentFavorites) favorites).deleteSelectedFavorite();
}
}
public void updateFavoritesMenu(final boolean editDeleteEnabled) {
handler.post(new Runnable() {
@Override
public void run() {
if(mCreateFavorite != null) {
SubMenu menu = mCreateFavorite.getSubMenu();
menu.findItem(R.id.menu_tvbrowser_action_favorite_edit).setEnabled(editDeleteEnabled);
menu.findItem(R.id.menu_tvbrowser_action_favorite_delete).setEnabled(editDeleteEnabled);
}
}
});
}
private void showMarkingData() {
Map<String,?> mark = PrefUtils.getSharedPreferences(PrefUtils.TYPE_PREFERENCES_MARKINGS, TvBrowser.this).getAll();
StringBuilder markValue = new StringBuilder();
for(String key : mark.keySet()) {
markValue.append(key).append("=").append(mark.get(key)).append("\n");
}
if(markValue.length() == 0) {
markValue.append("NO PLUGIN MARKINGS");
}
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle("CURRENT PLUGIN MARKINGS");
builder.setMessage(markValue.toString());
builder.setPositiveButton(android.R.string.ok, null);
showAlertDialog(builder);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_username_password:
{
showUserSetting(false);
}
break;
case R.id.action_show_markings: showMarkingData();break;
case R.id.menu_tvbrowser_action_favorite_add: UiUtils.editFavorite(null, TvBrowser.this, null);break;
case R.id.menu_tvbrowser_action_favorite_edit: editFavorite();break;
case R.id.menu_tvbrowser_action_favorite_delete: deleteFavorite();break;
case R.id.action_donation: showDonationInfo(); break;
case R.id.action_search_plugins:
if(isOnline()) {
searchPlugins(false);
}
else {
showNoInternetConnection(getString(R.string.no_network_info_data_search_plugins),new Runnable() {
@Override
public void run() {
searchPlugins(false);
}
});
}
break;
case R.id.action_pause_reminder: pauseReminder(); break;
case R.id.action_continue_reminder: {
SettingConstants.setReminderPaused(TvBrowser.this, false);
actionBar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#212021")));
mPauseReminder.setVisible(true);
mContinueReminder.setVisible(false);
UiUtils.updateToggleReminderStateWidget(getApplicationContext());
}break;
case R.id.action_synchronize_reminders_down:
if(isOnline()) {
startSynchronizeRemindersDown();
}
else {
showNoInternetConnection(getString(R.string.no_network_info_data_sync_reminder), null);
}
break;
case R.id.action_synchronize_reminders_up:
if(isOnline()) {
startSynchronizeUp(true, null, SettingConstants.URL_SYNC_BASE + "data/scripts/syncUp.php?type=reminderFromApp", SettingConstants.SYNCHRONIZE_UP_DONE, null);
}
else {
showNoInternetConnection(getString(R.string.no_network_info_data_sync_reminder),null);
}
break;
case R.id.action_dont_want_to_see_edit:
editDontWantToSee();
break;
case R.id.action_synchronize_dont_want_to_see:
if(isOnline()) {
synchronizeDontWantToSee();
}
else {
showNoInternetConnection(getString(R.string.no_network_info_data_sync_dont_want_to_see), null);
}
break;
case R.id.action_synchronize_channels:
if(isOnline()) {
if(!hasChannels()) {
askChannelDownload(R.string.channel_notification_title);
}
else {
syncronizeChannels();
}
}
else {
showNoInternetConnection(getString(R.string.no_network_info_data_sync_channels),null);
}
break;
case R.id.action_synchronize_channels_up:
if(isOnline()) {
uploadChannels();
}
else {
showNoInternetConnection(getString(R.string.no_network_info_data_sync_channels),null);
}
break;
case R.id.action_delete_data_update_log: deleteLog("data-update-log.txt");break;
case R.id.action_delete_reminder_log: deleteLog("reminder-log.txt");break;
case R.id.action_delete_plugin_log: deleteLog("plugin-log.txt");break;
case R.id.action_send_data_update_log:sendLogMail("data-update-log.txt",getString(R.string.log_send_data_update));break;
case R.id.action_send_reminder_log:sendLogMail("reminder-log.txt",getString(R.string.log_send_reminder));break;
case R.id.action_send_plugin_log:sendLogMail("plugin-log.txt",getString(R.string.log_send_plugin));break;
case R.id.menu_tvbrowser_action_settings_basic:
Intent startPref = new Intent(this, TvbPreferencesActivity.class);
startActivityForResult(startPref, SHOW_PREFERENCES);
break;
case R.id.menu_tvbrowser_action_settings_plugins:
Intent startPluginPref = new Intent(this, PluginPreferencesActivity.class);
startActivityForResult(startPluginPref, SHOW_PLUGIN_PREFERENCES);
break;
case R.id.menu_tvbrowser_action_update_data:
if(isOnline()) {
checkTermsAccepted();
}
else {
showNoInternetConnection(getString(R.string.no_network_info_data_update), null);
}
break;
case R.id.action_privacy: showPrivacyStatement();break;
case R.id.action_about: showAbout();break;
case R.id.action_load_channels_again: selectChannels(true);break;
case R.id.action_select_channels: selectChannels(false);break;
case R.id.action_sort_channels: sortChannels(false);break;
case R.id.action_delete_all_data: getContentResolver().delete(TvBrowserContentProvider.CONTENT_URI_DATA, TvBrowserContentProvider.KEY_ID + " > 0", null);
getContentResolver().delete(TvBrowserContentProvider.CONTENT_URI_DATA_VERSION, TvBrowserContentProvider.KEY_ID + " > 0", null);
PrefUtils.resetDataMetaData(getApplicationContext());
break;
case R.id.action_scroll_now:scrollToTime(0);break;
case R.id.action_scroll_next:scrollToTime(Integer.MAX_VALUE);break;
case R.id.action_scroll_time_free:scrollToTimePick();break;
case R.id.action_activity_filter_list_edit_open:openFilterEdit();break;
// case R.id.action_filter_channels:filterChannels();break;
case R.id.action_reset: {
Editor edit = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit();
edit.putLong(getString(R.string.LAST_DATA_UPDATE), 0);
edit.commit();
break;
}
case R.id.action_backup_preferences_save: backupPreferences();break;
case R.id.action_backup_preferences_restore: restorePreferences();break;
}
for(int i = 0; i < SCROLL_IDS.length; i++) {
if(item.getItemId() == SCROLL_IDS[i]) {
scrollToTime(SCROLL_TIMES[i]+1);
break;
}
}
return super.onOptionsItemSelected(item);
}
private void scrollToTimePick() {
final int lastExtraTime = PrefUtils.getIntValue(R.string.PREF_MISC_LAST_TIME_PICK_VALUE, PrefUtils.getIntValueWithDefaultKey(R.string.PREF_MISC_LAST_TIME_EXTRA_VALUE, R.integer.pref_misc_last_time_extra_value_default));
final TimePickerDialog pick = new TimePickerDialog(TvBrowser.this, TimePickerDialog.THEME_HOLO_DARK, new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
scrollToTime(hourOfDay*60+minute+1);
PrefUtils.getSharedPreferences(PrefUtils.TYPE_PREFERENCES_SHARED_GLOBAL, TvBrowser.this).edit().putInt(getString(R.string.PREF_MISC_LAST_TIME_PICK_VALUE), hourOfDay*60+minute).commit();
}
}, lastExtraTime/60, lastExtraTime%60, DateFormat.is24HourFormat(TvBrowser.this));
pick.show();
}
/*
* a value of 0 stands for now, Integer.MAX_VALUE for next and every number
* from 1 to 1440 for a time in minutes plus one
*/
private void scrollToTime(int time) {
Log.d("info8", "scrollToTime " + time);
if(mViewPager.getCurrentItem() == 0) {
Fragment test = mSectionsPagerAdapter.getRegisteredFragment(0);
if(test instanceof FragmentProgramsListRunning && time >= 0) {
((FragmentProgramsListRunning)test).selectTime(time);
}
}
else if(mViewPager.getCurrentItem() == 1) {
Fragment test = mSectionsPagerAdapter.getRegisteredFragment(1);
if(test instanceof FragmentProgramsList && time >= 0) {
((FragmentProgramsList)test).setScrollTime(time);
((FragmentProgramsList)test).scrollToTime();
}
}
else if(mViewPager.getCurrentItem() == 3) {
Fragment test = mSectionsPagerAdapter.getRegisteredFragment(3);
if(test instanceof FragmentProgramTable) {
((FragmentProgramTable)test).scrollToTime(time, mScrollTimeItem);
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.tv_browser, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView =
(SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
mUpdateItem = menu.findItem(R.id.menu_tvbrowser_action_update_data);
if(!PrefUtils.getStringValue(R.string.PREF_AUTO_UPDATE_TYPE, R.string.pref_auto_update_type_default).equals("0")) {
mUpdateItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
}
mFilterItem = menu.findItem(R.id.action_filter_channels);
mCreateFavorite = menu.findItem(R.id.menu_tvbrowser_action_create_favorite);
Fragment fragment = mSectionsPagerAdapter.getItem(mViewPager.getCurrentItem());
mFilterItem.setVisible(!(fragment instanceof FragmentFavorites));
mCreateFavorite.setVisible(fragment instanceof FragmentFavorites);
mScrollTimeItem = menu.findItem(R.id.action_scroll);
updateFromFilterEdit();
mPluginPreferencesMenuItem = menu.findItem(R.id.menu_tvbrowser_action_settings_plugins);
handler.postDelayed(new Runnable() {
@Override
public void run() {
mPluginPreferencesMenuItem.setEnabled(PluginHandler.pluginsAvailable());
}
},3000);
menu.findItem(R.id.action_reset).setVisible(TEST_VERSION);
menu.findItem(R.id.action_show_markings).setVisible(TEST_VERSION);
mSearchExpanded = false;
// if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
addOnActionExpandListener(menu.findItem(R.id.search));
// }
// menu.findItem(R.id.action_synchronize_dont_want_to_see).setVisible(false);
menu.findItem(R.id.action_synchronize_favorites).setVisible(false);
if(mUpdateItem != null && TvDataUpdateService.isRunning()) {
updateProgressIcon(true);
}
mDebugMenuItem = menu.findItem(R.id.action_debug);
mSendDataUpdateLogItem = menu.findItem(R.id.action_send_data_update_log);
mDeleteDataUpdateLogItem = menu.findItem(R.id.action_delete_data_update_log);
mSendReminderLogItem = menu.findItem(R.id.action_send_reminder_log);
mDeleteReminderLogItem = menu.findItem(R.id.action_delete_reminder_log);
mSendPluginLogItem = menu.findItem(R.id.action_send_plugin_log);
mDeletePluginLogItem = menu.findItem(R.id.action_delete_plugin_log);
mPauseReminder = menu.findItem(R.id.action_pause_reminder);
mContinueReminder = menu.findItem(R.id.action_continue_reminder);
mPauseReminder.setVisible(!SettingConstants.isReminderPaused(TvBrowser.this));
mContinueReminder.setVisible(SettingConstants.isReminderPaused(TvBrowser.this));
mScrollTimeItem.setVisible(mViewPager.getCurrentItem() != 2 && !mSearchExpanded);
boolean dataUpdateLogEnabled = PrefUtils.getBooleanValue(R.string.WRITE_DATA_UPDATE_LOG, R.bool.write_data_update_log_default);
boolean reminderLogEnabled = PrefUtils.getBooleanValue(R.string.WRITE_REMINDER_LOG, R.bool.write_reminder_log_default);
boolean pluginLogEnabled = PrefUtils.getBooleanValue(R.string.LOG_WRITE_PLUGIN_LOG, R.bool.log_write_plugin_log_default);
mDebugMenuItem.setVisible(dataUpdateLogEnabled || reminderLogEnabled || pluginLogEnabled);
mSendDataUpdateLogItem.setEnabled(dataUpdateLogEnabled);
mDeleteDataUpdateLogItem.setEnabled(dataUpdateLogEnabled);
mSendReminderLogItem.setEnabled(reminderLogEnabled);
mDeleteReminderLogItem.setEnabled(reminderLogEnabled);
mSendPluginLogItem.setEnabled(pluginLogEnabled);
mDeletePluginLogItem.setEnabled(pluginLogEnabled);
updateScrollMenu();
mOptionsMenu = menu;
updateSynchroMenu();
return true;
}
@SuppressLint("NewApi")
private void addOnActionExpandListener(MenuItem search) {
if(search != null) {
MenuItemCompat.setOnActionExpandListener(search, new MenuItemCompat.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
mSearchExpanded = true;
if(PrefUtils.getStringValue(R.string.PREF_AUTO_UPDATE_TYPE, R.string.pref_auto_update_type_default).equals("0")) {
mUpdateItem.setVisible(false);
}
mScrollTimeItem.setVisible(false);
mCreateFavorite.setVisible(false);
mFilterItem.setVisible(false);
return true;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
mSearchExpanded = false;
Fragment fragment = mSectionsPagerAdapter.getItem(mViewPager.getCurrentItem());
if(PrefUtils.getStringValue(R.string.PREF_AUTO_UPDATE_TYPE, R.string.pref_auto_update_type_default).equals("0")) {
mUpdateItem.setVisible(true);
}
if(!(fragment instanceof FragmentFavorites)) {
mScrollTimeItem.setVisible(true);
}
if((fragment instanceof FragmentFavorites)) {
mCreateFavorite.setVisible(true);
}
if(!(fragment instanceof FragmentFavorites)) {
mFilterItem.setVisible(true);
}
return true;
}
});
}
}
private void updateSynchroMenu() {
SharedPreferences pref = getSharedPreferences("transportation", Context.MODE_PRIVATE);
String car = pref.getString(SettingConstants.USER_NAME, null);
String bicycle = pref.getString(SettingConstants.USER_PASSWORD, null);
boolean isAccount = (car != null && car.trim().length() > 0 && bicycle != null && bicycle.trim().length() > 0);
if(mOptionsMenu != null) {
mOptionsMenu.findItem(R.id.action_synchronize_channels).setEnabled(isAccount);
mOptionsMenu.findItem(R.id.action_synchronize_channels_up).setEnabled(isAccount);
mOptionsMenu.findItem(R.id.action_synchronize_dont_want_to_see).setEnabled(isAccount);
mOptionsMenu.findItem(R.id.action_synchronize_favorites).setEnabled(isAccount);
mOptionsMenu.findItem(R.id.action_synchronize_reminders_up).setEnabled(isAccount);
mOptionsMenu.findItem(R.id.action_synchronize_reminders_down).setEnabled(isAccount);
mOptionsMenu.findItem(R.id.action_backup_preferences_save).setEnabled(isAccount);
mOptionsMenu.findItem(R.id.action_backup_preferences_restore).setEnabled(isAccount);
}
}
private void updateScrollMenu() {
if(mScrollTimeItem != null) {
SubMenu subMenu = mScrollTimeItem.getSubMenu();
Log.d("info4", ""+subMenu.size());
for (int SCROLL_ID : SCROLL_IDS) {
subMenu.removeItem(SCROLL_ID);
}
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(TvBrowser.this);
ArrayList<Integer> values = new ArrayList<Integer>();
int[] defaultValues = getResources().getIntArray(R.array.time_button_defaults);
int timeButtonCount = pref.getInt(getString(R.string.TIME_BUTTON_COUNT),getResources().getInteger(R.integer.time_button_count_default));
for(int i = 1; i <= Math.min(timeButtonCount, getResources().getInteger(R.integer.time_button_count_default)); i++) {
try {
Class<?> string = R.string.class;
Field setting = string.getDeclaredField("TIME_BUTTON_" + i);
Integer value = pref.getInt(getResources().getString((Integer) setting.get(string)), defaultValues[i - 1]);
if(value >= -1 && !values.contains(value)) {
values.add(value);
}
} catch (Exception e) {}
}
for(int i = 7; i <= timeButtonCount; i++) {
Integer value = pref.getInt("TIME_BUTTON_" + i, 0);
if(value >= -1 && !values.contains(value)) {
values.add(value);
}
}
if(PrefUtils.getBooleanValue(R.string.SORT_RUNNING_TIMES, R.bool.sort_running_times_default)) {
Collections.sort(values);
}
SCROLL_TIMES = new int[values.size()];
SCROLL_IDS = new int[values.size()];
for(int i = 0; i < values.size(); i++) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, values.get(i) / 60);
cal.set(Calendar.MINUTE, values.get(i) % 60);
SCROLL_TIMES[i] = values.get(i);
SCROLL_IDS[i] = -(i+1);
subMenu.add(100, SCROLL_IDS[i], i+1, DateFormat.getTimeFormat(TvBrowser.this).format(cal.getTime()));
}
}
}
@Override
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
if(mScrollTimeItem != null) {
switch(tab.getPosition()) {
case 2:mScrollTimeItem.setVisible(false);break;
default:mScrollTimeItem.setVisible(true && !mSearchExpanded);break;
}
}
}
@Override
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
@Override
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to one
* of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
SparseArrayCompat<Fragment> registeredFragments = new SparseArrayCompat<Fragment>();
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public synchronized Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a DummySectionFragment (defined as a static inner class
// below) with the page number as its lone argument.
Fragment fragment = registeredFragments.get(position);
if(fragment == null) {
if(position == 0) {
if(IOUtils.isDatabaseAccessible(getApplicationContext())) {
fragment = new FragmentProgramsListRunning();
}
else {
fragment = new Fragment();
}
}
else if(position == 1) {
fragment = new FragmentProgramsList(mProgramListChannelId, mProgramListScrollTime, mProgramListScrollEndTime);
mProgramListChannelId = FragmentProgramsList.NO_CHANNEL_SELECTION_ID;
mProgramListScrollTime = -1;
mProgramListScrollEndTime = -1;
}
else if(position == 2) {
fragment = new FragmentFavorites();
}
else if(position == 3) {
fragment = new FragmentProgramTable();
}
}
return fragment;
}
@Override
public int getCount() {
if(!IOUtils.isDatabaseAccessible(getApplicationContext())) {
return 1;
}
// Show 3 total pages.
if(PrefUtils.getBooleanValue(R.string.PROG_TABLE_ACTIVATED, R.bool.prog_table_activated_default)) {
return 4;
}
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return !IOUtils.isDatabaseAccessible(getApplicationContext()) ? "DATABASE NOT AVAILABLE" : getString(R.string.title_running_programs).toUpperCase(l);
case 1:
return getString(R.string.title_programs_list).toUpperCase(l);
case 2:
return getString(R.string.title_favorites).toUpperCase(l);
case 3:
return getString(R.string.title_program_table).toUpperCase(l);
}
return null;
}
@Override
public synchronized Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}
public void updateProgressIcon(final boolean progress) {
handler.post(new Runnable() {
@Override
public void run() {
if(mUpdateItem != null) {
if(progress) {
mUpdateItem.setActionView(R.layout.progressbar);
mUpdateItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
}
else {
if(!PrefUtils.getStringValue(R.string.PREF_AUTO_UPDATE_TYPE, R.string.pref_auto_update_type_default).equals("0")) {
mUpdateItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
invalidateOptionsMenu();
}
mUpdateItem.setActionView(null);
}
}
}
});
}
public void showProgramsListTab(boolean remember) {
Log.d("info14", "showProgramsListTab " + System.currentTimeMillis());
if(mViewPager.getCurrentItem() != 1) {
mLastSelectedTab = mViewPager.getCurrentItem();
mViewPager.setCurrentItem(1,true);
if(remember) {
mProgramsListWasShow = true;
}
else {
mProgramsListWasShow = false;
}
}
}
private void setRatingAndDonationInfoShown() {
PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit().putBoolean(getString(R.string.PREF_RATING_DONATION_INFO_SHOWN), true).commit();
}
private void showInAppDonations(final Inventory inv, boolean showIfAlreadyDonated) {
updateProgressIcon(false);
AlertDialog.Builder alert = new AlertDialog.Builder(TvBrowser.this);
alert.setTitle(R.string.donation);
View view = getLayoutInflater().inflate(R.layout.in_app_donations, getParentViewGroup(), false);
LinearLayout layout = (LinearLayout)view.findViewById(R.id.donation_in_app_layout);
alert.setView(view);
alert.setNegativeButton(getString(R.string.not_now).replace("{0}", ""), null);
if(Locale.getDefault().getCountry().equals("DE")) {
alert.setPositiveButton(R.string.donation_info_website, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(SettingConstants.URL_SYNC_BASE + "index.php?id=donations")));
}
});
}
final AlertDialog d = alert.create();
View.OnClickListener onDonationClick = new View.OnClickListener() {
@Override
public void onClick(View v) {
d.dismiss();
openDonation((SkuDetails)v.getTag());
}
};
Purchase donated = null;
SkuDetails donatedDetails = null;
for(String sku : SettingConstants.SKU_LIST) {
SkuDetails details = inv.getSkuDetails(sku);
Purchase donatedTest = inv.getPurchase(sku);
if(donatedTest != null && details != null) {
donated = donatedTest;
donatedDetails = details;
}
if(details != null) {
if(!details.getSku().equals(SettingConstants.SKU_EPG_DONATE_ONCE) || hasEpgDonateChannelsSubscribed()) {
String title = details.getTitle().substring(0,details.getTitle().indexOf("(")-1);
Button donation = new Button(this);
donation.setTextSize(TypedValue.COMPLEX_UNIT_SP,18);
donation.setText(title + ": " + details.getPrice());
donation.setTag(details);
donation.setOnClickListener(onDonationClick);
layout.addView(donation);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)donation.getLayoutParams();
params.setMargins(5, 0, 5, 5); //left, top, right, bottom
donation.setLayoutParams(params);
}
}
}
if(donated == null || showIfAlreadyDonated) {
showAlertDialog(d);
}
else if(donated != null) {
AlertDialog.Builder alert2 = new AlertDialog.Builder(TvBrowser.this);
alert2.setTitle(R.string.donation);
String message = getString(R.string.already_donated).replace("{1}", DateFormat.getLongDateFormat(this).format(new Date(donated.getPurchaseTime()))).replace("{0}", donatedDetails.getPrice());
alert2.setMessage(message);
final Purchase toConsume = donated;
alert2.setPositiveButton(R.string.donate_again, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
updateProgressIcon(true);
mHelper.consumeAsync(toConsume,new IabHelper.OnConsumeFinishedListener() {
@Override
public void onConsumeFinished(Purchase purchase, IabResult result) {
updateProgressIcon(false);
if(result.isSuccess()) {
showAlertDialog(d);
}
else {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(TvBrowser.this, "", Toast.LENGTH_LONG).show();
}
});
}
}
});
}
});
alert2.setNegativeButton(R.string.stop_donation, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {}
});
showAlertDialog(alert2);
}
}
@Override
public void onDestroy() {
PluginHandler.shutdownPlugins(getApplicationContext());
if (mHelper != null) {
mHelper.dispose();
}
mHelper = null;
super.onDestroy();
}
private void showInAppError(String error) {
updateProgressIcon(false);
AlertDialog.Builder alert = new AlertDialog.Builder(TvBrowser.this);
alert.setTitle(R.string.donation);
boolean showOthers = true;
if(!Locale.getDefault().getCountry().equals("DE")) {
showOthers = false;
}
String message = getString(R.string.in_app_error_1);
if(showOthers) {
message += " " + getString(R.string.in_app_error_2);
}
else {
message += ".";
}
alert.setMessage(message);
alert.setNegativeButton(android.R.string.ok, null);
if(showOthers) {
alert.setPositiveButton(R.string.donation_open_website, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(SettingConstants.URL_SYNC_BASE + "index.php?id=donations")));
}
});
}
showAlertDialog(alert);
}
private void listPurchaseItems() {
try {
mHelper.queryInventoryAsync(true, SettingConstants.SKU_LIST, new QueryInventoryFinishedListener() {
@Override
public void onQueryInventoryFinished(IabResult result, final Inventory inv) {
if(result.isFailure()) {
showInAppError("InApp Billing listing failed");
}
else {
handler.post(new Runnable() {
@Override
public void run() {
showInAppDonations(inv,false);
}
});
}
}
});
}catch(IllegalStateException e) {
showInAppError("InApp Billing listing failed");
}
}
private void prepareInAppPayment() {
updateProgressIcon(true);
if(mHelper == null) {
String a2b = "2XQh0oOHnnZ2p3Ja8Xj6SlLFmI1Z/QIDAQAB";
String a2a = "8AMIIBCgKCAQEAqfmi767AEH+MBv+";
String ag2 = "Zh6iBFrN3zYpj1ikPu9jdtp+H47F8JvCzKt55xgIrzBpID58VfO";
String u6c = "+K1ZDlHw1rO+qN7GW177mzEO0yk+bVs0hwE/5QF2RamM+hOcCeyB7";
String ab2 = "6r2nGP94ai9Rgip1NLwZ1VYzFOPFC2/";
String hm5 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ";
String ot8 = "tWvkedDMJd+4l912GuKiUa6FNw/sZLa9UIWB2ojgr2";
String bt4 = "TPd7Q6T9xOhHS01Ydws58YaK1NSCuIrFLG1I";
String ddx = "x3bLB5fJKPrWJc33MMqybm6KWIc+HVt2+HT";
String iz4 = "dePazzkaD5s84IG9FDe/cO3tvL/EZmSUiphDGXWl+beL2TW7D";
String hrq = hm5 + a2a + ab2 + bt4 + ddx + iz4 + u6c + ag2 + ot8 + a2b;
mHelper = new IabHelper(TvBrowser.this, hrq);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
@Override
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
showInAppError("InApp Billing Setup failed");
}
else {
handler.post(new Runnable() {
@Override
public void run() {
listPurchaseItems();
}
});
}
}
});
}
else {
listPurchaseItems();
}
}
private void openDonation(final SkuDetails skuDetails) {
if(skuDetails != null && mHelper != null) {
AlertDialog.Builder alert = new AlertDialog.Builder(TvBrowser.this);
alert.setTitle(R.string.donation);
View view = getLayoutInflater().inflate(R.layout.open_donation, getParentViewGroup(), false);
alert.setView(view);
((TextView)view.findViewById(R.id.donation_open_info)).setText(getString(R.string.make_donation_info).replace("{0}", skuDetails.getPrice()));
alert.setNegativeButton(R.string.stop_donation, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {}
});
alert.setPositiveButton(R.string.make_donation, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
handler.post(new Runnable() {
@Override
public void run() {
mHelper.launchPurchaseFlow(TvBrowser.this, skuDetails.getSku(), 500012, new IabHelper.OnIabPurchaseFinishedListener() {
@Override
public void onIabPurchaseFinished(IabResult result, Purchase info) {
if(result.isSuccess()) {
AlertDialog.Builder alert2 = new AlertDialog.Builder(TvBrowser.this);
alert2.setTitle(R.string.donation);
alert2.setMessage(R.string.thanks_for_donation);
alert2.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {}
});
showAlertDialog(alert2);
}
}
}, Long.toHexString(Double.doubleToLongBits(Math.random())));
}
});
}
});
showAlertDialog(alert);
}
}
private void showDonationInfo() {
AlertDialog.Builder alert = new AlertDialog.Builder(TvBrowser.this);
alert.setTitle(R.string.donation);
View view = getLayoutInflater().inflate(R.layout.dialog_donations, getParentViewGroup(), false);
alert.setView(view);
Button inAppDonation = (Button)view.findViewById(R.id.donation_in_app_button);
TextView webInfo = (TextView)view.findViewById(R.id.donation_show_ways);
Button openWeb = (Button)view.findViewById(R.id.donation_website_button);
if(!Locale.getDefault().getCountry().equals("DE")) {
webInfo.setVisibility(View.GONE);
openWeb.setVisibility(View.GONE);
}
alert.setNegativeButton(getString(R.string.not_now).replace("{0}", ""), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
final AlertDialog d = alert.create();
inAppDonation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
d.dismiss();
prepareInAppPayment();
}
});
openWeb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
d.dismiss();
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(SettingConstants.URL_SYNC_BASE + "index.php?id=donations")));
}
});
showAlertDialog(d);
}
private void showRatingAndDonationInfo() {
AlertDialog.Builder alert = new AlertDialog.Builder(TvBrowser.this);
alert.setTitle(R.string.you_like_it);
View view = getLayoutInflater().inflate(R.layout.rating_and_donation, getParentViewGroup(), false);
TextView ratingInfo = (TextView)view.findViewById(R.id.rating_info);
Button rate = (Button)view.findViewById(R.id.rating_button);
Button donate = (Button)view.findViewById(R.id.donation_button);
if(!SettingConstants.GOOGLE_PLAY) {
ratingInfo.setVisibility(View.GONE);
rate.setVisibility(View.GONE);
}
ratingInfo.setText(Html.fromHtml(getString(R.string.rating_text)));
((TextView)view.findViewById(R.id.donation_info)).setText(Html.fromHtml(getString(R.string.donate_text)));
final Button cancel = (Button)view.findViewById(R.id.rating_donation_cancel);
cancel.setEnabled(false);
alert.setView(view);
alert.setCancelable(false);
final AlertDialog d = alert.create();
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setRatingAndDonationInfoShown();
d.dismiss();
finish();
}
});
donate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setRatingAndDonationInfoShown();
d.dismiss();
showDonationInfo();
}
});
rate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setRatingAndDonationInfoShown();
d.dismiss();
final String appPackageName = getPackageName(); // getPackageName() from Context or Activity object
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName)));
} catch (android.content.ActivityNotFoundException anfe) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=" + appPackageName)));
}
finish();
}
});
d.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
new Thread("Cancel wait thread") {
@Override
public void run() {
setRatingAndDonationInfoShown();
int count = 10;
while(--count >= 0) {
final int countValue = count+1;
handler.post(new Runnable() {
@Override
public void run() {
cancel.setText(getString(R.string.not_now).replace("{0}", " (" + countValue + ")"));
}
});
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
handler.post(new Runnable() {
@Override
public void run() {
cancel.setText(getString(R.string.not_now).replace("{0}", ""));
cancel.setEnabled(true);
}
});
}
}.start();
}
});
showAlertDialog(d,true);
}
@Override
public void onBackPressed() {
if(mProgramsListWasShow) {
mProgramsListWasShow = false;
mViewPager.setCurrentItem(mLastSelectedTab,true);
}
else if(!mProgamListStateStack.isEmpty()) {
mProgramsListWasShow = false;
ProgramsListState state = mProgamListStateStack.pop();
Intent showChannel = new Intent(SettingConstants.SHOW_ALL_PROGRAMS_FOR_CHANNEL_INTENT);
showChannel.putExtra(SettingConstants.CHANNEL_ID_EXTRA, state.mChannelID);
showChannel.putExtra(SettingConstants.SCROLL_POSITION_EXTRA, state.mScrollPos);
showChannel.putExtra(SettingConstants.DAY_POSITION_EXTRA, state.mDayPos);
showChannel.putExtra(SettingConstants.FILTER_POSITION_EXTRA, state.mFilterPos);
LocalBroadcastManager.getInstance(TvBrowser.this).sendBroadcastSync(showChannel);
}
else {
final SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
final boolean infoShown = pref.getBoolean(getString(R.string.PREF_RATING_DONATION_INFO_SHOWN), getResources().getBoolean(R.bool.pref_rating_donation_info_shown_default));
final boolean timeToShow = (pref.getLong(getString(R.string.PREF_RUNNING_TIME), getResources().getInteger(R.integer.pref_running_time_default)) > 2 * 60 * 60000);
if(isTaskRoot() && !infoShown && timeToShow) {
showRatingAndDonationInfo();
}
else {
super.onBackPressed();
}
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
SettingConstants.ORIENTATION = newConfig.orientation;
}
public void addProgramListState(int dayPos, int channelID, int filterPos, int scrollPos) {
mProgramsListWasShow = false;
mProgamListStateStack.push(new ProgramsListState(dayPos, channelID, filterPos, scrollPos));
}
private static final class ProgramsListState {
public int mDayPos;
public int mChannelID;
public int mFilterPos;
public int mScrollPos;
public ProgramsListState(int dayPos, int channelID, int filterPos, int scrollPos) {
mDayPos = dayPos;
mChannelID = channelID;
mFilterPos = filterPos;
mScrollPos = scrollPos;
}
}
public String getFilterSelection(boolean onlyChannelFilter) {
return PrefUtils.getFilterSelection(getApplicationContext(), onlyChannelFilter, mCurrentFilter);
}
public String getCategoryFilterSelection() {
final StringBuilder result = new StringBuilder();
for(FilterValues values : mCurrentFilter) {
if(values instanceof FilterValuesCategories || values instanceof FilterValuesKeyword) {
result.append(values.getWhereClause(getApplicationContext()).getWhere());
}
}
return result.toString();
}
/*
* Workaround for NPE on LG devices from:
* http://stackoverflow.com/questions/26833242/nullpointerexception-phonewindowonkeyuppanel1002-main
*
* Use workaround for all devices.
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU/* && "LGE".equalsIgnoreCase(Build.BRAND)*/) {
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU/* && "LGE".equalsIgnoreCase(Build.BRAND)*/) {
openOptionsMenu();
return true;
}
return super.onKeyUp(keyCode, event);
}
public ViewGroup getParentViewGroup() {
View test = getCurrentFocus();
if(test instanceof ViewGroup) {
return (ViewGroup)test;
}
return null;
}
/* Workaround end */
/*@Override
public boolean onMenuOpened(int featureId, Menu menu)
{
if(featureId == Window.FEATURE_ACTION_BAR && menu != null){
if(menu.getClass().getSimpleName().equals("MenuBuilder")){
try{
Method m = menu.getClass().getDeclaredMethod(
"setOptionalIconsVisible", Boolean.TYPE);
m.setAccessible(true);
m.invoke(menu, true);
}
catch(NoSuchMethodException e){
// Log.e(TAG, "onMenuOpened", e);
}
catch(Exception e){
throw new RuntimeException(e);
}
}
}
return super.onMenuOpened(featureId, menu);
}*/
public void showSQLquery(String selection, String[] selectionArgs) {
if(TEST_VERSION) {
StringBuilder message = new StringBuilder();
if(selection != null) {
message.append("SELECTION:\n").append(selection).append("\n\n");
}
if(selectionArgs != null) {
message.append("ARGUMENTS:\n");
for(String arg : selectionArgs) {
message.append(arg).append(", ");
}
}
if(message.length() > 0) {
AlertDialog.Builder builder = new AlertDialog.Builder(TvBrowser.this);
builder.setTitle("SQL QUERY SELECTION INFO");
builder.setMessage(message.toString());
builder.setPositiveButton(android.R.string.ok, null);
showAlertDialog(builder);
}
}
}
}