From bcdcfe0d587445500de8681be6854708971bebf7 Mon Sep 17 00:00:00 2001 From: Domingos Lopes Date: Sat, 4 Jun 2016 14:20:28 -0400 Subject: adapt ui to different flavors --- .../danoeh/antennapod/activity/MainActivity.java | 773 ----------------- .../antennapod/activity/MediaplayerActivity.java | 876 ------------------- .../danoeh/antennapod/fragment/ItemFragment.java | 593 ------------- .../preferences/PreferenceController.java | 953 --------------------- .../preferences/PreferenceControllerHelper.java | 31 + 5 files changed, 31 insertions(+), 3195 deletions(-) delete mode 100644 app/src/play/java/de/danoeh/antennapod/activity/MainActivity.java delete mode 100644 app/src/play/java/de/danoeh/antennapod/activity/MediaplayerActivity.java delete mode 100644 app/src/play/java/de/danoeh/antennapod/fragment/ItemFragment.java delete mode 100644 app/src/play/java/de/danoeh/antennapod/preferences/PreferenceController.java create mode 100644 app/src/play/java/de/danoeh/antennapod/preferences/PreferenceControllerHelper.java (limited to 'app/src/play') diff --git a/app/src/play/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/play/java/de/danoeh/antennapod/activity/MainActivity.java deleted file mode 100644 index 17965ca8e..000000000 --- a/app/src/play/java/de/danoeh/antennapod/activity/MainActivity.java +++ /dev/null @@ -1,773 +0,0 @@ -package de.danoeh.antennapod.activity; - -import android.annotation.TargetApi; -import android.app.ProgressDialog; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.Configuration; -import android.database.DataSetObserver; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentManager; -import android.support.v4.app.FragmentTransaction; -import android.support.v4.widget.DrawerLayout; -import android.support.v7.app.ActionBarDrawerToggle; -import android.support.v7.app.AlertDialog; -import android.support.v7.widget.Toolbar; -import android.util.Log; -import android.util.TypedValue; -import android.view.ContextMenu; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.widget.AdapterView; -import android.widget.ListView; - -import com.bumptech.glide.Glide; - -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.Validate; - -import java.util.List; - -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.adapter.NavListAdapter; -import de.danoeh.antennapod.core.asynctask.FeedRemover; -import de.danoeh.antennapod.core.dialog.ConfirmationDialog; -import de.danoeh.antennapod.core.event.ProgressEvent; -import de.danoeh.antennapod.core.event.QueueEvent; -import de.danoeh.antennapod.core.feed.EventDistributor; -import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.preferences.PlaybackPreferences; -import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.service.playback.PlaybackService; -import de.danoeh.antennapod.core.storage.DBReader; -import de.danoeh.antennapod.core.storage.DBWriter; -import de.danoeh.antennapod.core.util.FeedItemUtil; -import de.danoeh.antennapod.core.util.StorageUtils; -import de.danoeh.antennapod.dialog.RatingDialog; -import de.danoeh.antennapod.fragment.AddFeedFragment; -import de.danoeh.antennapod.fragment.DownloadsFragment; -import de.danoeh.antennapod.fragment.EpisodesFragment; -import de.danoeh.antennapod.fragment.ExternalPlayerFragment; -import de.danoeh.antennapod.fragment.ItemlistFragment; -import de.danoeh.antennapod.fragment.PlaybackHistoryFragment; -import de.danoeh.antennapod.fragment.QueueFragment; -import de.danoeh.antennapod.fragment.SubscriptionFragment; -import de.danoeh.antennapod.menuhandler.NavDrawerActivity; -import de.danoeh.antennapod.preferences.PreferenceController; -import de.greenrobot.event.EventBus; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; - -/** - * The activity that is shown when the user launches the app. - */ -public class MainActivity extends CastEnabledActivity implements NavDrawerActivity { - - private static final String TAG = "MainActivity"; - - private static final int EVENTS = EventDistributor.FEED_LIST_UPDATE - | EventDistributor.UNREAD_ITEMS_UPDATE; - - public static final String PREF_NAME = "MainActivityPrefs"; - public static final String PREF_IS_FIRST_LAUNCH = "prefMainActivityIsFirstLaunch"; - public static final String PREF_LAST_FRAGMENT_TAG = "prefMainActivityLastFragmentTag"; - - public static final String EXTRA_NAV_TYPE = "nav_type"; - public static final String EXTRA_NAV_INDEX = "nav_index"; - public static final String EXTRA_FRAGMENT_TAG = "fragment_tag"; - public static final String EXTRA_FRAGMENT_ARGS = "fragment_args"; - public static final String EXTRA_FEED_ID = "fragment_feed_id"; - - public static final String SAVE_BACKSTACK_COUNT = "backstackCount"; - public static final String SAVE_TITLE = "title"; - - public static final String[] NAV_DRAWER_TAGS = { - QueueFragment.TAG, - EpisodesFragment.TAG, - SubscriptionFragment.TAG, - DownloadsFragment.TAG, - PlaybackHistoryFragment.TAG, - AddFeedFragment.TAG, - NavListAdapter.SUBSCRIPTION_LIST_TAG - }; - - private Toolbar toolbar; - private ExternalPlayerFragment externalPlayerFragment; - private DrawerLayout drawerLayout; - - private View navDrawer; - private ListView navList; - private NavListAdapter navAdapter; - private int mPosition = -1; - - private ActionBarDrawerToggle drawerToggle; - - private CharSequence currentTitle; - - private ProgressDialog pd; - - private Subscription subscription; - - @Override - public void onCreate(Bundle savedInstanceState) { - setTheme(UserPreferences.getNoTitleTheme()); - super.onCreate(savedInstanceState); - StorageUtils.checkStorageAvailability(this); - setContentView(R.layout.main); - - toolbar = (Toolbar) findViewById(R.id.toolbar); - setSupportActionBar(toolbar); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - findViewById(R.id.shadow).setVisibility(View.GONE); - int elevation = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, - getResources().getDisplayMetrics()); - getSupportActionBar().setElevation(elevation); - } - - currentTitle = getTitle(); - - drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); - navList = (ListView) findViewById(R.id.nav_list); - navDrawer = findViewById(R.id.nav_layout); - - drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.drawer_open, R.string.drawer_close); - if (savedInstanceState != null) { - int backstackCount = savedInstanceState.getInt(SAVE_BACKSTACK_COUNT, 0); - drawerToggle.setDrawerIndicatorEnabled(backstackCount == 0); - } - drawerLayout.setDrawerListener(drawerToggle); - - final FragmentManager fm = getSupportFragmentManager(); - - fm.addOnBackStackChangedListener(() -> { - drawerToggle.setDrawerIndicatorEnabled(fm.getBackStackEntryCount() == 0); - }); - - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - getSupportActionBar().setHomeButtonEnabled(true); - - navAdapter = new NavListAdapter(itemAccess, this); - navList.setAdapter(navAdapter); - navList.setOnItemClickListener(navListClickListener); - navList.setOnItemLongClickListener(newListLongClickListener); - registerForContextMenu(navList); - - navAdapter.registerDataSetObserver(new DataSetObserver() { - @Override - public void onChanged() { - selectedNavListIndex = getSelectedNavListIndex(); - } - }); - - findViewById(R.id.nav_settings).setOnClickListener(v -> { - drawerLayout.closeDrawer(navDrawer); - startActivity(new Intent(MainActivity.this, PreferenceController.getPreferenceActivity())); - }); - - FragmentTransaction transaction = fm.beginTransaction(); - - Fragment mainFragment = fm.findFragmentByTag("main"); - if (mainFragment != null) { - transaction.replace(R.id.main_view, mainFragment); - } else { - String lastFragment = getLastNavFragment(); - if (ArrayUtils.contains(NAV_DRAWER_TAGS, lastFragment)) { - loadFragment(lastFragment, null); - } else { - try { - loadFeedFragmentById(Integer.parseInt(lastFragment), null); - } catch (NumberFormatException e) { - // it's not a number, this happens if we removed - // a label from the NAV_DRAWER_TAGS - // give them a nice default... - loadFragment(QueueFragment.TAG, null); - } - } - } - externalPlayerFragment = new ExternalPlayerFragment(); - transaction.replace(R.id.playerFragment, externalPlayerFragment, ExternalPlayerFragment.TAG); - transaction.commit(); - - checkFirstLaunch(); - } - - private void saveLastNavFragment(String tag) { - Log.d(TAG, "saveLastNavFragment(tag: " + tag +")"); - SharedPreferences prefs = getSharedPreferences(PREF_NAME, MODE_PRIVATE); - SharedPreferences.Editor edit = prefs.edit(); - if(tag != null) { - edit.putString(PREF_LAST_FRAGMENT_TAG, tag); - } else { - edit.remove(PREF_LAST_FRAGMENT_TAG); - } - edit.apply(); - } - - private String getLastNavFragment() { - SharedPreferences prefs = getSharedPreferences(PREF_NAME, MODE_PRIVATE); - String lastFragment = prefs.getString(PREF_LAST_FRAGMENT_TAG, QueueFragment.TAG); - Log.d(TAG, "getLastNavFragment() -> " + lastFragment); - return lastFragment; - } - - private void checkFirstLaunch() { - SharedPreferences prefs = getSharedPreferences(PREF_NAME, MODE_PRIVATE); - if (prefs.getBoolean(PREF_IS_FIRST_LAUNCH, true)) { - new Handler().postDelayed(() -> drawerLayout.openDrawer(navDrawer), 1500); - - // for backward compatibility, we only change defaults for fresh installs - UserPreferences.setUpdateInterval(12); - - SharedPreferences.Editor edit = prefs.edit(); - edit.putBoolean(PREF_IS_FIRST_LAUNCH, false); - edit.commit(); - } - } - - public void showDrawerPreferencesDialog() { - final List hiddenDrawerItems = UserPreferences.getHiddenDrawerItems(); - String[] navLabels = new String[NAV_DRAWER_TAGS.length]; - final boolean[] checked = new boolean[NAV_DRAWER_TAGS.length]; - for (int i = 0; i < NAV_DRAWER_TAGS.length; i++) { - String tag = NAV_DRAWER_TAGS[i]; - navLabels[i] = navAdapter.getLabel(tag); - if (!hiddenDrawerItems.contains(tag)) { - checked[i] = true; - } - } - - AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); - builder.setTitle(R.string.drawer_preferences); - builder.setMultiChoiceItems(navLabels, checked, (dialog, which, isChecked) -> { - if (isChecked) { - hiddenDrawerItems.remove(NAV_DRAWER_TAGS[which]); - } else { - hiddenDrawerItems.add(NAV_DRAWER_TAGS[which]); - } - }); - builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> { - UserPreferences.setHiddenDrawerItems(hiddenDrawerItems); - }); - builder.setNegativeButton(R.string.cancel_label, null); - builder.create().show(); - } - - public boolean isDrawerOpen() { - return drawerLayout != null && navDrawer != null && drawerLayout.isDrawerOpen(navDrawer); - } - - public List getFeeds() { - return (navDrawerData != null) ? navDrawerData.feeds : null; - } - - public void loadFragment(int index, Bundle args) { - Log.d(TAG, "loadFragment(index: " + index + ", args: " + args + ")"); - if (index < navAdapter.getSubscriptionOffset()) { - String tag = navAdapter.getTags().get(index); - loadFragment(tag, args); - } else { - int pos = index - navAdapter.getSubscriptionOffset(); - loadFeedFragmentByPosition(pos, args); - } - } - - public void loadFragment(String tag, Bundle args) { - Log.d(TAG, "loadFragment(tag: " + tag + ", args: " + args + ")"); - Fragment fragment = null; - switch (tag) { - case QueueFragment.TAG: - fragment = new QueueFragment(); - break; - case EpisodesFragment.TAG: - fragment = new EpisodesFragment(); - break; - case DownloadsFragment.TAG: - fragment = new DownloadsFragment(); - break; - case PlaybackHistoryFragment.TAG: - fragment = new PlaybackHistoryFragment(); - break; - case AddFeedFragment.TAG: - fragment = new AddFeedFragment(); - break; - case SubscriptionFragment.TAG: - SubscriptionFragment subscriptionFragment = new SubscriptionFragment(); - fragment = subscriptionFragment; - break; - default: - // default to the queue - tag = QueueFragment.TAG; - fragment = new QueueFragment(); - args = null; - break; - } - currentTitle = navAdapter.getLabel(tag); - getSupportActionBar().setTitle(currentTitle); - saveLastNavFragment(tag); - if (args != null) { - fragment.setArguments(args); - } - loadFragment(fragment); - } - - private void loadFeedFragmentByPosition(int relPos, Bundle args) { - if(relPos < 0) { - return; - } - Feed feed = itemAccess.getItem(relPos); - loadFeedFragmentById(feed.getId(), args); - } - - public void loadFeedFragmentById(long feedId, Bundle args) { - Fragment fragment = ItemlistFragment.newInstance(feedId); - if(args != null) { - fragment.setArguments(args); - } - saveLastNavFragment(String.valueOf(feedId)); - currentTitle = ""; - getSupportActionBar().setTitle(currentTitle); - loadFragment(fragment); - } - - private void loadFragment(Fragment fragment) { - FragmentManager fragmentManager = getSupportFragmentManager(); - // clear back stack - for (int i = 0; i < fragmentManager.getBackStackEntryCount(); i++) { - fragmentManager.popBackStack(); - } - FragmentTransaction t = fragmentManager.beginTransaction(); - t.replace(R.id.main_view, fragment, "main"); - fragmentManager.popBackStack(); - // TODO: we have to allow state loss here - // since this function can get called from an AsyncTask which - // could be finishing after our app has already committed state - // and is about to get shutdown. What we *should* do is - // not commit anything in an AsyncTask, but that's a bigger - // change than we want now. - t.commitAllowingStateLoss(); - if (navAdapter != null) { - navAdapter.notifyDataSetChanged(); - } - } - - public void loadChildFragment(Fragment fragment) { - Validate.notNull(fragment); - FragmentManager fm = getSupportFragmentManager(); - fm.beginTransaction() - .replace(R.id.main_view, fragment, "main") - .addToBackStack(null) - .commit(); - } - - public void dismissChildFragment() { - getSupportFragmentManager().popBackStack(); - } - - private int getSelectedNavListIndex() { - String currentFragment = getLastNavFragment(); - if(currentFragment == null) { - // should not happen, but better safe than sorry - return -1; - } - int tagIndex = navAdapter.getTags().indexOf(currentFragment); - if(tagIndex >= 0) { - return tagIndex; - } else if(ArrayUtils.contains(NAV_DRAWER_TAGS, currentFragment)) { - // the fragment was just hidden - return -1; - } else { // last fragment was not a list, but a feed - long feedId = Long.parseLong(currentFragment); - if (navDrawerData != null) { - List feeds = navDrawerData.feeds; - for (int i = 0; i < feeds.size(); i++) { - if (feeds.get(i).getId() == feedId) { - return i + navAdapter.getSubscriptionOffset(); - } - } - } - return -1; - } - } - - private AdapterView.OnItemClickListener navListClickListener = new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - int viewType = parent.getAdapter().getItemViewType(position); - if (viewType != NavListAdapter.VIEW_TYPE_SECTION_DIVIDER && position != selectedNavListIndex) { - loadFragment(position, null); - } - drawerLayout.closeDrawer(navDrawer); - } - }; - - private AdapterView.OnItemLongClickListener newListLongClickListener = new AdapterView.OnItemLongClickListener() { - @Override - public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { - if(position < navAdapter.getTags().size()) { - showDrawerPreferencesDialog(); - return true; - } else { - mPosition = position; - return false; - } - } - }; - - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - super.onPostCreate(savedInstanceState); - drawerToggle.syncState(); - if (savedInstanceState != null) { - currentTitle = savedInstanceState.getString(SAVE_TITLE); - if (!drawerLayout.isDrawerOpen(navDrawer)) { - getSupportActionBar().setTitle(currentTitle); - } - selectedNavListIndex = getSelectedNavListIndex(); - } - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - drawerToggle.onConfigurationChanged(newConfig); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putString(SAVE_TITLE, getSupportActionBar().getTitle().toString()); - outState.putInt(SAVE_BACKSTACK_COUNT, getSupportFragmentManager().getBackStackEntryCount()); - } - - @Override - public void onStart() { - super.onStart(); - EventDistributor.getInstance().register(contentUpdate); - EventBus.getDefault().register(this); - RatingDialog.init(this); - } - - @Override - protected void onPause() { - super.onPause(); - } - - @Override - protected void onResume() { - super.onResume(); - StorageUtils.checkStorageAvailability(this); - - Intent intent = getIntent(); - if (intent.hasExtra(EXTRA_FEED_ID) || - (navDrawerData != null && intent.hasExtra(EXTRA_NAV_TYPE) && - (intent.hasExtra(EXTRA_NAV_INDEX) || intent.hasExtra(EXTRA_FRAGMENT_TAG)))) { - handleNavIntent(); - } - loadData(); - RatingDialog.check(); - } - - @Override - protected void onStop() { - super.onStop(); - EventDistributor.getInstance().unregister(contentUpdate); - EventBus.getDefault().unregister(this); - if(subscription != null) { - subscription.unsubscribe(); - } - if(pd != null) { - pd.dismiss(); - } - } - - - @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) - @Override - public void onTrimMemory(int level) { - super.onTrimMemory(level); - Glide.get(this).trimMemory(level); - } - - @Override - public void onLowMemory() { - super.onLowMemory(); - Glide.get(this).clearMemory(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - boolean retVal = super.onCreateOptionsMenu(menu); - switch (getLastNavFragment()) { - case QueueFragment.TAG: - case EpisodesFragment.TAG: - requestCastButton(MenuItem.SHOW_AS_ACTION_IF_ROOM); - return retVal; - case DownloadsFragment.TAG: - case PlaybackHistoryFragment.TAG: - case AddFeedFragment.TAG: - case SubscriptionFragment.TAG: - return retVal; - default: - requestCastButton(MenuItem.SHOW_AS_ACTION_NEVER); - return retVal; - } - - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (drawerToggle.onOptionsItemSelected(item)) { - return true; - } else if (item.getItemId() == android.R.id.home) { - if (getSupportFragmentManager().getBackStackEntryCount() > 0) { - dismissChildFragment(); - } - return true; - } else { - return super.onOptionsItemSelected(item); - } - } - - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - if(v.getId() != R.id.nav_list) { - return; - } - AdapterView.AdapterContextMenuInfo adapterInfo = (AdapterView.AdapterContextMenuInfo) menuInfo; - int position = adapterInfo.position; - if(position < navAdapter.getSubscriptionOffset()) { - return; - } - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.nav_feed_context, menu); - Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset()); - menu.setHeaderTitle(feed.getTitle()); - // episodes are not loaded, so we cannot check if the podcast has new or unplayed ones! - } - - - @Override - public boolean onContextItemSelected(MenuItem item) { - final int position = mPosition; - mPosition = -1; // reset - if(position < 0) { - return false; - } - Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset()); - switch(item.getItemId()) { - case R.id.mark_all_seen_item: - DBWriter.markFeedSeen(feed.getId()); - return true; - case R.id.mark_all_read_item: - DBWriter.markFeedRead(feed.getId()); - return true; - case R.id.remove_item: - final FeedRemover remover = new FeedRemover(this, feed) { - @Override - protected void onPostExecute(Void result) { - super.onPostExecute(result); - if(getSelectedNavListIndex() == position) { - loadFragment(EpisodesFragment.TAG, null); - } - } - }; - ConfirmationDialog conDialog = new ConfirmationDialog(this, - R.string.remove_feed_label, - R.string.feed_delete_confirmation_msg) { - @Override - public void onConfirmButtonPressed( - DialogInterface dialog) { - dialog.dismiss(); - long mediaId = PlaybackPreferences.getCurrentlyPlayingFeedMediaId(); - if (mediaId > 0 && - FeedItemUtil.indexOfItemWithMediaId(feed.getItems(), mediaId) >= 0) { - Log.d(TAG, "Currently playing episode is about to be deleted, skipping"); - remover.skipOnCompletion = true; - int playerStatus = PlaybackPreferences.getCurrentPlayerStatus(); - if(playerStatus == PlaybackPreferences.PLAYER_STATUS_PLAYING) { - sendBroadcast(new Intent( - PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE)); - } - } - remover.executeAsync(); - } - }; - conDialog.createNewDialog().show(); - return true; - default: - return super.onContextItemSelected(item); - } - } - - @Override - public void onBackPressed() { - if(isDrawerOpen()) { - drawerLayout.closeDrawer(navDrawer); - } else { - super.onBackPressed(); - } - } - - private DBReader.NavDrawerData navDrawerData; - private int selectedNavListIndex = 0; - - private NavListAdapter.ItemAccess itemAccess = new NavListAdapter.ItemAccess() { - @Override - public int getCount() { - if (navDrawerData != null) { - return navDrawerData.feeds.size(); - } else { - return 0; - } - } - - @Override - public Feed getItem(int position) { - if (navDrawerData != null && 0 <= position && position < navDrawerData.feeds.size()) { - return navDrawerData.feeds.get(position); - } else { - return null; - } - } - - @Override - public int getSelectedItemIndex() { - return selectedNavListIndex; - } - - @Override - public int getQueueSize() { - return (navDrawerData != null) ? navDrawerData.queueSize : 0; - } - - @Override - public int getNumberOfNewItems() { - return (navDrawerData != null) ? navDrawerData.numNewItems : 0; - } - - @Override - public int getNumberOfDownloadedItems() { - return (navDrawerData != null) ? navDrawerData.numDownloadedItems : 0; - } - - @Override - public int getReclaimableItems() { - return (navDrawerData != null) ? navDrawerData.reclaimableSpace : 0; - } - - @Override - public int getFeedCounter(long feedId) { - return navDrawerData != null ? navDrawerData.feedCounters.get(feedId) : 0; - } - - @Override - public int getFeedCounterSum() { - if(navDrawerData == null) { - return 0; - } - int sum = 0; - for(int counter : navDrawerData.feedCounters.values()) { - sum += counter; - } - return sum; - } - - }; - - private void loadData() { - subscription = Observable.fromCallable(DBReader::getNavDrawerData) - .subscribeOn(Schedulers.newThread()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(result -> { - boolean handleIntent = (navDrawerData == null); - - navDrawerData = result; - navAdapter.notifyDataSetChanged(); - - if (handleIntent) { - handleNavIntent(); - } - }, error -> { - Log.e(TAG, Log.getStackTraceString(error)); - }); - } - - public void onEvent(QueueEvent event) { - Log.d(TAG, "onEvent(" + event + ")"); - // we are only interested in the number of queue items, not download status or position - if(event.action == QueueEvent.Action.DELETED_MEDIA || - event.action == QueueEvent.Action.SORTED || - event.action == QueueEvent.Action.MOVED) { - return; - } - loadData(); - } - - public void onEventMainThread(ProgressEvent event) { - Log.d(TAG, "onEvent(" + event + ")"); - switch(event.action) { - case START: - pd = new ProgressDialog(this); - pd.setMessage(event.message); - pd.setIndeterminate(true); - pd.setCancelable(false); - pd.show(); - break; - case END: - if(pd != null) { - pd.dismiss(); - } - break; - } - } - - private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() { - - @Override - public void update(EventDistributor eventDistributor, Integer arg) { - if ((EVENTS & arg) != 0) { - Log.d(TAG, "Received contentUpdate Intent."); - loadData(); - } - } - }; - - private void handleNavIntent() { - Log.d(TAG, "handleNavIntent()"); - Intent intent = getIntent(); - if (intent.hasExtra(EXTRA_FEED_ID) || - (intent.hasExtra(EXTRA_NAV_TYPE) && - (intent.hasExtra(EXTRA_NAV_INDEX) || intent.hasExtra(EXTRA_FRAGMENT_TAG)))) { - int index = intent.getIntExtra(EXTRA_NAV_INDEX, -1); - String tag = intent.getStringExtra(EXTRA_FRAGMENT_TAG); - Bundle args = intent.getBundleExtra(EXTRA_FRAGMENT_ARGS); - long feedId = intent.getLongExtra(EXTRA_FEED_ID, 0); - if (index >= 0) { - loadFragment(index, args); - } else if (tag != null) { - loadFragment(tag, args); - } else if(feedId > 0) { - loadFeedFragmentById(feedId, args); - } - } - setIntent(new Intent(MainActivity.this, MainActivity.class)); // to avoid handling the intent twice when the configuration changes - } - - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - setIntent(intent); - } -} diff --git a/app/src/play/java/de/danoeh/antennapod/activity/MediaplayerActivity.java b/app/src/play/java/de/danoeh/antennapod/activity/MediaplayerActivity.java deleted file mode 100644 index 71d288725..000000000 --- a/app/src/play/java/de/danoeh/antennapod/activity/MediaplayerActivity.java +++ /dev/null @@ -1,876 +0,0 @@ -package de.danoeh.antennapod.activity; - -import android.annotation.TargetApi; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.TypedArray; -import android.graphics.Color; -import android.graphics.PixelFormat; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.support.v7.app.AlertDialog; -import android.util.Log; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.ImageButton; -import android.widget.SeekBar; -import android.widget.SeekBar.OnSeekBarChangeListener; -import android.widget.TextView; -import android.widget.Toast; - -import com.afollestad.materialdialogs.MaterialDialog; -import com.bumptech.glide.Glide; -import com.joanzapata.iconify.IconDrawable; -import com.joanzapata.iconify.fonts.FontAwesomeIcons; - -import java.util.Locale; - -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.core.feed.FeedItem; -import de.danoeh.antennapod.core.feed.FeedMedia; -import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.service.playback.PlaybackService; -import de.danoeh.antennapod.core.storage.DBReader; -import de.danoeh.antennapod.core.storage.DBTasks; -import de.danoeh.antennapod.core.storage.DBWriter; -import de.danoeh.antennapod.core.util.Converter; -import de.danoeh.antennapod.core.util.ShareUtils; -import de.danoeh.antennapod.core.util.StorageUtils; -import de.danoeh.antennapod.core.util.playback.MediaPlayerError; -import de.danoeh.antennapod.core.util.playback.Playable; -import de.danoeh.antennapod.core.util.playback.PlaybackController; -import de.danoeh.antennapod.dialog.SleepTimerDialog; -import de.danoeh.antennapod.dialog.VariableSpeedDialog; -import rx.Observable; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; - - -/** - * Provides general features which are both needed for playing audio and video - * files. - */ -public abstract class MediaplayerActivity extends CastEnabledActivity implements OnSeekBarChangeListener { - private static final String TAG = "MediaplayerActivity"; - private static final String PREFS = "MediaPlayerActivityPreferences"; - private static final String PREF_SHOW_TIME_LEFT = "showTimeLeft"; - - protected PlaybackController controller; - - protected TextView txtvPosition; - protected TextView txtvLength; - protected SeekBar sbPosition; - protected ImageButton butRev; - protected TextView txtvRev; - protected ImageButton butPlay; - protected ImageButton butFF; - protected TextView txtvFF; - protected ImageButton butSkip; - - protected boolean showTimeLeft = false; - - private boolean isFavorite = false; - - private PlaybackController newPlaybackController() { - return new PlaybackController(this, false) { - - @Override - public void setupGUI() { - MediaplayerActivity.this.setupGUI(); - } - - @Override - public void onPositionObserverUpdate() { - MediaplayerActivity.this.onPositionObserverUpdate(); - } - - @Override - public void onBufferStart() { - MediaplayerActivity.this.onBufferStart(); - } - - @Override - public void onBufferEnd() { - MediaplayerActivity.this.onBufferEnd(); - } - - @Override - public void onBufferUpdate(float progress) { - MediaplayerActivity.this.onBufferUpdate(progress); - } - - @Override - public void handleError(int code) { - MediaplayerActivity.this.handleError(code); - } - - @Override - public void onReloadNotification(int code) { - MediaplayerActivity.this.onReloadNotification(code); - } - - @Override - public void onSleepTimerUpdate() { - supportInvalidateOptionsMenu(); - } - - @Override - public ImageButton getPlayButton() { - return butPlay; - } - - @Override - public void postStatusMsg(int msg, boolean showToast) { - MediaplayerActivity.this.postStatusMsg(msg, showToast); - } - - @Override - public void clearStatusMsg() { - MediaplayerActivity.this.clearStatusMsg(); - } - - @Override - public boolean loadMediaInfo() { - return MediaplayerActivity.this.loadMediaInfo(); - } - - @Override - public void onAwaitingVideoSurface() { - MediaplayerActivity.this.onAwaitingVideoSurface(); - } - - @Override - public void onServiceQueried() { - MediaplayerActivity.this.onServiceQueried(); - } - - @Override - public void onShutdownNotification() { - finish(); - } - - @Override - public void onPlaybackEnd() { - finish(); - } - - @Override - public void onPlaybackSpeedChange() { - MediaplayerActivity.this.onPlaybackSpeedChange(); - } - - @Override - protected void setScreenOn(boolean enable) { - super.setScreenOn(enable); - MediaplayerActivity.this.setScreenOn(enable); - } - - @Override - public void onSetSpeedAbilityChanged() { - MediaplayerActivity.this.onSetSpeedAbilityChanged(); - } - }; - } - - protected void onSetSpeedAbilityChanged() { - Log.d(TAG, "onSetSpeedAbilityChanged()"); - updatePlaybackSpeedButton(); - } - - protected void onPlaybackSpeedChange() { - updatePlaybackSpeedButtonText(); - } - - protected void onServiceQueried() { - supportInvalidateOptionsMenu(); - } - - protected void chooseTheme() { - setTheme(UserPreferences.getTheme()); - } - - protected void setScreenOn(boolean enable) { - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - chooseTheme(); - super.onCreate(savedInstanceState); - - Log.d(TAG, "onCreate()"); - StorageUtils.checkStorageAvailability(this); - - orientation = getResources().getConfiguration().orientation; - getWindow().setFormat(PixelFormat.TRANSPARENT); - } - - @Override - protected void onPause() { - if(controller != null) { - controller.reinitServiceIfPaused(); - controller.pause(); - } - super.onPause(); - } - - /** - * Should be used to switch to another player activity if the mime type is - * not the correct one for the current activity. - */ - protected abstract void onReloadNotification(int notificationCode); - - /** - * Should be used to inform the user that the PlaybackService is currently - * buffering. - */ - protected abstract void onBufferStart(); - - /** - * Should be used to hide the view that was showing the 'buffering'-message. - */ - protected abstract void onBufferEnd(); - - protected void onBufferUpdate(float progress) { - if (sbPosition != null) { - sbPosition.setSecondaryProgress((int) progress * sbPosition.getMax()); - } - } - - /** - * Current screen orientation. - */ - protected int orientation; - - @Override - protected void onStart() { - super.onStart(); - if (controller != null) { - controller.release(); - } - controller = newPlaybackController(); - } - - @Override - protected void onStop() { - Log.d(TAG, "onStop()"); - if (controller != null) { - controller.release(); - controller = null; // prevent leak - } - super.onStop(); - } - - @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) - @Override - public void onTrimMemory(int level) { - super.onTrimMemory(level); - Glide.get(this).trimMemory(level); - } - - @Override - public void onLowMemory() { - super.onLowMemory(); - Glide.get(this).clearMemory(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); - requestCastButton(MenuItem.SHOW_AS_ACTION_ALWAYS); - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.mediaplayer, menu); - return true; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - if (controller == null) { - return false; - } - Playable media = controller.getMedia(); - - menu.findItem(R.id.support_item).setVisible( - media != null && media.getPaymentLink() != null && - (media instanceof FeedMedia) && - ((FeedMedia) media).getItem() != null && - ((FeedMedia) media).getItem().getFlattrStatus().flattrable() - ); - - boolean hasWebsiteLink = media != null && media.getWebsiteLink() != null; - menu.findItem(R.id.visit_website_item).setVisible(hasWebsiteLink); - - boolean isItemAndHasLink = media != null && (media instanceof FeedMedia) && - ((FeedMedia) media).getItem() != null && ((FeedMedia) media).getItem().getLink() != null; - menu.findItem(R.id.share_link_item).setVisible(isItemAndHasLink); - menu.findItem(R.id.share_link_with_position_item).setVisible(isItemAndHasLink); - - boolean isItemHasDownloadLink = media != null && (media instanceof FeedMedia) && ((FeedMedia) media).getDownload_url() != null; - menu.findItem(R.id.share_download_url_item).setVisible(isItemHasDownloadLink); - menu.findItem(R.id.share_download_url_with_position_item).setVisible(isItemHasDownloadLink); - - menu.findItem(R.id.share_item).setVisible(hasWebsiteLink || isItemAndHasLink || isItemHasDownloadLink); - - menu.findItem(R.id.add_to_favorites_item).setVisible(false); - menu.findItem(R.id.remove_from_favorites_item).setVisible(false); - if(media != null && media instanceof FeedMedia) { - menu.findItem(R.id.add_to_favorites_item).setVisible(!isFavorite); - menu.findItem(R.id.remove_from_favorites_item).setVisible(isFavorite); - } - - boolean sleepTimerSet = controller.sleepTimerActive(); - boolean sleepTimerNotSet = controller.sleepTimerNotActive(); - menu.findItem(R.id.set_sleeptimer_item).setVisible(sleepTimerNotSet); - menu.findItem(R.id.disable_sleeptimer_item).setVisible(sleepTimerSet); - - if (this instanceof AudioplayerActivity) { - int[] attrs = {R.attr.action_bar_icon_color}; - TypedArray ta = obtainStyledAttributes(UserPreferences.getTheme(), attrs); - int textColor = ta.getColor(0, Color.GRAY); - ta.recycle(); - menu.findItem(R.id.audio_controls).setIcon(new IconDrawable(this, - FontAwesomeIcons.fa_sliders).color(textColor).actionBarSize()); - } else { - menu.findItem(R.id.audio_controls).setVisible(false); - } - - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (controller == null) { - return false; - } - Playable media = controller.getMedia(); - if (item.getItemId() == android.R.id.home) { - Intent intent = new Intent(MediaplayerActivity.this, - MainActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP - | Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); - return true; - } else { - if (media != null) { - switch (item.getItemId()) { - case R.id.add_to_favorites_item: - if(media instanceof FeedMedia) { - FeedItem feedItem = ((FeedMedia)media).getItem(); - if(feedItem != null) { - DBWriter.addFavoriteItem(feedItem); - isFavorite = true; - invalidateOptionsMenu(); - Toast.makeText(this, R.string.added_to_favorites, Toast.LENGTH_SHORT) - .show(); - } - } - break; - case R.id.remove_from_favorites_item: - if(media instanceof FeedMedia) { - FeedItem feedItem = ((FeedMedia)media).getItem(); - if(feedItem != null) { - DBWriter.removeFavoriteItem(feedItem); - isFavorite = false; - invalidateOptionsMenu(); - Toast.makeText(this, R.string.removed_from_favorites, Toast.LENGTH_SHORT) - .show(); - } - } - break; - case R.id.disable_sleeptimer_item: - if (controller.serviceAvailable()) { - - MaterialDialog.Builder stDialog = new MaterialDialog.Builder(this); - stDialog.title(R.string.sleep_timer_label); - stDialog.content(getString(R.string.time_left_label) - + Converter.getDurationStringLong((int) controller - .getSleepTimerTimeLeft())); - stDialog.positiveText(R.string.disable_sleeptimer_label); - stDialog.negativeText(R.string.cancel_label); - stDialog.onPositive((dialog, which) -> { - dialog.dismiss(); - controller.disableSleepTimer(); - }); - stDialog.onNegative((dialog, which) -> dialog.dismiss()); - stDialog.build().show(); - } - break; - case R.id.set_sleeptimer_item: - if (controller.serviceAvailable()) { - SleepTimerDialog td = new SleepTimerDialog(this) { - @Override - public void onTimerSet(long millis, boolean shakeToReset, boolean vibrate) { - controller.setSleepTimer(millis, shakeToReset, vibrate); - } - }; - td.createNewDialog().show(); - } - break; - case R.id.audio_controls: - MaterialDialog dialog = new MaterialDialog.Builder(this) - .title(R.string.audio_controls) - .customView(R.layout.audio_controls, true) - .neutralText(R.string.close_label) - .onNeutral((dialog1, which) -> { - final SeekBar left = (SeekBar) dialog1.findViewById(R.id.volume_left); - final SeekBar right = (SeekBar) dialog1.findViewById(R.id.volume_right); - UserPreferences.setVolume(left.getProgress(), right.getProgress()); - }) - .show(); - final SeekBar barPlaybackSpeed = (SeekBar) dialog.findViewById(R.id.playback_speed); - final Button butDecSpeed = (Button) dialog.findViewById(R.id.butDecSpeed); - butDecSpeed.setOnClickListener(v -> { - if(controller != null && controller.canSetPlaybackSpeed()) { - barPlaybackSpeed.setProgress(barPlaybackSpeed.getProgress() - 2); - } else { - VariableSpeedDialog.showGetPluginDialog(this); - } - }); - final Button butIncSpeed = (Button) dialog.findViewById(R.id.butIncSpeed); - butIncSpeed.setOnClickListener(v -> { - if(controller != null && controller.canSetPlaybackSpeed()) { - barPlaybackSpeed.setProgress(barPlaybackSpeed.getProgress() + 2); - } else { - VariableSpeedDialog.showGetPluginDialog(this); - } - }); - - final TextView txtvPlaybackSpeed = (TextView) dialog.findViewById(R.id.txtvPlaybackSpeed); - float currentSpeed = 1.0f; - try { - currentSpeed = Float.parseFloat(UserPreferences.getPlaybackSpeed()); - } catch (NumberFormatException e) { - Log.e(TAG, Log.getStackTraceString(e)); - UserPreferences.setPlaybackSpeed(String.valueOf(currentSpeed)); - } - - txtvPlaybackSpeed.setText(String.format("%.2fx", currentSpeed)); - barPlaybackSpeed.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if(controller != null && controller.canSetPlaybackSpeed()) { - float playbackSpeed = (progress + 10) / 20.0f; - controller.setPlaybackSpeed(playbackSpeed); - String speedPref = String.format(Locale.US, "%.2f", playbackSpeed); - UserPreferences.setPlaybackSpeed(speedPref); - String speedStr = String.format("%.2fx", playbackSpeed); - txtvPlaybackSpeed.setText(speedStr); - } else if(fromUser) { - float speed = Float.valueOf(UserPreferences.getPlaybackSpeed()); - barPlaybackSpeed.post(() -> barPlaybackSpeed.setProgress((int) (20 * speed) - 10)); - } - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - if(controller != null && !controller.canSetPlaybackSpeed()) { - VariableSpeedDialog.showGetPluginDialog(MediaplayerActivity.this); - } - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - } - }); - barPlaybackSpeed.setProgress((int) (20 * currentSpeed) - 10); - - final SeekBar barLeftVolume = (SeekBar) dialog.findViewById(R.id.volume_left); - barLeftVolume.setProgress(UserPreferences.getLeftVolumePercentage()); - final SeekBar barRightVolume = (SeekBar) dialog.findViewById(R.id.volume_right); - barRightVolume.setProgress(UserPreferences.getRightVolumePercentage()); - final CheckBox stereoToMono = (CheckBox) dialog.findViewById(R.id.stereo_to_mono); - stereoToMono.setChecked(UserPreferences.stereoToMono()); - if (controller != null && !controller.canDownmix()) { - stereoToMono.setEnabled(false); - String sonicOnly = getString(R.string.sonic_only); - stereoToMono.setText(stereoToMono.getText() + " [" + sonicOnly + "]"); - } - - barLeftVolume.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - controller.setVolume( - Converter.getVolumeFromPercentage(progress), - Converter.getVolumeFromPercentage(barRightVolume.getProgress())); - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - } - }); - barRightVolume.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - controller.setVolume( - Converter.getVolumeFromPercentage(barLeftVolume.getProgress()), - Converter.getVolumeFromPercentage(progress)); - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - } - }); - stereoToMono.setOnCheckedChangeListener((buttonView, isChecked) -> { - UserPreferences.stereoToMono(isChecked); - if (controller != null) { - controller.setDownmix(isChecked); - } - }); - break; - case R.id.visit_website_item: - Uri uri = Uri.parse(media.getWebsiteLink()); - startActivity(new Intent(Intent.ACTION_VIEW, uri)); - break; - case R.id.support_item: - if (media instanceof FeedMedia) { - DBTasks.flattrItemIfLoggedIn(this, ((FeedMedia) media).getItem()); - } - break; - case R.id.share_link_item: - if (media instanceof FeedMedia) { - ShareUtils.shareFeedItemLink(this, ((FeedMedia) media).getItem()); - } - break; - case R.id.share_download_url_item: - if (media instanceof FeedMedia) { - ShareUtils.shareFeedItemDownloadLink(this, ((FeedMedia) media).getItem()); - } - break; - case R.id.share_link_with_position_item: - if (media instanceof FeedMedia) { - ShareUtils.shareFeedItemLink(this, ((FeedMedia) media).getItem(), true); - } - break; - case R.id.share_download_url_with_position_item: - if (media instanceof FeedMedia) { - ShareUtils.shareFeedItemDownloadLink(this, ((FeedMedia) media).getItem(), true); - } - break; - default: - return false; - } - return true; - } else { - return false; - } - } - } - - @Override - protected void onResume() { - super.onResume(); - Log.d(TAG, "onResume()"); - StorageUtils.checkStorageAvailability(this); - if(controller != null) { - controller.init(); - } - } - - /** - * Called by 'handleStatus()' when the PlaybackService is waiting for - * a video surface. - */ - protected abstract void onAwaitingVideoSurface(); - - protected abstract void postStatusMsg(int resId, boolean showToast); - - protected abstract void clearStatusMsg(); - - protected void onPositionObserverUpdate() { - if (controller == null || txtvPosition == null || txtvLength == null) { - return; - } - int currentPosition = controller.getPosition(); - int duration = controller.getDuration(); - Log.d(TAG, "currentPosition " + Converter.getDurationStringLong(currentPosition)); - if (currentPosition == PlaybackService.INVALID_TIME || - duration == PlaybackService.INVALID_TIME) { - Log.w(TAG, "Could not react to position observer update because of invalid time"); - return; - } - txtvPosition.setText(Converter.getDurationStringLong(currentPosition)); - if (showTimeLeft) { - txtvLength.setText("-" + Converter.getDurationStringLong(duration - currentPosition)); - } else { - txtvLength.setText(Converter.getDurationStringLong(duration)); - } - updateProgressbarPosition(currentPosition, duration); - } - - private void updateProgressbarPosition(int position, int duration) { - Log.d(TAG, "updateProgressbarPosition(" + position + ", " + duration + ")"); - if(sbPosition == null) { - return; - } - float progress = ((float) position) / duration; - sbPosition.setProgress((int) (progress * sbPosition.getMax())); - } - - /** - * Load information about the media that is going to be played or currently - * being played. This method will be called when the activity is connected - * to the PlaybackService to ensure that the activity has the right - * FeedMedia object. - */ - protected boolean loadMediaInfo() { - Log.d(TAG, "loadMediaInfo()"); - Playable media = controller.getMedia(); - SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE); - showTimeLeft = prefs.getBoolean(PREF_SHOW_TIME_LEFT, false); - if (media != null) { - onPositionObserverUpdate(); - checkFavorite(); - updatePlaybackSpeedButton(); - return true; - } else { - return false; - } - } - - protected void updatePlaybackSpeedButton() { - // Only meaningful on AudioplayerActivity, where it is overridden. - } - - protected void updatePlaybackSpeedButtonText() { - // Only meaningful on AudioplayerActivity, where it is overridden. - } - - - protected void setupGUI() { - setContentView(getContentViewResourceId()); - sbPosition = (SeekBar) findViewById(R.id.sbPosition); - txtvPosition = (TextView) findViewById(R.id.txtvPosition); - - SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE); - showTimeLeft = prefs.getBoolean(PREF_SHOW_TIME_LEFT, false); - Log.d("timeleft", showTimeLeft ? "true" : "false"); - txtvLength = (TextView) findViewById(R.id.txtvLength); - if (txtvLength != null) { - txtvLength.setOnClickListener(v -> { - showTimeLeft = !showTimeLeft; - Playable media = controller.getMedia(); - if (media == null) { - return; - } - - String length; - if (showTimeLeft) { - length = "-" + Converter.getDurationStringLong(media.getDuration() - media.getPosition()); - } else { - length = Converter.getDurationStringLong(media.getDuration()); - } - txtvLength.setText(length); - - SharedPreferences.Editor editor = prefs.edit(); - editor.putBoolean(PREF_SHOW_TIME_LEFT, showTimeLeft); - editor.apply(); - Log.d("timeleft on click", showTimeLeft ? "true" : "false"); - }); - } - - butRev = (ImageButton) findViewById(R.id.butRev); - txtvRev = (TextView) findViewById(R.id.txtvRev); - if (txtvRev != null) { - txtvRev.setText(String.valueOf(UserPreferences.getRewindSecs())); - } - butPlay = (ImageButton) findViewById(R.id.butPlay); - butFF = (ImageButton) findViewById(R.id.butFF); - txtvFF = (TextView) findViewById(R.id.txtvFF); - if (txtvFF != null) { - txtvFF.setText(String.valueOf(UserPreferences.getFastFowardSecs())); - } - butSkip = (ImageButton) findViewById(R.id.butSkip); - - // SEEKBAR SETUP - - sbPosition.setOnSeekBarChangeListener(this); - - // BUTTON SETUP - - if (butRev != null) { - butRev.setOnClickListener(v -> onRewind()); - butRev.setOnLongClickListener(new View.OnLongClickListener() { - - int choice; - - @Override - public boolean onLongClick(View v) { - int checked = 0; - int rewindSecs = UserPreferences.getRewindSecs(); - final int[] values = getResources().getIntArray(R.array.seek_delta_values); - final String[] choices = new String[values.length]; - for (int i = 0; i < values.length; i++) { - if (rewindSecs == values[i]) { - checked = i; - } - choices[i] = String.valueOf(values[i]) + " " + getString(R.string.time_seconds); - } - choice = values[checked]; - AlertDialog.Builder builder = new AlertDialog.Builder(MediaplayerActivity.this); - builder.setTitle(R.string.pref_rewind); - builder.setSingleChoiceItems(choices, checked, - (dialog, which) -> { - choice = values[which]; - }); - builder.setNegativeButton(R.string.cancel_label, null); - builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> { - UserPreferences.setPrefRewindSecs(choice); - if(txtvRev != null){ - txtvRev.setText(String.valueOf(choice)); - } - }); - builder.create().show(); - return true; - } - }); - } - - butPlay.setOnClickListener(v -> onPlayPause()); - - if (butFF != null) { - butFF.setOnClickListener(v -> onFastForward()); - butFF.setOnLongClickListener(new View.OnLongClickListener() { - - int choice; - - @Override - public boolean onLongClick(View v) { - int checked = 0; - int rewindSecs = UserPreferences.getFastFowardSecs(); - final int[] values = getResources().getIntArray(R.array.seek_delta_values); - final String[] choices = new String[values.length]; - for (int i = 0; i < values.length; i++) { - if (rewindSecs == values[i]) { - checked = i; - } - choices[i] = String.valueOf(values[i]) + " " + getString(R.string.time_seconds); - } - choice = values[checked]; - AlertDialog.Builder builder = new AlertDialog.Builder(MediaplayerActivity.this); - builder.setTitle(R.string.pref_fast_forward); - builder.setSingleChoiceItems(choices, checked, - (dialog, which) -> { - choice = values[which]; - }); - builder.setNegativeButton(R.string.cancel_label, null); - builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> { - UserPreferences.setPrefFastForwardSecs(choice); - if(txtvFF != null) { - txtvFF.setText(String.valueOf(choice)); - } - }); - builder.create().show(); - return true; - } - }); - } - - if (butSkip != null) { - butSkip.setOnClickListener(v -> sendBroadcast(new Intent(PlaybackService.ACTION_SKIP_CURRENT_EPISODE))); - } - } - - protected void onRewind() { - if (controller == null) { - return; - } - int curr = controller.getPosition(); - controller.seekTo(curr - UserPreferences.getRewindSecs() * 1000); - } - - protected void onPlayPause() { - if(controller == null) { - return; - } - controller.playPause(); - } - - protected void onFastForward() { - if (controller == null) { - return; - } - int curr = controller.getPosition(); - controller.seekTo(curr + UserPreferences.getFastFowardSecs() * 1000); - } - - protected abstract int getContentViewResourceId(); - - void handleError(int errorCode) { - final AlertDialog.Builder errorDialog = new AlertDialog.Builder(this); - errorDialog.setTitle(R.string.error_label); - errorDialog.setMessage(MediaPlayerError.getErrorString(this, errorCode)); - errorDialog.setNeutralButton("OK", - (dialog, which) -> { - dialog.dismiss(); - finish(); - } - ); - errorDialog.create().show(); - } - - float prog; - - @Override - public void onProgressChanged (SeekBar seekBar,int progress, boolean fromUser) { - if (controller == null || txtvLength == null) { - return; - } - prog = controller.onSeekBarProgressChanged(seekBar, progress, fromUser, txtvPosition); - if (showTimeLeft && prog != 0) { - int duration = controller.getDuration(); - String length = "-" + Converter.getDurationStringLong(duration - (int) (prog * duration)); - txtvLength.setText(length); - } - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - if (controller != null) { - controller.onSeekBarStartTrackingTouch(seekBar); - } - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - if (controller != null) { - controller.onSeekBarStopTrackingTouch(seekBar, prog); - } - } - - private void checkFavorite() { - Playable playable = controller.getMedia(); - if (playable != null && playable instanceof FeedMedia) { - FeedItem feedItem = ((FeedMedia) playable).getItem(); - if (feedItem != null) { - Observable.fromCallable(() -> DBReader.getFeedItem(feedItem.getId())) - .subscribeOn(Schedulers.newThread()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe( - item -> { - boolean isFav = item.isTagged(FeedItem.TAG_FAVORITE); - if (isFavorite != isFav) { - isFavorite = isFav; - invalidateOptionsMenu(); - } - }, error -> { - Log.e(TAG, Log.getStackTraceString(error)); - } - ); - } - } - } - -} diff --git a/app/src/play/java/de/danoeh/antennapod/fragment/ItemFragment.java b/app/src/play/java/de/danoeh/antennapod/fragment/ItemFragment.java deleted file mode 100644 index 524b78ed2..000000000 --- a/app/src/play/java/de/danoeh/antennapod/fragment/ItemFragment.java +++ /dev/null @@ -1,593 +0,0 @@ -package de.danoeh.antennapod.fragment; - -import android.content.ClipData; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v4.app.Fragment; -import android.support.v4.content.ContextCompat; -import android.support.v4.view.GestureDetectorCompat; -import android.text.Layout; -import android.text.TextUtils; -import android.util.Log; -import android.view.ContextMenu; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.webkit.WebSettings; -import android.webkit.WebView; -import android.webkit.WebViewClient; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.TextView; -import android.widget.Toast; - -import com.bumptech.glide.Glide; -import com.joanzapata.iconify.Iconify; -import com.joanzapata.iconify.widget.IconButton; - -import org.apache.commons.lang3.ArrayUtils; - -import java.util.List; - -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.CastEnabledActivity; -import de.danoeh.antennapod.activity.MainActivity; -import de.danoeh.antennapod.adapter.DefaultActionButtonCallback; -import de.danoeh.antennapod.core.event.DownloadEvent; -import de.danoeh.antennapod.core.event.DownloaderUpdate; -import de.danoeh.antennapod.core.event.FeedItemEvent; -import de.danoeh.antennapod.core.feed.EventDistributor; -import de.danoeh.antennapod.core.feed.FeedItem; -import de.danoeh.antennapod.core.feed.FeedMedia; -import de.danoeh.antennapod.core.glide.ApGlideSettings; -import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.service.download.Downloader; -import de.danoeh.antennapod.core.storage.DBReader; -import de.danoeh.antennapod.core.storage.DBTasks; -import de.danoeh.antennapod.core.storage.DBWriter; -import de.danoeh.antennapod.core.storage.DownloadRequestException; -import de.danoeh.antennapod.core.storage.DownloadRequester; -import de.danoeh.antennapod.core.util.Converter; -import de.danoeh.antennapod.core.util.DateUtils; -import de.danoeh.antennapod.core.util.IntentUtils; -import de.danoeh.antennapod.core.util.LongList; -import de.danoeh.antennapod.core.util.ShareUtils; -import de.danoeh.antennapod.core.util.playback.Timeline; -import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; -import de.danoeh.antennapod.view.OnSwipeGesture; -import de.danoeh.antennapod.view.SwipeGestureDetector; -import de.greenrobot.event.EventBus; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; - -/** - * Displays information about a FeedItem and actions. - */ -public class ItemFragment extends Fragment implements OnSwipeGesture { - - private static final String TAG = "ItemFragment"; - - private static final int EVENTS = EventDistributor.UNREAD_ITEMS_UPDATE; - - private static final String ARG_FEEDITEMS = "feeditems"; - private static final String ARG_FEEDITEM_POS = "feeditem_pos"; - - private GestureDetectorCompat headerGestureDetector; - private GestureDetectorCompat webviewGestureDetector; - - /** - * Creates a new instance of an ItemFragment - * - * @param feeditem The ID of the FeedItem that should be displayed. - * @return The ItemFragment instance - */ - public static ItemFragment newInstance(long feeditem) { - return newInstance(new long[] { feeditem }, 0); - } - - /** - * Creates a new instance of an ItemFragment - * - * @param feeditems The IDs of the FeedItems that belong to the same list - * @param feedItemPos The position of the FeedItem that is currently shown - * @return The ItemFragment instance - */ - public static ItemFragment newInstance(long[] feeditems, int feedItemPos) { - ItemFragment fragment = new ItemFragment(); - Bundle args = new Bundle(); - args.putLongArray(ARG_FEEDITEMS, feeditems); - args.putInt(ARG_FEEDITEM_POS, feedItemPos); - fragment.setArguments(args); - return fragment; - } - - private boolean itemsLoaded = false; - private long[] feedItems; - private int feedItemPos; - private FeedItem item; - private String webviewData; - private List downloaderList; - - private ViewGroup root; - private WebView webvDescription; - private TextView txtvPodcast; - private TextView txtvTitle; - private TextView txtvDuration; - private TextView txtvPublished; - private ImageView imgvCover; - private ProgressBar progbarDownload; - private ProgressBar progbarLoading; - private IconButton butAction1; - private IconButton butAction2; - private Menu popupMenu; - - private Subscription subscription; - - /** - * URL that was selected via long-press. - */ - private String selectedURL; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setRetainInstance(true); - setHasOptionsMenu(true); - - feedItems = getArguments().getLongArray(ARG_FEEDITEMS); - feedItemPos = getArguments().getInt(ARG_FEEDITEM_POS); - - headerGestureDetector = new GestureDetectorCompat(getActivity(), new SwipeGestureDetector(this)); - webviewGestureDetector = new GestureDetectorCompat(getActivity(), new SwipeGestureDetector(this) { - // necessary for the longclick context menu to work properly - @Override - public boolean onDown(MotionEvent e) { - return false; - } - }); - } - - @Override - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - super.onCreateView(inflater, container, savedInstanceState); - View layout = inflater.inflate(R.layout.feeditem_fragment, container, false); - - root = (ViewGroup) layout.findViewById(R.id.content_root); - - LinearLayout header = (LinearLayout) root.findViewById(R.id.header); - if(feedItems.length > 0) { - header.setOnTouchListener((v, event) -> headerGestureDetector.onTouchEvent(event)); - } - - txtvPodcast = (TextView) layout.findViewById(R.id.txtvPodcast); - txtvPodcast.setOnClickListener(v -> openPodcast()); - txtvTitle = (TextView) layout.findViewById(R.id.txtvTitle); - if(Build.VERSION.SDK_INT >= 23) { - txtvTitle.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL); - } - txtvDuration = (TextView) layout.findViewById(R.id.txtvDuration); - txtvPublished = (TextView) layout.findViewById(R.id.txtvPublished); - if (Build.VERSION.SDK_INT >= 14) { // ellipsize is causing problems on old versions, see #448 - txtvTitle.setEllipsize(TextUtils.TruncateAt.END); - } - webvDescription = (WebView) layout.findViewById(R.id.webvDescription); - if (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) { - if (Build.VERSION.SDK_INT >= 11 - && Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { - webvDescription.setLayerType(View.LAYER_TYPE_SOFTWARE, null); - } - webvDescription.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.black)); - } - webvDescription.getSettings().setUseWideViewPort(false); - webvDescription.getSettings().setLayoutAlgorithm( - WebSettings.LayoutAlgorithm.NARROW_COLUMNS); - webvDescription.getSettings().setLoadWithOverviewMode(true); - if(feedItems.length > 0) { - webvDescription.setOnLongClickListener(webViewLongClickListener); - } - webvDescription.setOnTouchListener((v, event) -> webviewGestureDetector.onTouchEvent(event)); - webvDescription.setWebViewClient(new WebViewClient() { - @Override - public boolean shouldOverrideUrlLoading(WebView view, String url) { - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); - if(IntentUtils.isCallable(getActivity(), intent)) { - startActivity(intent); - } - return true; - } - }); - registerForContextMenu(webvDescription); - - imgvCover = (ImageView) layout.findViewById(R.id.imgvCover); - imgvCover.setOnClickListener(v -> openPodcast()); - progbarDownload = (ProgressBar) layout.findViewById(R.id.progbarDownload); - progbarLoading = (ProgressBar) layout.findViewById(R.id.progbarLoading); - butAction1 = (IconButton) layout.findViewById(R.id.butAction1); - butAction2 = (IconButton) layout.findViewById(R.id.butAction2); - - butAction1.setOnClickListener(v -> { - if (item == null) { - return; - } - DefaultActionButtonCallback actionButtonCallback = new DefaultActionButtonCallback(getActivity()); - actionButtonCallback.onActionButtonPressed(item, item.isTagged(FeedItem.TAG_QUEUE) ? - LongList.of(item.getId()) : new LongList(0)); - FeedMedia media = item.getMedia(); - if (media != null && media.isDownloaded()) { - // playback was started, dialog should close itself - ((MainActivity) getActivity()).dismissChildFragment(); - } - }); - - butAction2.setOnClickListener(v -> { - if (item == null) { - return; - } - - if (item.hasMedia()) { - FeedMedia media = item.getMedia(); - if (!media.isDownloaded()) { - DBTasks.playMedia(getActivity(), media, true, true, true); - ((MainActivity) getActivity()).dismissChildFragment(); - } else { - DBWriter.deleteFeedMediaOfItem(getActivity(), media.getId()); - } - } else if (item.getLink() != null) { - Uri uri = Uri.parse(item.getLink()); - getActivity().startActivity(new Intent(Intent.ACTION_VIEW, uri)); - } - }); - - return layout; - } - - @Override - public void onActivityCreated(@Nullable Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - load(); - } - - @Override - public void onResume() { - super.onResume(); - EventDistributor.getInstance().register(contentUpdate); - EventBus.getDefault().registerSticky(this); - if(itemsLoaded) { - progbarLoading.setVisibility(View.GONE); - updateAppearance(); - } - } - - @Override - public void onPause() { - super.onPause(); - EventDistributor.getInstance().unregister(contentUpdate); - EventBus.getDefault().unregister(this); - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - if(subscription != null) { - subscription.unsubscribe(); - } - if (webvDescription != null && root != null) { - root.removeView(webvDescription); - webvDescription.destroy(); - } - } - - @Override - public boolean onSwipeLeftToRight() { - Log.d(TAG, "onSwipeLeftToRight()"); - feedItemPos = feedItemPos - 1; - if(feedItemPos < 0) { - feedItemPos = feedItems.length - 1; - } - load(); - return true; - } - - @Override - public boolean onSwipeRightToLeft() { - Log.d(TAG, "onSwipeRightToLeft()"); - feedItemPos = (feedItemPos + 1) % feedItems.length; - load(); - return true; - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - if(!isAdded() || item == null) { - return; - } - ((CastEnabledActivity) getActivity()).requestCastButton(MenuItem.SHOW_AS_ACTION_ALWAYS); - inflater.inflate(R.menu.feeditem_options, menu); - popupMenu = menu; - if (item.hasMedia()) { - FeedItemMenuHandler.onPrepareMenu(popupMenuInterface, item, true, null); - } else { - // these are already available via button1 and button2 - FeedItemMenuHandler.onPrepareMenu(popupMenuInterface, item, true, null, - R.id.mark_read_item, R.id.visit_website_item); - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem menuItem) { - switch(menuItem.getItemId()) { - case R.id.open_podcast: - openPodcast(); - return true; - default: - try { - return FeedItemMenuHandler.onMenuItemClicked(getActivity(), menuItem.getItemId(), item); - } catch (DownloadRequestException e) { - e.printStackTrace(); - Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_LONG).show(); - return true; - } - } - } - - private final FeedItemMenuHandler.MenuInterface popupMenuInterface = new FeedItemMenuHandler.MenuInterface() { - @Override - public void setItemVisibility(int id, boolean visible) { - MenuItem item = popupMenu.findItem(id); - if (item != null) { - item.setVisible(visible); - } - } - }; - - - private void onFragmentLoaded() { - if (webviewData != null) { - webvDescription.loadDataWithBaseURL(null, webviewData, "text/html", "utf-8", "about:blank"); - } - updateAppearance(); - } - - private void updateAppearance() { - if (item == null) { - Log.d(TAG, "updateAppearance item is null"); - return; - } - getActivity().supportInvalidateOptionsMenu(); - txtvPodcast.setText(item.getFeed().getTitle()); - txtvTitle.setText(item.getTitle()); - - if (item.getPubDate() != null) { - String pubDateStr = DateUtils.formatAbbrev(getActivity(), item.getPubDate()); - txtvPublished.setText(pubDateStr); - } - - Glide.with(getActivity()) - .load(item.getImageLocation()) - .placeholder(R.color.light_gray) - .error(R.color.light_gray) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() - .into(imgvCover); - - progbarDownload.setVisibility(View.GONE); - if (item.hasMedia() && downloaderList != null) { - for (Downloader downloader : downloaderList) { - if (downloader.getDownloadRequest().getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA - && downloader.getDownloadRequest().getFeedfileId() == item.getMedia().getId()) { - progbarDownload.setVisibility(View.VISIBLE); - progbarDownload.setProgress(downloader.getDownloadRequest().getProgressPercent()); - } - } - } - - FeedMedia media = item.getMedia(); - String butAction1Icon = null; - int butAction1Text = 0; - String butAction2Icon = null; - int butAction2Text = 0; - if (media == null) { - if (!item.isPlayed()) { - butAction1Icon = "{fa-check 24sp}"; - butAction1Text = R.string.mark_read_label; - } - if (item.getLink() != null) { - butAction2Icon = "{md-web 24sp}"; - butAction2Text = R.string.visit_website_label; - } - } else { - if(media.getDuration() > 0) { - txtvDuration.setText(Converter.getDurationStringLong(media.getDuration())); - } - boolean isDownloading = DownloadRequester.getInstance().isDownloadingFile(media); - if (!media.isDownloaded()) { - butAction2Icon = "{md-settings-input-antenna 24sp}"; - butAction2Text = R.string.stream_label; - } else { - butAction2Icon = "{md-delete 24sp}"; - butAction2Text = R.string.remove_label; - } - if (isDownloading) { - butAction1Icon = "{md-cancel 24sp}"; - butAction1Text = R.string.cancel_label; - } else if (media.isDownloaded()) { - butAction1Icon = "{md-play-arrow 24sp}"; - butAction1Text = R.string.play_label; - } else { - butAction1Icon = "{md-file-download 24sp}"; - butAction1Text = R.string.download_label; - } - } - if(butAction1Icon != null && butAction1Text != 0) { - butAction1.setText(butAction1Icon +"\u0020\u0020" + getActivity().getString(butAction1Text)); - Iconify.addIcons(butAction1); - butAction1.setVisibility(View.VISIBLE); - } else { - butAction1.setVisibility(View.INVISIBLE); - } - if(butAction2Icon != null && butAction2Text != 0) { - butAction2.setText(butAction2Icon +"\u0020\u0020" + getActivity().getString(butAction2Text)); - Iconify.addIcons(butAction2); - butAction2.setVisibility(View.VISIBLE); - } else { - butAction2.setVisibility(View.INVISIBLE); - } - } - - private View.OnLongClickListener webViewLongClickListener = new View.OnLongClickListener() { - - @Override - public boolean onLongClick(View v) { - WebView.HitTestResult r = webvDescription.getHitTestResult(); - if (r != null - && r.getType() == WebView.HitTestResult.SRC_ANCHOR_TYPE) { - Log.d(TAG, "Link of webview was long-pressed. Extra: " + r.getExtra()); - selectedURL = r.getExtra(); - webvDescription.showContextMenu(); - return true; - } - selectedURL = null; - return false; - } - }; - - @Override - public boolean onContextItemSelected(MenuItem item) { - boolean handled = selectedURL != null; - if (selectedURL != null) { - switch (item.getItemId()) { - case R.id.open_in_browser_item: - Uri uri = Uri.parse(selectedURL); - final Intent intent = new Intent(Intent.ACTION_VIEW, uri); - if(IntentUtils.isCallable(getActivity(), intent)) { - getActivity().startActivity(intent); - } - break; - case R.id.share_url_item: - ShareUtils.shareLink(getActivity(), selectedURL); - break; - case R.id.copy_url_item: - if (android.os.Build.VERSION.SDK_INT >= 11) { - ClipData clipData = ClipData.newPlainText(selectedURL, - selectedURL); - android.content.ClipboardManager cm = (android.content.ClipboardManager) getActivity() - .getSystemService(Context.CLIPBOARD_SERVICE); - cm.setPrimaryClip(clipData); - } else { - android.text.ClipboardManager cm = (android.text.ClipboardManager) getActivity() - .getSystemService(Context.CLIPBOARD_SERVICE); - cm.setText(selectedURL); - } - Toast t = Toast.makeText(getActivity(), - R.string.copied_url_msg, Toast.LENGTH_SHORT); - t.show(); - break; - default: - handled = false; - break; - - } - selectedURL = null; - } - return handled; - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, - ContextMenu.ContextMenuInfo menuInfo) { - if (selectedURL != null) { - super.onCreateContextMenu(menu, v, menuInfo); - Uri uri = Uri.parse(selectedURL); - final Intent intent = new Intent(Intent.ACTION_VIEW, uri); - if(IntentUtils.isCallable(getActivity(), intent)) { - menu.add(Menu.NONE, R.id.open_in_browser_item, Menu.NONE, - R.string.open_in_browser_label); - } - menu.add(Menu.NONE, R.id.copy_url_item, Menu.NONE, - R.string.copy_url_label); - menu.add(Menu.NONE, R.id.share_url_item, Menu.NONE, - R.string.share_url_label); - menu.setHeaderTitle(selectedURL); - } - } - - private void openPodcast() { - Fragment fragment = ItemlistFragment.newInstance(item.getFeedId()); - ((MainActivity)getActivity()).loadChildFragment(fragment); - } - - public void onEventMainThread(FeedItemEvent event) { - Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); - for(FeedItem item : event.items) { - if(feedItems[feedItemPos] == item.getId()) { - load(); - return; - } - } - } - - public void onEventMainThread(DownloadEvent event) { - Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); - DownloaderUpdate update = event.update; - downloaderList = update.downloaders; - if(item == null || item.getMedia() == null) { - return; - } - long mediaId = item.getMedia().getId(); - if(ArrayUtils.contains(update.mediaIds, mediaId)) { - if (itemsLoaded && getActivity() != null) { - updateAppearance(); - } - } - } - - - private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() { - @Override - public void update(EventDistributor eventDistributor, Integer arg) { - if ((arg & EVENTS) != 0) { - load(); - } - } - }; - - private void load() { - if(subscription != null) { - subscription.unsubscribe(); - } - progbarLoading.setVisibility(View.VISIBLE); - subscription = Observable.fromCallable(this::loadInBackground) - .subscribeOn(Schedulers.newThread()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(result -> { - progbarLoading.setVisibility(View.GONE); - item = result; - itemsLoaded = true; - onFragmentLoaded(); - }, error -> { - Log.e(TAG, Log.getStackTraceString(error)); - }); - } - - private FeedItem loadInBackground() { - FeedItem feedItem = DBReader.getFeedItem(feedItems[feedItemPos]); - if (feedItem != null) { - Timeline t = new Timeline(getActivity(), feedItem); - webviewData = t.processShownotes(false); - } - return feedItem; - } - -} diff --git a/app/src/play/java/de/danoeh/antennapod/preferences/PreferenceController.java b/app/src/play/java/de/danoeh/antennapod/preferences/PreferenceController.java deleted file mode 100644 index 183ef338a..000000000 --- a/app/src/play/java/de/danoeh/antennapod/preferences/PreferenceController.java +++ /dev/null @@ -1,953 +0,0 @@ -package de.danoeh.antennapod.preferences; - -import android.Manifest; -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.TimePickerDialog; -import android.content.ActivityNotFoundException; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.pm.PackageManager; -import android.content.res.Resources; -import android.net.Uri; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiManager; -import android.os.Build; -import android.preference.CheckBoxPreference; -import android.preference.EditTextPreference; -import android.preference.ListPreference; -import android.preference.Preference; -import android.preference.PreferenceManager; -import android.preference.PreferenceScreen; -import android.support.design.widget.Snackbar; -import android.support.v4.app.ActivityCompat; -import android.support.v4.content.ContextCompat; -import android.support.v7.app.AlertDialog; -import android.text.Editable; -import android.text.Html; -import android.text.TextWatcher; -import android.text.format.DateFormat; -import android.util.Log; -import android.widget.EditText; -import android.widget.Toast; -import android.widget.ListView; - -import com.afollestad.materialdialogs.MaterialDialog; -import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.GoogleApiAvailability; - -import org.apache.commons.lang3.ArrayUtils; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import de.danoeh.antennapod.CrashReportWriter; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.AboutActivity; -import de.danoeh.antennapod.activity.DirectoryChooserActivity; -import de.danoeh.antennapod.activity.MainActivity; -import de.danoeh.antennapod.activity.PreferenceActivity; -import de.danoeh.antennapod.activity.PreferenceActivityGingerbread; -import de.danoeh.antennapod.activity.StatisticsActivity; -import de.danoeh.antennapod.asynctask.OpmlExportWorker; -import de.danoeh.antennapod.core.preferences.GpodnetPreferences; -import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.service.GpodnetSyncService; -import de.danoeh.antennapod.core.util.Converter; -import de.danoeh.antennapod.core.util.StorageUtils; -import de.danoeh.antennapod.core.util.flattr.FlattrUtils; -import de.danoeh.antennapod.dialog.AuthenticationDialog; -import de.danoeh.antennapod.dialog.AutoFlattrPreferenceDialog; -import de.danoeh.antennapod.dialog.GpodnetSetHostnameDialog; -import de.danoeh.antennapod.dialog.ProxyDialog; -import de.danoeh.antennapod.dialog.VariableSpeedDialog; - -/** - * Sets up a preference UI that lets the user change user preferences. - */ - -public class PreferenceController implements SharedPreferences.OnSharedPreferenceChangeListener { - - private static final String TAG = "PreferenceController"; - - public static final String PREF_FLATTR_SETTINGS = "prefFlattrSettings"; - public static final String PREF_FLATTR_AUTH = "pref_flattr_authenticate"; - public static final String PREF_FLATTR_REVOKE = "prefRevokeAccess"; - public static final String PREF_AUTO_FLATTR_PREFS = "prefAutoFlattrPrefs"; - public static final String PREF_OPML_EXPORT = "prefOpmlExport"; - public static final String STATISTICS = "statistics"; - public static final String PREF_ABOUT = "prefAbout"; - public static final String PREF_CHOOSE_DATA_DIR = "prefChooseDataDir"; - public static final String AUTO_DL_PREF_SCREEN = "prefAutoDownloadSettings"; - public static final String PREF_PLAYBACK_SPEED_LAUNCHER = "prefPlaybackSpeedLauncher"; - public static final String PREF_GPODNET_LOGIN = "pref_gpodnet_authenticate"; - public static final String PREF_GPODNET_SETLOGIN_INFORMATION = "pref_gpodnet_setlogin_information"; - public static final String PREF_GPODNET_SYNC = "pref_gpodnet_sync"; - public static final String PREF_GPODNET_LOGOUT = "pref_gpodnet_logout"; - public static final String PREF_GPODNET_HOSTNAME = "pref_gpodnet_hostname"; - public static final String PREF_EXPANDED_NOTIFICATION = "prefExpandNotify"; - public static final String PREF_PROXY = "prefProxy"; - public static final String PREF_KNOWN_ISSUES = "prefKnownIssues"; - public static final String PREF_FAQ = "prefFaq"; - public static final String PREF_SEND_CRASH_REPORT = "prefSendCrashReport"; - - private final PreferenceUI ui; - - private CheckBoxPreference[] selectedNetworks; - - private static final String[] EXTERNAL_STORAGE_PERMISSIONS = { - Manifest.permission.READ_EXTERNAL_STORAGE, - Manifest.permission.WRITE_EXTERNAL_STORAGE }; - private static final int PERMISSION_REQUEST_EXTERNAL_STORAGE = 41; - - public PreferenceController(PreferenceUI ui) { - this.ui = ui; - PreferenceManager.getDefaultSharedPreferences(ui.getActivity().getApplicationContext()) - .registerOnSharedPreferenceChangeListener(this); - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - if(key.equals(UserPreferences.PREF_SONIC)) { - CheckBoxPreference prefSonic = (CheckBoxPreference) ui.findPreference(UserPreferences.PREF_SONIC); - if(prefSonic != null) { - prefSonic.setChecked(sharedPreferences.getBoolean(UserPreferences.PREF_SONIC, false)); - } - } - } - - /** - * Returns the preference activity that should be used on this device. - * - * @return PreferenceActivity if the API level is greater than 10, PreferenceActivityGingerbread otherwise. - */ - public static Class getPreferenceActivity() { - if (Build.VERSION.SDK_INT > 10) { - return PreferenceActivity.class; - } else { - return PreferenceActivityGingerbread.class; - } - } - - public void onCreate() { - final Activity activity = ui.getActivity(); - - if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { - // disable expanded notification option on unsupported android versions - ui.findPreference(PreferenceController.PREF_EXPANDED_NOTIFICATION).setEnabled(false); - ui.findPreference(PreferenceController.PREF_EXPANDED_NOTIFICATION).setOnPreferenceClickListener( - preference -> { - Toast toast = Toast.makeText(activity, - R.string.pref_expand_notify_unsupport_toast, Toast.LENGTH_SHORT); - toast.show(); - return true; - } - ); - } - ui.findPreference(PreferenceController.PREF_FLATTR_REVOKE).setOnPreferenceClickListener( - preference -> { - FlattrUtils.revokeAccessToken(activity); - checkItemVisibility(); - return true; - } - ); - ui.findPreference(PreferenceController.PREF_ABOUT).setOnPreferenceClickListener( - preference -> { - activity.startActivity(new Intent(activity, AboutActivity.class)); - return true; - } - ); - ui.findPreference(PreferenceController.STATISTICS).setOnPreferenceClickListener( - preference -> { - activity.startActivity(new Intent(activity, StatisticsActivity.class)); - return true; - } - ); - ui.findPreference(PreferenceController.PREF_OPML_EXPORT).setOnPreferenceClickListener( - preference -> { - new OpmlExportWorker(activity).executeAsync(); - return true; - } - ); - ui.findPreference(PreferenceController.PREF_CHOOSE_DATA_DIR).setOnPreferenceClickListener( - preference -> { - if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT && - Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) { - showChooseDataFolderDialog(); - } else { - int readPermission = ActivityCompat.checkSelfPermission( - activity, Manifest.permission.READ_EXTERNAL_STORAGE); - int writePermission = ActivityCompat.checkSelfPermission( - activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); - if (readPermission == PackageManager.PERMISSION_GRANTED && - writePermission == PackageManager.PERMISSION_GRANTED) { - openDirectoryChooser(); - } else { - requestPermission(); - } - } - return true; - } - ); - ui.findPreference(PreferenceController.PREF_CHOOSE_DATA_DIR) - .setOnPreferenceClickListener( - preference -> { - if (Build.VERSION.SDK_INT >= 19) { - showChooseDataFolderDialog(); - } else { - Intent intent = new Intent(activity, DirectoryChooserActivity.class); - activity.startActivityForResult(intent, - DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED); - } - return true; - } - ); - ui.findPreference(UserPreferences.PREF_THEME) - .setOnPreferenceChangeListener( - (preference, newValue) -> { - Intent i = new Intent(activity, MainActivity.class); - i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK - | Intent.FLAG_ACTIVITY_NEW_TASK); - activity.finish(); - activity.startActivity(i); - return true; - } - ); - ui.findPreference(UserPreferences.PREF_HIDDEN_DRAWER_ITEMS) - .setOnPreferenceClickListener(preference -> { - showDrawerPreferencesDialog(); - return true; - }); - - ui.findPreference(UserPreferences.PREF_COMPACT_NOTIFICATION_BUTTONS) - .setOnPreferenceClickListener(preference -> { - showNotificationButtonsDialog(); - return true; - }); - - ui.findPreference(UserPreferences.PREF_UPDATE_INTERVAL) - .setOnPreferenceClickListener(preference -> { - showUpdateIntervalTimePreferencesDialog(); - return true; - }); - - ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL).setOnPreferenceChangeListener( - (preference, newValue) -> { - if (newValue instanceof Boolean) { - boolean enabled = (Boolean) newValue; - ui.findPreference(UserPreferences.PREF_EPISODE_CACHE_SIZE).setEnabled(enabled); - ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_ON_BATTERY).setEnabled(enabled); - ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_WIFI_FILTER).setEnabled(enabled); - setSelectedNetworksEnabled(enabled && UserPreferences.isEnableAutodownloadWifiFilter()); - } - return true; - }); - ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_WIFI_FILTER) - .setOnPreferenceChangeListener( - (preference, newValue) -> { - if (newValue instanceof Boolean) { - setSelectedNetworksEnabled((Boolean) newValue); - return true; - } else { - return false; - } - } - ); - ui.findPreference(UserPreferences.PREF_PARALLEL_DOWNLOADS) - .setOnPreferenceChangeListener( - (preference, o) -> { - if (o instanceof String) { - try { - int value = Integer.parseInt((String) o); - if (1 <= value && value <= 50) { - setParallelDownloadsText(value); - return true; - } - } catch (NumberFormatException e) { - return false; - } - } - return false; - } - ); - // validate and set correct value: number of downloads between 1 and 50 (inclusive) - final EditText ev = ((EditTextPreference) ui.findPreference(UserPreferences.PREF_PARALLEL_DOWNLOADS)).getEditText(); - ev.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void afterTextChanged(Editable s) { - if (s.length() > 0) { - try { - int value = Integer.parseInt(s.toString()); - if (value <= 0) { - ev.setText("1"); - } else if (value > 50) { - ev.setText("50"); - } - } catch (NumberFormatException e) { - ev.setText("6"); - } - ev.setSelection(ev.getText().length()); - } - } - }); - ui.findPreference(UserPreferences.PREF_EPISODE_CACHE_SIZE) - .setOnPreferenceChangeListener( - (preference, o) -> { - if (o instanceof String) { - setEpisodeCacheSizeText(UserPreferences.readEpisodeCacheSize((String) o)); - } - return true; - } - ); - ui.findPreference(PreferenceController.PREF_PLAYBACK_SPEED_LAUNCHER) - .setOnPreferenceClickListener(preference -> { - VariableSpeedDialog.showDialog(activity); - return true; - }); - ui.findPreference(PreferenceController.PREF_GPODNET_SETLOGIN_INFORMATION) - .setOnPreferenceClickListener(preference -> { - AuthenticationDialog dialog = new AuthenticationDialog(activity, - R.string.pref_gpodnet_setlogin_information_title, false, false, GpodnetPreferences.getUsername(), - null) { - - @Override - protected void onConfirmed(String username, String password, boolean saveUsernamePassword) { - GpodnetPreferences.setPassword(password); - } - }; - dialog.show(); - return true; - }); - ui.findPreference(PreferenceController.PREF_GPODNET_SYNC). - setOnPreferenceClickListener(preference -> { - GpodnetSyncService.sendSyncIntent(ui.getActivity().getApplicationContext()); - Toast toast = Toast.makeText(ui.getActivity(), R.string.pref_gpodnet_sync_started, - Toast.LENGTH_SHORT); - toast.show(); - return true; - }); - ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setOnPreferenceClickListener( - preference -> { - GpodnetPreferences.logout(); - Toast toast = Toast.makeText(activity, R.string.pref_gpodnet_logout_toast, Toast.LENGTH_SHORT); - toast.show(); - updateGpodnetPreferenceScreen(); - return true; - }); - ui.findPreference(PreferenceController.PREF_GPODNET_HOSTNAME).setOnPreferenceClickListener( - preference -> { - GpodnetSetHostnameDialog.createDialog(activity).setOnDismissListener(dialog -> updateGpodnetPreferenceScreen()); - return true; - }); - - ui.findPreference(PreferenceController.PREF_AUTO_FLATTR_PREFS) - .setOnPreferenceClickListener(preference -> { - AutoFlattrPreferenceDialog.newAutoFlattrPreferenceDialog(activity, - new AutoFlattrPreferenceDialog.AutoFlattrPreferenceDialogInterface() { - @Override - public void onCancelled() { - - } - - @Override - public void onConfirmed(boolean autoFlattrEnabled, float autoFlattrValue) { - UserPreferences.setAutoFlattrSettings(autoFlattrEnabled, autoFlattrValue); - checkItemVisibility(); - } - }); - return true; - }); - ui.findPreference(UserPreferences.PREF_IMAGE_CACHE_SIZE).setOnPreferenceChangeListener( - (preference, o) -> { - if (o instanceof String) { - int newValue = Integer.parseInt((String) o) * 1024 * 1024; - if (newValue != UserPreferences.getImageCacheSize()) { - AlertDialog.Builder dialog = new AlertDialog.Builder(ui.getActivity()); - dialog.setTitle(android.R.string.dialog_alert_title); - dialog.setMessage(R.string.pref_restart_required); - dialog.setPositiveButton(android.R.string.ok, null); - dialog.show(); - } - return true; - } - return false; - } - ); - ui.findPreference(PREF_PROXY).setOnPreferenceClickListener(preference -> { - ProxyDialog dialog = new ProxyDialog(ui.getActivity()); - dialog.createDialog().show(); - return true; - }); - ui.findPreference(PREF_KNOWN_ISSUES).setOnPreferenceClickListener(preference -> { - openInBrowser("https://github.com/AntennaPod/AntennaPod/labels/bug"); - return true; - }); - ui.findPreference(PREF_FAQ).setOnPreferenceClickListener(preference -> { - openInBrowser("http://antennapod.org/faq.html"); - return true; - }); - ui.findPreference(PREF_SEND_CRASH_REPORT).setOnPreferenceClickListener(preference -> { - Intent emailIntent = new Intent(Intent.ACTION_SEND); - emailIntent.setType("text/plain"); - emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{"Martin.Fietz@gmail.com"}); - emailIntent.putExtra(Intent.EXTRA_SUBJECT, "AntennaPod Crash Report"); - emailIntent.putExtra(Intent.EXTRA_TEXT, "Please describe what you were doing when the app crashed"); - // the attachment - emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(CrashReportWriter.getFile())); - String intentTitle = ui.getActivity().getString(R.string.send_email); - ui.getActivity().startActivity(Intent.createChooser(emailIntent, intentTitle)); - return true; - }); - //checks whether Google Play Services is installed on the device (condition necessary for Cast support) - ui.findPreference(UserPreferences.PREF_CAST_ENABLED).setOnPreferenceChangeListener((preference, o) -> { - if (o instanceof Boolean && ((Boolean) o)) { - final int googlePlayServicesCheck = GoogleApiAvailability.getInstance() - .isGooglePlayServicesAvailable(ui.getActivity()); - if (googlePlayServicesCheck == ConnectionResult.SUCCESS) { - return true; - } else { - GoogleApiAvailability.getInstance() - .getErrorDialog(ui.getActivity(), googlePlayServicesCheck, 0) - .show(); - return false; - } - } - return true; - }); - buildEpisodeCleanupPreference(); - buildSmartMarkAsPlayedPreference(); - buildAutodownloadSelectedNetworsPreference(); - setSelectedNetworksEnabled(UserPreferences.isEnableAutodownloadWifiFilter()); - } - - private void openInBrowser(String url) { - try { - Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); - ui.getActivity().startActivity(myIntent); - } catch (ActivityNotFoundException e) { - Toast.makeText(ui.getActivity(), R.string.pref_no_browser_found, Toast.LENGTH_LONG).show(); - Log.e(TAG, Log.getStackTraceString(e)); - } - } - - public void onResume() { - checkItemVisibility(); - setUpdateIntervalText(); - setParallelDownloadsText(UserPreferences.getParallelDownloads()); - setEpisodeCacheSizeText(UserPreferences.getEpisodeCacheSize()); - setDataFolderText(); - updateGpodnetPreferenceScreen(); - } - - @SuppressLint("NewApi") - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (resultCode == Activity.RESULT_OK && - requestCode == DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED) { - String dir = data.getStringExtra(DirectoryChooserActivity.RESULT_SELECTED_DIR); - - File path; - if(dir != null) { - path = new File(dir); - } else { - path = ui.getActivity().getExternalFilesDir(null); - } - String message = null; - final Context context= ui.getActivity().getApplicationContext(); - if(!path.exists()) { - message = String.format(context.getString(R.string.folder_does_not_exist_error), dir); - } else if(!path.canRead()) { - message = String.format(context.getString(R.string.folder_not_readable_error), dir); - } else if(!path.canWrite()) { - message = String.format(context.getString(R.string.folder_not_writable_error), dir); - } - - if(message == null) { - Log.d(TAG, "Setting data folder: " + dir); - UserPreferences.setDataFolder(dir); - setDataFolderText(); - } else { - AlertDialog.Builder ab = new AlertDialog.Builder(ui.getActivity()); - ab.setMessage(message); - ab.setPositiveButton(android.R.string.ok, null); - ab.show(); - } - } - } - - - private void updateGpodnetPreferenceScreen() { - final boolean loggedIn = GpodnetPreferences.loggedIn(); - ui.findPreference(PreferenceController.PREF_GPODNET_LOGIN).setEnabled(!loggedIn); - ui.findPreference(PreferenceController.PREF_GPODNET_SETLOGIN_INFORMATION).setEnabled(loggedIn); - ui.findPreference(PreferenceController.PREF_GPODNET_SYNC).setEnabled(loggedIn); - ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setEnabled(loggedIn); - if(loggedIn) { - String format = ui.getActivity().getString(R.string.pref_gpodnet_login_status); - String summary = String.format(format, GpodnetPreferences.getUsername(), - GpodnetPreferences.getDeviceID()); - ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setSummary(Html.fromHtml(summary)); - } else { - ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setSummary(null); - } - ui.findPreference(PreferenceController.PREF_GPODNET_HOSTNAME).setSummary(GpodnetPreferences.getHostname()); - } - - private String[] getUpdateIntervalEntries(final String[] values) { - final Resources res = ui.getActivity().getResources(); - String[] entries = new String[values.length]; - for (int x = 0; x < values.length; x++) { - Integer v = Integer.parseInt(values[x]); - switch (v) { - case 0: - entries[x] = res.getString(R.string.pref_update_interval_hours_manual); - break; - case 1: - entries[x] = v + " " + res.getString(R.string.pref_update_interval_hours_singular); - break; - default: - entries[x] = v + " " + res.getString(R.string.pref_update_interval_hours_plural); - break; - - } - } - return entries; - } - - private void buildEpisodeCleanupPreference() { - final Resources res = ui.getActivity().getResources(); - - ListPreference pref = (ListPreference) ui.findPreference(UserPreferences.PREF_EPISODE_CLEANUP); - String[] values = res.getStringArray( - R.array.episode_cleanup_values); - String[] entries = new String[values.length]; - for (int x = 0; x < values.length; x++) { - int v = Integer.parseInt(values[x]); - if (v == UserPreferences.EPISODE_CLEANUP_QUEUE) { - entries[x] = res.getString(R.string.episode_cleanup_queue_removal); - } else if (v == UserPreferences.EPISODE_CLEANUP_NULL){ - entries[x] = res.getString(R.string.episode_cleanup_never); - } else if (v == 0) { - entries[x] = res.getString(R.string.episode_cleanup_after_listening); - } else { - entries[x] = res.getQuantityString(R.plurals.episode_cleanup_days_after_listening, v, v); - } - } - pref.setEntries(entries); - } - - private void buildSmartMarkAsPlayedPreference() { - final Resources res = ui.getActivity().getResources(); - - ListPreference pref = (ListPreference) ui.findPreference(UserPreferences.PREF_SMART_MARK_AS_PLAYED_SECS); - String[] values = res.getStringArray(R.array.smart_mark_as_played_values); - String[] entries = new String[values.length]; - for (int x = 0; x < values.length; x++) { - if(x == 0) { - entries[x] = res.getString(R.string.pref_smart_mark_as_played_disabled); - } else { - Integer v = Integer.parseInt(values[x]); - if(v < 60) { - entries[x] = res.getQuantityString(R.plurals.time_seconds_quantified, v, v); - } else { - v /= 60; - entries[x] = res.getQuantityString(R.plurals.time_minutes_quantified, v, v); - } - } - } - pref.setEntries(entries); - } - - private void setSelectedNetworksEnabled(boolean b) { - if (selectedNetworks != null) { - for (Preference p : selectedNetworks) { - p.setEnabled(b); - } - } - } - - @SuppressWarnings("deprecation") - private void checkItemVisibility() { - boolean hasFlattrToken = FlattrUtils.hasToken(); - ui.findPreference(PreferenceController.PREF_FLATTR_SETTINGS).setEnabled(FlattrUtils.hasAPICredentials()); - ui.findPreference(PreferenceController.PREF_FLATTR_AUTH).setEnabled(!hasFlattrToken); - ui.findPreference(PreferenceController.PREF_FLATTR_REVOKE).setEnabled(hasFlattrToken); - ui.findPreference(PreferenceController.PREF_AUTO_FLATTR_PREFS).setEnabled(hasFlattrToken); - - boolean autoDownload = UserPreferences.isEnableAutodownload(); - ui.findPreference(UserPreferences.PREF_EPISODE_CACHE_SIZE).setEnabled(autoDownload); - ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_ON_BATTERY).setEnabled(autoDownload); - ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_WIFI_FILTER).setEnabled(autoDownload); - setSelectedNetworksEnabled(autoDownload && UserPreferences.isEnableAutodownloadWifiFilter()); - - ui.findPreference(PREF_SEND_CRASH_REPORT).setEnabled(CrashReportWriter.getFile().exists()); - - if (Build.VERSION.SDK_INT >= 16) { - ui.findPreference(UserPreferences.PREF_SONIC).setEnabled(true); - } else { - Preference prefSonic = ui.findPreference(UserPreferences.PREF_SONIC); - prefSonic.setSummary("[Android 4.1+]\n" + prefSonic.getSummary()); - } - } - - private void setUpdateIntervalText() { - Context context = ui.getActivity().getApplicationContext(); - String val; - long interval = UserPreferences.getUpdateInterval(); - if(interval > 0) { - int hours = (int) TimeUnit.MILLISECONDS.toHours(interval); - String hoursStr = context.getResources().getQuantityString(R.plurals.time_hours_quantified, hours, hours); - val = String.format(context.getString(R.string.pref_autoUpdateIntervallOrTime_every), hoursStr); - } else { - int[] timeOfDay = UserPreferences.getUpdateTimeOfDay(); - if(timeOfDay.length == 2) { - Calendar cal = new GregorianCalendar(); - cal.set(Calendar.HOUR_OF_DAY, timeOfDay[0]); - cal.set(Calendar.MINUTE, timeOfDay[1]); - String timeOfDayStr = DateFormat.getTimeFormat(context).format(cal.getTime()); - val = String.format(context.getString(R.string.pref_autoUpdateIntervallOrTime_at), - timeOfDayStr); - } else { - val = context.getString(R.string.pref_smart_mark_as_played_disabled); - } - } - String summary = context.getString(R.string.pref_autoUpdateIntervallOrTime_sum) + "\n" - + String.format(context.getString(R.string.pref_current_value), val); - ui.findPreference(UserPreferences.PREF_UPDATE_INTERVAL).setSummary(summary); - } - - private void setParallelDownloadsText(int downloads) { - final Resources res = ui.getActivity().getResources(); - - String s = Integer.toString(downloads) - + res.getString(R.string.parallel_downloads_suffix); - ui.findPreference(UserPreferences.PREF_PARALLEL_DOWNLOADS).setSummary(s); - } - - private void setEpisodeCacheSizeText(int cacheSize) { - final Resources res = ui.getActivity().getResources(); - - String s; - if (cacheSize == res.getInteger( - R.integer.episode_cache_size_unlimited)) { - s = res.getString(R.string.pref_episode_cache_unlimited); - } else { - s = Integer.toString(cacheSize) - + res.getString(R.string.episodes_suffix); - } - ui.findPreference(UserPreferences.PREF_EPISODE_CACHE_SIZE).setSummary(s); - } - - private void setDataFolderText() { - File f = UserPreferences.getDataFolder(null); - if (f != null) { - ui.findPreference(PreferenceController.PREF_CHOOSE_DATA_DIR) - .setSummary(f.getAbsolutePath()); - } - } - - private void buildAutodownloadSelectedNetworsPreference() { - final Activity activity = ui.getActivity(); - - if (selectedNetworks != null) { - clearAutodownloadSelectedNetworsPreference(); - } - // get configured networks - WifiManager wifiservice = (WifiManager) activity.getSystemService(Context.WIFI_SERVICE); - List networks = wifiservice.getConfiguredNetworks(); - - if (networks != null) { - selectedNetworks = new CheckBoxPreference[networks.size()]; - List prefValues = Arrays.asList(UserPreferences - .getAutodownloadSelectedNetworks()); - PreferenceScreen prefScreen = (PreferenceScreen) ui.findPreference(PreferenceController.AUTO_DL_PREF_SCREEN); - Preference.OnPreferenceClickListener clickListener = preference -> { - if (preference instanceof CheckBoxPreference) { - String key = preference.getKey(); - List prefValuesList = new ArrayList<>( - Arrays.asList(UserPreferences - .getAutodownloadSelectedNetworks()) - ); - boolean newValue = ((CheckBoxPreference) preference) - .isChecked(); - Log.d(TAG, "Selected network " + key + ". New state: " + newValue); - - int index = prefValuesList.indexOf(key); - if (index >= 0 && !newValue) { - // remove network - prefValuesList.remove(index); - } else if (index < 0 && newValue) { - prefValuesList.add(key); - } - - UserPreferences.setAutodownloadSelectedNetworks( - prefValuesList.toArray(new String[prefValuesList.size()]) - ); - return true; - } else { - return false; - } - }; - // create preference for each known network. attach listener and set - // value - for (int i = 0; i < networks.size(); i++) { - WifiConfiguration config = networks.get(i); - - CheckBoxPreference pref = new CheckBoxPreference(activity); - String key = Integer.toString(config.networkId); - pref.setTitle(config.SSID); - pref.setKey(key); - pref.setOnPreferenceClickListener(clickListener); - pref.setPersistent(false); - pref.setChecked(prefValues.contains(key)); - selectedNetworks[i] = pref; - prefScreen.addPreference(pref); - } - } else { - Log.e(TAG, "Couldn't get list of configure Wi-Fi networks"); - } - } - - private void clearAutodownloadSelectedNetworsPreference() { - if (selectedNetworks != null) { - PreferenceScreen prefScreen = (PreferenceScreen) ui.findPreference(PreferenceController.AUTO_DL_PREF_SCREEN); - - for (CheckBoxPreference network : selectedNetworks) { - if (network != null) { - prefScreen.removePreference(network); - } - } - } - } - - private void showDrawerPreferencesDialog() { - final Context context = ui.getActivity(); - final List hiddenDrawerItems = UserPreferences.getHiddenDrawerItems(); - final String[] navTitles = context.getResources().getStringArray(R.array.nav_drawer_titles); - final String[] NAV_DRAWER_TAGS = MainActivity.NAV_DRAWER_TAGS; - boolean[] checked = new boolean[MainActivity.NAV_DRAWER_TAGS.length]; - for(int i=0; i < NAV_DRAWER_TAGS.length; i++) { - String tag = NAV_DRAWER_TAGS[i]; - if(!hiddenDrawerItems.contains(tag)) { - checked[i] = true; - } - } - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(R.string.drawer_preferences); - builder.setMultiChoiceItems(navTitles, checked, (dialog, which, isChecked) -> { - if (isChecked) { - hiddenDrawerItems.remove(NAV_DRAWER_TAGS[which]); - } else { - hiddenDrawerItems.add(NAV_DRAWER_TAGS[which]); - } - }); - builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> { - UserPreferences.setHiddenDrawerItems(hiddenDrawerItems); - }); - builder.setNegativeButton(R.string.cancel_label, null); - builder.create().show(); - } - - private void showNotificationButtonsDialog() { - final Context context = ui.getActivity(); - final List preferredButtons = UserPreferences.getCompactNotificationButtons(); - final String[] allButtonNames = context.getResources().getStringArray( - R.array.compact_notification_buttons_options); - boolean[] checked = new boolean[allButtonNames.length]; // booleans default to false in java - - for(int i=0; i < checked.length; i++) { - if(preferredButtons.contains(i)) { - checked[i] = true; - } - } - - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(String.format(context.getResources().getString( - R.string.pref_compact_notification_buttons_dialog_title), 2)); - builder.setMultiChoiceItems(allButtonNames, checked, (dialog, which, isChecked) -> { - checked[which] = isChecked; - - if (isChecked) { - if (preferredButtons.size() < 2) { - preferredButtons.add(which); - } else { - // Only allow a maximum of two selections. This is because the notification - // on the lock screen can only display 3 buttons, and the play/pause button - // is always included. - checked[which] = false; - ListView selectionView = ((AlertDialog) dialog).getListView(); - selectionView.setItemChecked(which, false); - Snackbar.make( - selectionView, - String.format(context.getResources().getString( - R.string.pref_compact_notification_buttons_dialog_error), 2), - Snackbar.LENGTH_SHORT).show(); - } - } else { - preferredButtons.remove((Integer) which); - } - }); - builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> { - UserPreferences.setCompactNotificationButtons(preferredButtons); - }); - builder.setNegativeButton(R.string.cancel_label, null); - builder.create().show(); - } - - // CHOOSE DATA FOLDER - - private void requestPermission() { - ActivityCompat.requestPermissions(ui.getActivity(), EXTERNAL_STORAGE_PERMISSIONS, - PERMISSION_REQUEST_EXTERNAL_STORAGE); - } - - private void openDirectoryChooser() { - Activity activity = ui.getActivity(); - Intent intent = new Intent(activity, DirectoryChooserActivity.class); - activity.startActivityForResult(intent, DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED); - } - - private void showChooseDataFolderDialog() { - Context context = ui.getActivity(); - File dataFolder = UserPreferences.getDataFolder(null); - if(dataFolder == null) { - new MaterialDialog.Builder(ui.getActivity()) - .title(R.string.error_label) - .content(R.string.external_storage_error_msg) - .neutralText(android.R.string.ok) - .show(); - return; - } - String dataFolderPath = dataFolder.getAbsolutePath(); - int selectedIndex = -1; - File[] mediaDirs = ContextCompat.getExternalFilesDirs(context, null); - List folders = new ArrayList<>(mediaDirs.length); - List choices = new ArrayList<>(mediaDirs.length); - for(int i=0; i < mediaDirs.length; i++) { - File dir = mediaDirs[i]; - if(dir == null || !dir.exists() || !dir.canRead() || !dir.canWrite()) { - continue; - } - String path = mediaDirs[i].getAbsolutePath(); - folders.add(path); - if(dataFolderPath.equals(path)) { - selectedIndex = i; - } - int index = path.indexOf("Android"); - String choice; - if(index >= 0) { - choice = path.substring(0, index); - } else { - choice = path; - } - long bytes = StorageUtils.getFreeSpaceAvailable(path); - String freeSpace = String.format(context.getString(R.string.free_space_label), - Converter.byteToString(bytes)); - choices.add(Html.fromHtml("" + choice - + " [" + freeSpace + "]" + "")); - } - if(choices.size() == 0) { - new MaterialDialog.Builder(ui.getActivity()) - .title(R.string.error_label) - .content(R.string.external_storage_error_msg) - .neutralText(android.R.string.ok) - .show(); - return; - } - MaterialDialog dialog = new MaterialDialog.Builder(ui.getActivity()) - .title(R.string.choose_data_directory) - .content(R.string.choose_data_directory_message) - .items(choices.toArray(new CharSequence[choices.size()])) - .itemsCallbackSingleChoice(selectedIndex, (dialog1, itemView, which, text) -> { - String folder = folders.get(which); - Log.d(TAG, "data folder: " + folder); - UserPreferences.setDataFolder(folder); - setDataFolderText(); - return true; - }) - .negativeText(R.string.cancel_label) - .cancelable(true) - .build(); - dialog.show(); - } - - // UPDATE TIME/INTERVAL DIALOG - - private void showUpdateIntervalTimePreferencesDialog() { - final Context context = ui.getActivity(); - - MaterialDialog.Builder builder = new MaterialDialog.Builder(context); - builder.title(R.string.pref_autoUpdateIntervallOrTime_title); - builder.content(R.string.pref_autoUpdateIntervallOrTime_message); - builder.positiveText(R.string.pref_autoUpdateIntervallOrTime_Interval); - builder.negativeText(R.string.pref_autoUpdateIntervallOrTime_TimeOfDay); - builder.neutralText(R.string.pref_autoUpdateIntervallOrTime_Disable); - builder.onPositive((dialog, which) -> { - AlertDialog.Builder builder1 = new AlertDialog.Builder(context); - builder1.setTitle(context.getString(R.string.pref_autoUpdateIntervallOrTime_Interval)); - final String[] values = context.getResources().getStringArray(R.array.update_intervall_values); - final String[] entries = getUpdateIntervalEntries(values); - long currInterval = UserPreferences.getUpdateInterval(); - int checkedItem = -1; - if(currInterval > 0) { - String currIntervalStr = String.valueOf(TimeUnit.MILLISECONDS.toHours(currInterval)); - checkedItem = ArrayUtils.indexOf(values, currIntervalStr); - } - builder1.setSingleChoiceItems(entries, checkedItem, (dialog1, which1) -> { - int hours = Integer.parseInt(values[which1]); - UserPreferences.setUpdateInterval(hours); - dialog1.dismiss(); - setUpdateIntervalText(); - }); - builder1.setNegativeButton(context.getString(R.string.cancel_label), null); - builder1.show(); - }); - builder.onNegative((dialog, which) -> { - int hourOfDay = 7, minute = 0; - int[] updateTime = UserPreferences.getUpdateTimeOfDay(); - if (updateTime.length == 2) { - hourOfDay = updateTime[0]; - minute = updateTime[1]; - } - TimePickerDialog timePickerDialog = new TimePickerDialog(context, - (view, selectedHourOfDay, selectedMinute) -> { - if (view.getTag() == null) { // onTimeSet() may get called twice! - view.setTag("TAGGED"); - UserPreferences.setUpdateTimeOfDay(selectedHourOfDay, selectedMinute); - setUpdateIntervalText(); - } - }, hourOfDay, minute, DateFormat.is24HourFormat(context)); - timePickerDialog.setTitle(context.getString(R.string.pref_autoUpdateIntervallOrTime_TimeOfDay)); - timePickerDialog.show(); - }); - builder.onNeutral((dialog, which) -> { - UserPreferences.setUpdateInterval(0); - setUpdateIntervalText(); - }); - builder.show(); - } - - - public interface PreferenceUI { - - /** - * Finds a preference based on its key. - */ - Preference findPreference(CharSequence key); - - Activity getActivity(); - } -} diff --git a/app/src/play/java/de/danoeh/antennapod/preferences/PreferenceControllerHelper.java b/app/src/play/java/de/danoeh/antennapod/preferences/PreferenceControllerHelper.java new file mode 100644 index 000000000..173e47890 --- /dev/null +++ b/app/src/play/java/de/danoeh/antennapod/preferences/PreferenceControllerHelper.java @@ -0,0 +1,31 @@ +package de.danoeh.antennapod.preferences; + +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.GoogleApiAvailability; + +import de.danoeh.antennapod.core.preferences.UserPreferences; + +/** + * Implements functions from PreferenceController that are flavor dependent. + */ +public class PreferenceControllerHelper { + + static void setupFlavoredUI(PreferenceController.PreferenceUI ui) { + //checks whether Google Play Services is installed on the device (condition necessary for Cast support) + ui.findPreference(UserPreferences.PREF_CAST_ENABLED).setOnPreferenceChangeListener((preference, o) -> { + if (o instanceof Boolean && ((Boolean) o)) { + final int googlePlayServicesCheck = GoogleApiAvailability.getInstance() + .isGooglePlayServicesAvailable(ui.getActivity()); + if (googlePlayServicesCheck == ConnectionResult.SUCCESS) { + return true; + } else { + GoogleApiAvailability.getInstance() + .getErrorDialog(ui.getActivity(), googlePlayServicesCheck, 0) + .show(); + return false; + } + } + return true; + }); + } +} -- cgit v1.2.3