Java tutorial
/* * Copyright (C) 2015 SpiritCroc * Email: spiritcroc@gmail.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.spiritcroc.modular_remote; import android.app.DialogFragment; import android.app.Fragment; import android.app.FragmentManager; import android.app.KeyguardManager; import android.appwidget.AppWidgetHost; import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.media.AudioManager; import android.os.Build; import android.os.Handler; import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.v4.view.PagerTabStrip; import android.support.v4.view.ViewPager; import android.os.Bundle; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.ActionMode; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.widget.Toast; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import de.spiritcroc.modular_remote.dialogs.AboutDialog; import de.spiritcroc.modular_remote.dialogs.AddFragmentDialog; import de.spiritcroc.modular_remote.dialogs.GreetingDialog; import de.spiritcroc.modular_remote.dialogs.OverlapWarningDialog; import de.spiritcroc.modular_remote.dialogs.SelectConnectionDialog; import de.spiritcroc.modular_remote.dialogs.SelectFragmentsDialog; import de.spiritcroc.modular_remote.dialogs.SetupGridSizeDialog; import de.spiritcroc.modular_remote.modules.Container; import de.spiritcroc.modular_remote.modules.ModuleFragment; import de.spiritcroc.modular_remote.modules.PageContainerFragment; import de.spiritcroc.modular_remote.modules.WidgetContainerFragment; public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener { private static final String LOG_TAG = MainActivity.class.getSimpleName(); private static final boolean DEBUG = false; // For launcher shortcut intents public static final String EXTRA_SELECT_PAGE_ID = "de.spiritcroc.modular_remote.extra.SELECT_PAGE_ID"; private static final String EXTRA_RESTARTED_FROM_EDIT_MODE = "de.spiritcroc.modular_remote.extra.RESTARTED_FROM_EDIT_MODE"; // Force orientation when using launcher shortcuts public static final String EXTRA_FORCE_ORIENTATION = "de.spiritcroc.modular_remote.extra.FORCE_ORIENTATION"; public static final int FORCE_ORIENTATION_PORTRAIT = 1; public static final int FORCE_ORIENTATION_LANDSCAPE = 2; private CustomFragmentPagerAdapter fragmentPagerAdapter; private static CustomViewPager viewPager; private PagerTabStrip pagerTabStrip; private SharedPreferences sharedPreferences; private TcpConnectionManager tcpConnectionManager; private ArrayList<PageContainerFragment> pages; private static final String separator = Util.RK_CONTAINER_BRACKET + "0" + Util.RK_CONTAINER_BRACKET; private boolean neverDestroyPages, fullscreen, hideNavigationBar, hideActionBar; private View decorView; private Handler hideSystemUIHandler = new Handler(); private AppWidgetManager appWidgetManager; private AppWidgetHost appWidgetHost; private Container addWidgetContainer; private DialogFragment addWidgetListener; private int previousRingerMode; private boolean changedRingerMode = false; private int volumeButtonSettingsShortcutCount = 0; private Handler resetVolumeButtonSettingsShortcutHandler = new Handler(); private MenuItem editModeMenuItem, connectionMgrMenuItem; private boolean discardSavedInstance = false; private int forceOrientation = -1; private ActionMode actionMode; private boolean editModeContainerDrag = true;// If false: editModeContainerScroll private Toast editModeContainerDragMoveToast = null; private ActionMode.Callback actionModeCallback = new ActionMode.Callback() { @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { mode.getMenuInflater().inflate(R.menu.menu_main_edit, menu); for (int i = 0; i < pages.size(); i++) { pages.get(i).onStartDragMode(); } editModeContainerDrag = true; MenuItem editModeItem = menu.findItem(R.id.action_container_edit_mode); editModeItem.setTitle(R.string.action_container_edit_mode_scroll); return true; } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.action_fragment_settings: new SelectFragmentsDialog().setPage(pages.get(viewPager.getCurrentItem())) .show(getFragmentManager(), "SelectFragmentDialog"); return true; case R.id.action_add_fragment: new AddFragmentDialog().setPage(pages.get(viewPager.getCurrentItem())).show(getFragmentManager(), "AddFragmentDialog"); return true; case R.id.action_container_edit_mode: cancelEditContainerModeToast(); if (editModeContainerDrag) { editModeContainerDrag = false; item.setTitle(R.string.action_container_edit_mode_drag); item.setIcon(R.drawable.ic_action_container_drag_24dp); editModeContainerDragMoveToast = Toast.makeText(MainActivity.this, R.string.toast_container_edit_scroll, Toast.LENGTH_SHORT); editModeContainerDragMoveToast.show(); } else { editModeContainerDrag = true; item.setTitle(R.string.action_container_edit_mode_scroll); item.setIcon(R.drawable.ic_action_container_scroll_24dp); editModeContainerDragMoveToast = Toast.makeText(MainActivity.this, R.string.toast_container_edit_drag, Toast.LENGTH_SHORT); editModeContainerDragMoveToast.show(); } for (int i = 0; i < pages.size(); i++) { pages.get(i).setContainerDragEnabled(editModeContainerDrag); } return true; default: return false; } } @Override public void onDestroyActionMode(ActionMode mode) { actionMode = null; for (int i = 0; i < pages.size(); i++) { pages.get(i).onStopDragMode(); } for (int i = 0; i < pages.size(); i++) { if (Util.hasContainerOverlappingFragments(pages.get(i))) { new OverlapWarningDialog().setCallback(MainActivity.this).show(getFragmentManager(), "OverlapWarningDialog"); return; } } cancelEditContainerModeToast(); exitEditMode(); } }; public void enterEditMode() { actionMode = startActionMode(actionModeCallback); } public void exitEditMode() { saveSettings(); } //constants for AppWidgetHost: private static final int APPWIDGET_HOST_ID = 1024; private static final int REQUEST_PICK_APPWIDGET = 9; private static final int REQUEST_CREATE_APPWIDGET = 5; private static int shortcutPage = -1;//-1 == no shortcut, change if launched from shortcut @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setTitle(R.string.title_activity_main); Util.init(this); sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); pages = new ArrayList<>(); String savedFragments = sharedPreferences.getString(getSavedFragmentsKey(), ""); if (DEBUG) Log.v(LOG_TAG, "savedFragments: " + savedFragments); pagerTabStrip = (PagerTabStrip) findViewById(R.id.pager_tab_strip); viewPager = (CustomViewPager) findViewById(R.id.view_pager); forceOrientation = getIntent().getIntExtra(EXTRA_FORCE_ORIENTATION, -1); restoreContentFromRecreationKey(savedFragments); pages.get(0).setMenuEnabled(true); fragmentPagerAdapter = new CustomFragmentPagerAdapter(this, getFragmentManager()); viewPager.setAdapter(fragmentPagerAdapter); viewPager.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { boolean newY = Util.newY(viewPager); boolean newX = Util.newX(viewPager); if (newY || newX) { viewPager.post(new Runnable() { @Override public void run() { resizeContent(); } }); } } }); fullscreen = sharedPreferences.getBoolean(Preferences.FULLSCREEN, false); hideNavigationBar = sharedPreferences.getBoolean(Preferences.HIDE_NAVIGATION_BAR, false); hideActionBar = sharedPreferences.getBoolean(Preferences.HIDE_ACTION_BAR, false); decorView = getWindow().getDecorView(); decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() { @Override public void onSystemUiVisibilityChange(int visibility) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { boolean visible = (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0; if (visible) { delayedHide(); } } } }); appWidgetManager = AppWidgetManager.getInstance(this); appWidgetHost = new AppWidgetHost(this, APPWIDGET_HOST_ID); tcpConnectionManager = TcpConnectionManager.getInstance(getApplicationContext()); tcpConnectionManager.recreateConnectionsFromRecreationKey( sharedPreferences.getString(Preferences.SAVED_CONNECTIONS, "")); if (sharedPreferences.getInt(Preferences.SEEN_GREETING_VERSION, 0) < GreetingDialog.VERSION) { new GreetingDialog().show(getFragmentManager(), "GreetingDialog"); } else if (SetupGridSizeDialog.shouldShow(sharedPreferences)) { new SetupGridSizeDialog().show(getFragmentManager(), "SetupGridSizeDialog"); } getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); if (DEBUG) { getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { @Override public void onBackStackChanged() { Log.v(LOG_TAG, "Back stack count: " + getFragmentManager().getBackStackEntryCount()); } }); } if (getIntent().getBooleanExtra(EXTRA_RESTARTED_FROM_EDIT_MODE, false)) { enterEditMode(); } } private Runnable hideSystemUIRunnable = new Runnable() { @Override public void run() { hideSystemUI(); } }; private void delayedHide() { hideSystemUIHandler.removeCallbacks(hideSystemUIRunnable); hideSystemUIHandler.postDelayed(hideSystemUIRunnable, Util.getPreferenceInt(sharedPreferences, Preferences.SYSTEM_UI_TIMEOUT, 3) * 1000); } public void hideSystemUI() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && fullscreen || hideNavigationBar) { decorView.setSystemUiVisibility(getHideSystemUIFlags()); } } private void resizeContent() { for (int i = 0; i < pages.size(); i++) { pages.get(i).resize(true); } } private int getHideSystemUIFlags() { int flags; if (Build.VERSION.SDK_INT >= 19) { flags = View.SYSTEM_UI_FLAG_IMMERSIVE; } else { flags = 0; } if (Build.VERSION.SDK_INT >= 16) { if (fullscreen) { flags |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_FULLSCREEN; } if (hideNavigationBar) { flags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; } if (hideActionBar) { flags |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE; } } return flags; } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (hasFocus) { hideSystemUI(); } else { hideSystemUIHandler.removeCallbacks(hideSystemUIRunnable); } } @Override protected void onPause() { super.onPause(); viewPager.removeOnPageChangeListener(this); saveConnections(); appWidgetHost.stopListening(); if (changedRingerMode) { changedRingerMode = false; AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); audioManager.setRingerMode(previousRingerMode); } } @Override protected void onResume() { super.onResume(); appWidgetHost.startListening(); tcpConnectionManager.refreshConnections(); viewPager.addOnPageChangeListener(this); onPageSelected(viewPager.getCurrentItem()); int tmp = Util.getPreferenceInt(sharedPreferences, Preferences.OFFSCREEN_PAGE_LIMIT, 2); if (tmp < 0) { neverDestroyPages = true; viewPager.setOffscreenPageLimit(pages.size()); } else { neverDestroyPages = false; viewPager.setOffscreenPageLimit(tmp); } fullscreen = sharedPreferences.getBoolean(Preferences.FULLSCREEN, false); hideNavigationBar = sharedPreferences.getBoolean(Preferences.HIDE_NAVIGATION_BAR, false); hideActionBar = sharedPreferences.getBoolean(Preferences.HIDE_ACTION_BAR, false); int pagerTabStripVisibility = sharedPreferences.getBoolean(Preferences.HIDE_PAGER_TAB_STRIP, false) ? View.GONE : View.VISIBLE; if (pagerTabStrip.getVisibility() != pagerTabStripVisibility) { pagerTabStrip.setVisibility(pagerTabStripVisibility); } String ringerMode = sharedPreferences.getString(Preferences.CHANGE_RINGER_MODE, getString(R.string.pref_ringer_mode_keep_value)); AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); previousRingerMode = audioManager.getRingerMode(); if (getString(R.string.pref_ringer_mode_mute_value).equals(ringerMode)) { audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT); changedRingerMode = true; } else if (getString(R.string.pref_ringer_mode_vibrate_value).equals(ringerMode)) { audioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE); changedRingerMode = true; } else if (getString(R.string.pref_ringer_mode_vibrate_if_not_muted_value).equals(ringerMode) && previousRingerMode != AudioManager.RINGER_MODE_SILENT) { audioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE); changedRingerMode = true; } if (forceOrientation == FORCE_ORIENTATION_PORTRAIT) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } else if (forceOrientation == FORCE_ORIENTATION_LANDSCAPE) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } else { String orientation = sharedPreferences.getString(Preferences.ORIENTATION, Preferences.ORIENTATION_SHARE_LAYOUT); if (Preferences.ORIENTATION_PORTRAIT_ONLY.equals(orientation)) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } else if (Preferences.ORIENTATION_LANDSCAPE_ONLY.equals(orientation)) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } else { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER); } } resizeContent(); setLockedModeVisibilities(); } @Override public boolean onPrepareOptionsMenu(Menu menu) { menu.clear(); getMenuInflater().inflate(R.menu.menu_main, menu); editModeMenuItem = menu.findItem(R.id.action_edit_page_content); connectionMgrMenuItem = menu.findItem(R.id.action_connection_manager); setLockedModeVisibilities(); return super.onPrepareOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_settings: startActivity(new Intent(this, SettingsActivity.class).addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)); return true; case R.id.action_about: new AboutDialog().show(getFragmentManager(), "AboutDialog"); return true; case R.id.action_edit_page_content: enterEditMode(); return true; case R.id.action_connection_manager: new SelectConnectionDialog().show(getFragmentManager(), "SelectConnectionDialog"); return true; default: return super.onOptionsItemSelected(item); } } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); if (discardSavedInstance) { outState.clear(); } } @Override public void onConfigurationChanged(Configuration configuration) { super.onConfigurationChanged(configuration); if (!Preferences.ORIENTATION_SHARE_LAYOUT.equals( sharedPreferences.getString(Preferences.ORIENTATION, Preferences.ORIENTATION_SHARE_LAYOUT))) { // Restart for new setup; don't recreate old fragments discardSavedInstance = true; restart(null); } } // Hardware key listener @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (volumeButtonSettingsShortcutCount) { case 0: case 1: case 4: case 6: resetVolumeButtonSettingsShortcutHandler.removeCallbacks(resetVolumeButtonSettingsShortcut); if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { volumeButtonSettingsShortcutCount++; resetVolumeButtonSettingsShortcutHandler.postDelayed(resetVolumeButtonSettingsShortcut, 1000); } else { volumeButtonSettingsShortcutCount = 0; } break; case 2: case 3: case 5: resetVolumeButtonSettingsShortcutHandler.removeCallbacks(resetVolumeButtonSettingsShortcut); if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { volumeButtonSettingsShortcutCount++; resetVolumeButtonSettingsShortcutHandler.postDelayed(resetVolumeButtonSettingsShortcut, 1000); } else { volumeButtonSettingsShortcutCount = 0; } break; case 7: resetVolumeButtonSettingsShortcutHandler.removeCallbacks(resetVolumeButtonSettingsShortcut); if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { Toast.makeText(getApplicationContext(), R.string.toast_volume_button_settings_shortcut, Toast.LENGTH_LONG).show(); startActivity( new Intent(this, SettingsActivity.class).addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)); } volumeButtonSettingsShortcutCount = 0; break; default: volumeButtonSettingsShortcutCount = 0; break; } return pages.get(viewPager.getCurrentItem()).onKeyDown(keyCode) || super.onKeyDown(keyCode, event); } @Override public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_VOLUME_UP: case KeyEvent.KEYCODE_VOLUME_DOWN: return pages.get(viewPager.getCurrentItem()).onKeyUp(keyCode) || super.onKeyDown(keyCode, event); } return super.onKeyUp(keyCode, event); } public void addPage(PageContainerFragment fragment) { if (neverDestroyPages) { viewPager.setOffscreenPageLimit(pages.size()); } if (actionMode != null) { fragment.onStartDragMode(); } pages.add(fragment); notifyDataSetChanged(); viewPager.setCurrentItem(pages.size() - 1, true); } public void notifyDataSetChanged() { if (fragmentPagerAdapter != null) { fragmentPagerAdapter.notifyDataSetChanged(); } } // For appropriate page display after page removal, a complete activity restart is required // (recreate() is not enough) public void removePage(PageContainerFragment page, boolean callOnRemove) { int pos = pages.indexOf(page); if (pos != 0) { pos--; } pages.remove(page); fragmentPagerAdapter.notifyDataSetChanged(); if (callOnRemove) { page.onRemove(); } restart(pos); } private void restart(Intent intent) { if (intent == null) { intent = getIntent(); } finish(); overridePendingTransition(0, 0); startActivity(intent); overridePendingTransition(0, 0); } private void restart(int selectPagePos) { Intent intent = getIntent(); if (selectPagePos >= 0 && pages.size() > selectPagePos) { intent.putExtra(EXTRA_SELECT_PAGE_ID, pages.get(selectPagePos).getPageId()); // Don't toast in case the page can not be selected intent.putExtra(EXTRA_RESTARTED_FROM_EDIT_MODE, true); } saveFragments(); restart(intent); } public void scrollToPage(PageContainerFragment page) { int pos = pages.indexOf(page); if (pos >= 0 && pos != viewPager.getCurrentItem()) { viewPager.setCurrentItem(pos, true); } } public void saveSettings() { saveFragments(); saveConnections(); } private String getSavedFragmentsKey() { String orientationPref = sharedPreferences.getString(Preferences.ORIENTATION, Preferences.ORIENTATION_SHARE_LAYOUT); boolean landscape = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE && !Preferences.ORIENTATION_SHARE_LAYOUT.equals(orientationPref); if (landscape) { return Preferences.SAVED_FRAGMENTS_LANDSCAPE; } else { return Preferences.SAVED_FRAGMENTS; } } private void saveFragments() { String key = ModuleFragment.ROOT + separator + Util.RECREATION_KEY_VERSION + separator; for (int i = 0; i < pages.size(); i++) { ModuleFragment fragment = pages.get(i); key += fragment.getRecreationKey() + separator; } if (DEBUG) Log.v(LOG_TAG, "saveFragments: " + key); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString(getSavedFragmentsKey(), key); editor.apply(); } private void saveConnections() { String key = tcpConnectionManager.getConnectionRecreationKey(); if (DEBUG) Log.v(LOG_TAG, "saveConnections: " + key); sharedPreferences.edit().putString(Preferences.SAVED_CONNECTIONS, key).apply(); } private void restoreContentFromRecreationKey(String key) { String[] args = Util.split(key, separator, 0); int recreationVersion; try { recreationVersion = Integer.parseInt(args[1]); if (DEBUG) Log.v(LOG_TAG, "RecreationVersion: " + recreationVersion); } catch (Exception e) { Log.w(LOG_TAG, "Got exception while trying to get recreationVersion for key " + key); Log.w(LOG_TAG, "Got exception: " + e); // Try using current version instead recreationVersion = Util.RECREATION_KEY_VERSION; } for (int i = 2; i < args.length; i++) { String[] subArgs = Util.split(args[i], Util.RK_ATTRIBUTE_SEPARATOR, 1); if (ModuleFragment.PAGE_CONTAINER_FRAGMENT.equals(subArgs[0])) { addPage(PageContainerFragment.recoverFromRecreationKey(args[i])); } else { Log.w(LOG_TAG, "restoreContentFromRecreationKey:" + " Only allowed to add PageContainers to MainActivity, you tried to add: " + subArgs[0]); } } if (pages.size() == 0) {// Not allowed to have no fragments addPage(PageContainerFragment.newInstance(getString(R.string.page_name_default), new Display.StaticTextSettings(getString(R.string.app_name)), false, null, null, null, null)); } // Select page if shortcut used and page is on current orientation: Intent intent = getIntent(); long pageId = intent.getLongExtra(EXTRA_SELECT_PAGE_ID, -1); boolean landscape = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; if (pageId != -1 && (forceOrientation == -1 || (landscape && forceOrientation == FORCE_ORIENTATION_LANDSCAPE) || (!landscape && forceOrientation == FORCE_ORIENTATION_PORTRAIT))) { for (int i = 0; i < pages.size(); i++) { if (pages.get(i).getPageId() == pageId) { shortcutPage = i; } } if (shortcutPage == -1) {// Could not find page if (!intent.getBooleanExtra(EXTRA_RESTARTED_FROM_EDIT_MODE, false)) Toast.makeText(this, R.string.error_page_not_available, Toast.LENGTH_LONG).show(); } } } public static String[] getPageNamesFromRecreationKey(String key, ArrayList<Long> pageIDs) { ArrayList<String> pageNames = new ArrayList<>(); String[] args = Util.split(key, separator, 0); for (int i = 1; i < args.length; i++) { String[] subArgs = Util.split(args[i], Util.RK_ATTRIBUTE_SEPARATOR, 1); if (ModuleFragment.PAGE_CONTAINER_FRAGMENT.equals(subArgs[0])) { pageNames.add(PageContainerFragment.getPageNameFromRecreationKey(args[i])); pageIDs.add(PageContainerFragment.getPageIdFromRecreationKey(args[i])); } else { Log.e(LOG_TAG, "getPageNamesFromRecreationKey: Only allowed to add " + "PageContainers to MainActivity, you tried to add: " + subArgs[0]); } } return pageNames.toArray(new String[pageNames.size()]); } public static class CustomFragmentPagerAdapter extends android.support.v13.app.FragmentPagerAdapter { MainActivity activity; public CustomFragmentPagerAdapter(MainActivity activity, FragmentManager fragmentManager) { super(fragmentManager); this.activity = activity; } @Override public int getCount() { return activity.pages.size(); } @Override public Fragment getItem(int position) { return activity.pages.get(position); } @Override public CharSequence getPageTitle(int position) { return activity.pages.get(position).getName(); } @Override public void finishUpdate(ViewGroup container) { super.finishUpdate(container); if (shortcutPage >= 0 && shortcutPage < getCount()) { viewPager.setCurrentItem(shortcutPage); shortcutPage = -1;//use shortcut only once } } } public void addWidget(Container container) { addWidgetContainer = container; int appWidgetId = appWidgetHost.allocateAppWidgetId(); Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK) .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); startActivityForResult(pickIntent, MainActivity.REQUEST_PICK_APPWIDGET); } public void setAddWidgetListener(DialogFragment addWidgetListener) { this.addWidgetListener = addWidgetListener; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { if (requestCode == REQUEST_PICK_APPWIDGET) { configureWidget(data); } else if (requestCode == REQUEST_CREATE_APPWIDGET) { createWidgetContainerFragment(data); } } else if (resultCode == RESULT_CANCELED && data != null) { int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); if (appWidgetId != -1) { appWidgetHost.deleteAppWidgetId(appWidgetId); } } } private void configureWidget(Intent data) { Bundle extras = data.getExtras(); int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); AppWidgetProviderInfo appWidgetProviderInfo = appWidgetManager.getAppWidgetInfo(appWidgetId); if (appWidgetProviderInfo.configure != null) { Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE); intent.setComponent(appWidgetProviderInfo.configure); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); startActivityForResult(intent, REQUEST_CREATE_APPWIDGET); } else { createWidgetContainerFragment(data); } } private void createWidgetContainerFragment(Intent data) { Bundle extras = data.getExtras(); int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); if (addWidgetContainer != null) { addWidgetContainer.addFragment(WidgetContainerFragment.newInstance(appWidgetId), false); if (addWidgetListener != null) { addWidgetListener.dismiss(); addWidgetListener = null; } } } public View createWidget(int appWidgetId) { AppWidgetProviderInfo appWidgetProviderInfo = appWidgetManager.getAppWidgetInfo(appWidgetId); AppWidgetHostView hostView = appWidgetHost.createView(this, appWidgetId, appWidgetProviderInfo); hostView.setAppWidget(appWidgetId, appWidgetProviderInfo); return hostView; } public void removeWidget(int appWidgetId) { appWidgetHost.deleteAppWidgetId(appWidgetId); } public boolean isPageRemovalAllowed() { return pages.size() > 1; } public Container[] getAllContainers() { ArrayList<Container> list = new ArrayList<>(); for (int i = 0; i < pages.size(); i++) { Container[] addition = pages.get(i).getAllContainers(); list.addAll(Arrays.asList(addition)); } return list.toArray(new Container[list.size()]); } public PageContainerFragment[] getPages() { return pages.toArray(new PageContainerFragment[pages.size()]); } public void orderPages(List<Integer> order) { ArrayList<PageContainerFragment> pages = new ArrayList<>(); for (int i = 0; i < this.pages.size(); i++) { int index = order.indexOf(i); if (index < 0 || index >= this.pages.size()) { Log.e(LOG_TAG, "orderPages: illegal index " + index + " for page " + i); return; } pages.add(this.pages.get(index)); } if (pages.equals(this.pages)) { return; } PageContainerFragment currentPage = this.pages.get(viewPager.getCurrentItem()); this.pages = pages; notifyDataSetChanged(); restart(pages.indexOf(currentPage)); } // Required for the correct fragment size, as configured in the block unit preference public View getViewContainer() { return viewPager; } //ViewPager.OnPageChangeListener stuff @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { if (DEBUG) Log.v(LOG_TAG, "Select page " + position); setActionBarTitle(pages.get(position).getActionBarTitle()); for (int i = 0; i < pages.size(); i++) { pages.get(i).setMenuEnabled(i == position); } } @Override public void onPageScrollStateChanged(int state) { } private Runnable resetVolumeButtonSettingsShortcut = new Runnable() { @Override public void run() { volumeButtonSettingsShortcutCount = 0; } }; public void setActionBarTitle(PageContainerFragment page, String title) { if (page == pages.get(viewPager.getCurrentItem())) { setActionBarTitle(title); } } private void setActionBarTitle(String title) { ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setTitle(title); } } private void setLockedModeVisibilities() { // Only show some menu items if device unlocked KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE); boolean unlocked = !keyguardManager.inKeyguardRestrictedInputMode(); if (editModeMenuItem != null) { editModeMenuItem.setVisible(unlocked); } if (connectionMgrMenuItem != null) { connectionMgrMenuItem .setVisible(unlocked && tcpConnectionManager.getConnectionSuggestions().length != 0); } } public void setViewPagerEnabled(boolean enabled) { viewPager.setScrollEnabled(enabled); } private void cancelEditContainerModeToast() { if (editModeContainerDragMoveToast != null) { editModeContainerDragMoveToast.cancel(); editModeContainerDragMoveToast = null; } } }