Java tutorial
/* * Copyright (C) 2014 Simple Explorer * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ package com.dnielfe.manager; import java.io.File; import java.util.ArrayList; import org.apache.commons.io.FilenameUtils; import com.dnielfe.manager.adapters.BookmarksAdapter; import com.dnielfe.manager.adapters.DrawerListAdapter; import com.dnielfe.manager.adapters.BrowserListAdapter; import com.dnielfe.manager.controller.ActionModeController; import com.dnielfe.manager.dialogs.CreateFileDialog; import com.dnielfe.manager.dialogs.CreateFolderDialog; import com.dnielfe.manager.dialogs.DirectoryInfoDialog; import com.dnielfe.manager.dialogs.UnpackDialog; import com.dnielfe.manager.fileobserver.FileObserverCache; import com.dnielfe.manager.fileobserver.MultiFileObserver; import com.dnielfe.manager.fileobserver.MultiFileObserver.OnEventListener; import com.dnielfe.manager.settings.Settings; import com.dnielfe.manager.settings.SettingsActivity; import com.dnielfe.manager.tasks.PasteTaskExecutor; import com.dnielfe.manager.utils.ActionBarNavigation; import com.dnielfe.manager.utils.ActionBarNavigation.OnNavigateListener; import com.dnielfe.manager.utils.Bookmarks; import com.dnielfe.manager.utils.ClipBoard; import com.dnielfe.manager.utils.SimpleUtils; import android.app.ActionBar; import android.app.DialogFragment; import android.app.Fragment; import android.app.FragmentManager; import android.content.Intent; import android.content.res.Configuration; import android.content.res.TypedArray; import android.database.Cursor; import android.os.Bundle; import android.os.FileObserver; import android.os.Handler; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.view.KeyEvent; import android.view.View; import android.view.Menu; import android.view.MenuItem; import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.Toast; public final class Browser extends ThemableActivity implements OnEventListener, OnNavigateListener { public static final String EXTRA_SHORTCUT = "shortcut_path"; public static final String TAG_DIALOG = "dialog"; private static Handler sHandler; private static ActionBarNavigation mNavigation; private ActionModeController mActionController; private MultiFileObserver mObserver; private FileObserverCache mObserverCache; private Runnable mLastRunnable; private static BookmarksAdapter mBookmarksAdapter; private static BrowserListAdapter mListAdapter; private static DrawerListAdapter mMenuAdapter; private boolean mUseBackKey = true; public static ArrayList<String> mDataSource; public static String mCurrentPath; private FragmentManager fm; private Cursor mBookmarksCursor; private LinearLayout mDrawer; private MenuItem mMenuItemPaste; private DrawerLayout mDrawerLayout; private ListView mDrawerList, mBookmarkList; private AbsListView mListView; private ActionBar mActionBar; private ActionBarDrawerToggle mDrawerToggle; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_browser); Intent intent = getIntent(); if (savedInstanceState == null) { savedInstanceState = intent.getBundleExtra(EXTRA_SAVED_STATE); } init(intent); initDirectory(savedInstanceState, intent); } @Override public void onResume() { super.onResume(); Settings.updatePreferences(this); invalidateOptionsMenu(); } @Override public void onPause() { super.onPause(); mObserver.stopWatching(); final Fragment f = fm.findFragmentByTag(TAG_DIALOG); if (f != null) { fm.beginTransaction().remove(f).commit(); fm.executePendingTransactions(); } } @Override public void onDestroy() { super.onDestroy(); if (mObserver != null) { mObserver.stopWatching(); mObserver.removeOnEventListener(this); } if (mNavigation != null) mNavigation.removeOnNavigateListener(this); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString("location", mCurrentPath); } private void initDirectory(Bundle savedInstanceState, Intent intent) { String defaultdir; if (savedInstanceState != null) { // get directory when you rotate your phone defaultdir = savedInstanceState.getString("location"); } else { try { File dir = new File(intent.getStringExtra(EXTRA_SHORTCUT)); if (dir.exists() && dir.isDirectory()) { defaultdir = dir.getAbsolutePath(); } else { if (dir.exists() && dir.isFile()) listItemAction(dir); // you need to call it when shortcut-dir not exists defaultdir = Settings.defaultdir; } } catch (Exception e) { defaultdir = Settings.defaultdir; } } File dir = new File(defaultdir); if (dir.exists() && dir.isDirectory()) navigateTo(dir.getAbsolutePath()); } private void init(Intent intent) { fm = getFragmentManager(); mDataSource = new ArrayList<String>(); mObserverCache = FileObserverCache.getInstance(); mNavigation = new ActionBarNavigation(this); mActionController = new ActionModeController(this); // new ArrayAdapter mListAdapter = new BrowserListAdapter(this, mDataSource); if (sHandler == null) { sHandler = new Handler(this.getMainLooper()); } initActionBar(); setupDrawer(); initDrawerLists(); // get the browser list mListView = (ListView) findViewById(android.R.id.list); mListView.setEmptyView(findViewById(android.R.id.empty)); mListView.setAdapter(mListAdapter); mListView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE_MODAL); mListView.setOnItemClickListener(mOnItemClickListener); mActionController.setListView(mListView); } private OnItemClickListener mOnItemClickListener = new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { final File file = new File((mListView.getAdapter().getItem(position)).toString()); if (file.isDirectory()) { navigateTo(file.getAbsolutePath()); // go to the top of the ListView mListView.setSelection(0); if (!mUseBackKey) mUseBackKey = true; } else { listItemAction(file); } } }; private void initActionBar() { mActionBar = this.getActionBar(); mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_USE_LOGO | ActionBar.DISPLAY_HOME_AS_UP); // set custom ActionBar layout final View mActionView = getLayoutInflater().inflate(R.layout.activity_browser_actionbar, null); mActionBar.setCustomView(mActionView); mActionBar.show(); } private void setupDrawer() { final TypedArray array = obtainStyledAttributes(new int[] { R.attr.themeId }); final int themeId = array.getInteger(0, SimpleExplorer.THEME_ID_LIGHT); array.recycle(); mDrawer = (LinearLayout) findViewById(R.id.left_drawer); // Set shadow of navigation drawer mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START); int icon = themeId == SimpleExplorer.THEME_ID_LIGHT ? R.drawable.holo_light_ic_drawer : R.drawable.holo_dark_ic_drawer; // Add Navigation Drawer to ActionBar mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, icon, R.string.drawer_open, R.string.drawer_close) { @Override public void onDrawerOpened(View view) { super.onDrawerOpened(view); mActionBar.setDisplayOptions( ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_TITLE); mActionBar.setTitle(R.string.app_name); invalidateOptionsMenu(); } @Override public void onDrawerClosed(View view) { super.onDrawerClosed(view); mActionBar.setDisplayOptions( ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_CUSTOM); invalidateOptionsMenu(); } }; mDrawerLayout.setDrawerListener(mDrawerToggle); } // TODO improve - currently there are two ListViews in one Layout private void initDrawerLists() { mBookmarksCursor = getBookmarksCursor(); mBookmarksAdapter = new BookmarksAdapter(this, mBookmarksCursor); mMenuAdapter = new DrawerListAdapter(this); // initialize menu list mDrawerList = (ListView) findViewById(R.id.drawer_list); mDrawerList.setAdapter(mMenuAdapter); mDrawerList.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { switch (position) { case 0: // start AppManager Intent intent1 = new Intent(Browser.this, AppManager.class); startActivity(intent1); break; case 1: // start Preferences Intent intent2 = new Intent(Browser.this, SettingsActivity.class); startActivity(intent2); break; case 2: // exit finish(); } } }); // initialize bookmarks list mBookmarkList = (ListView) findViewById(R.id.bookmark_list); mBookmarkList.setAdapter(mBookmarksAdapter); mBookmarkList.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if (mDrawerLayout.isDrawerOpen(mDrawer)) mDrawerLayout.closeDrawer(mDrawer); if (mBookmarksCursor.moveToPosition(position)) { File file = new File( mBookmarksCursor.getString(mBookmarksCursor.getColumnIndex(Bookmarks.PATH))); if (file != null) { if (file.isDirectory()) { mCurrentPath = file.getAbsolutePath(); // go to the top of the ListView mListView.setSelection(0); } else { listItemAction(file); } } } } }); } private void navigateTo(String path) { mCurrentPath = new String(path); if (mObserver != null) { mObserver.stopWatching(); mObserver.removeOnEventListener(this); } listDirectory(path); mObserver = mObserverCache.getOrCreate(path); // add listener for FileObserver and start watching if (mObserver.listeners.isEmpty()) mObserver.addOnEventListener(this); mObserver.startWatching(); // add listener for navigation view in ActionBar if (mNavigation.listeners.isEmpty()) mNavigation.addonNavigateListener(this); mNavigation.setDirectoryButtons(path); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); mDrawerToggle.syncState(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mDrawerToggle.onConfigurationChanged(newConfig); } @Override public void onEvent(int event, String path) { // this will automatically update the directory when an action like this // will be performed switch (event & FileObserver.ALL_EVENTS) { case FileObserver.CREATE: case FileObserver.CLOSE_WRITE: case FileObserver.MOVE_SELF: case FileObserver.MOVED_TO: case FileObserver.MOVED_FROM: case FileObserver.ATTRIB: case FileObserver.DELETE: case FileObserver.DELETE_SELF: sHandler.removeCallbacks(mLastRunnable); sHandler.post(mLastRunnable = new NavigateRunnable(mCurrentPath)); break; } } @Override public void onNavigate(String path) { // navigate to path when ActionBarNavigation button is clicked navigateTo(path); // go to the top of the ListView mListView.setSelection(0); } private void listItemAction(File file) { String item_ext = FilenameUtils.getExtension(file.getName()); if (item_ext.equalsIgnoreCase("zip") || item_ext.equalsIgnoreCase("rar")) { final DialogFragment dialog = UnpackDialog.instantiate(file); dialog.show(fm, TAG_DIALOG); } else { SimpleUtils.openFile(this, file); } } @Override public boolean onCreateOptionsMenu(Menu menu) { this.getMenuInflater().inflate(R.menu.main, menu); mMenuItemPaste = menu.findItem(R.id.paste); mMenuItemPaste.setVisible(!ClipBoard.isEmpty()); return true; } @Override public boolean onPrepareOptionsMenu(Menu menu) { // this is needed when a Bookmark is selected in NavingationDrawer if (!mDrawerLayout.isDrawerOpen(mDrawer)) { // update ActionBar navigation view navigateTo(mCurrentPath); } return super.onPrepareOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: if (mDrawerLayout.isDrawerOpen(mDrawer)) { mDrawerLayout.closeDrawer(mDrawer); } else { mDrawerLayout.openDrawer(mDrawer); } return true; case R.id.createfile: final DialogFragment dialog1 = new CreateFileDialog(); dialog1.show(fm, TAG_DIALOG); return true; case R.id.createfolder: final DialogFragment dialog2 = new CreateFolderDialog(); dialog2.show(fm, TAG_DIALOG); return true; case R.id.folderinfo: final DialogFragment dirInfo = new DirectoryInfoDialog(); dirInfo.show(fm, TAG_DIALOG); return true; case R.id.search: Intent sintent = new Intent(Browser.this, SearchActivity.class); startActivity(sintent); return true; case R.id.paste: final PasteTaskExecutor ptc = new PasteTaskExecutor(this, mCurrentPath); ptc.start(); return true; default: return super.onOptionsItemSelected(item); } } public static BookmarksAdapter getBookmarksAdapter() { return mBookmarksAdapter; } private Cursor getBookmarksCursor() { return getContentResolver().query(Bookmarks.CONTENT_URI, new String[] { Bookmarks._ID, Bookmarks.NAME, Bookmarks.PATH, Bookmarks.CHECKED }, null, null, null); } private static final class NavigateRunnable implements Runnable { private final String target; NavigateRunnable(final String path) { this.target = path; } @Override public void run() { listDirectory(target); } } public static void listDirectory(String path) { ArrayList<String> ab = SimpleUtils.listFiles(path); mCurrentPath = path; if (!mDataSource.isEmpty()) mDataSource.clear(); for (String data : ab) mDataSource.add(data); mListAdapter.notifyDataSetChanged(); } public static ActionBarNavigation getNavigation() { return mNavigation; } @Override public boolean onKeyDown(int keycode, KeyEvent event) { if (keycode == KeyEvent.KEYCODE_BACK && mUseBackKey && !mCurrentPath.equals("/")) { File file = new File(mCurrentPath); navigateTo(file.getParent()); // go to the top of the ListView mListView.setSelection(0); return true; } else if (keycode == KeyEvent.KEYCODE_BACK && mUseBackKey && mCurrentPath.equals("/")) { Toast.makeText(Browser.this, getString(R.string.pressbackagaintoquit), Toast.LENGTH_SHORT).show(); mUseBackKey = false; return false; } else if (keycode == KeyEvent.KEYCODE_BACK && !mUseBackKey && mCurrentPath.equals("/")) { finish(); return false; } return super.onKeyDown(keycode, event); } }