Java tutorial
/* * Tweetings - Twitter client for Android * * Copyright (C) 2012-2013 RBD Solutions Limited <apps@tweetings.net> * Copyright (C) 2012 Mariotaku Lee <mariotaku.lee@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 com.dwdesign.tweetings.activity; import static android.os.Environment.getExternalStorageDirectory; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.dwdesign.tweetings.Constants; import com.dwdesign.tweetings.R; import com.dwdesign.tweetings.util.ArrayUtils; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.AsyncTaskLoader; import android.support.v4.content.Loader; import android.text.TextUtils.TruncateAt; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.BaseAdapter; import android.widget.ListView; import android.widget.TextView; public class FilePickerActivity extends BaseActivity implements Constants, OnItemClickListener, LoaderCallbacks<List<File>> { private File mCurrentDirectory; private ListView mListView; private FilesAdapter mAdapter; @Override public void onBackPressed() { if (mCurrentDirectory != null) { final File parent = mCurrentDirectory.getParentFile(); if (parent != null) { mCurrentDirectory = parent; getSupportLoaderManager().restartLoader(0, null, this); return; } } setResult(RESULT_CANCELED); finish(); } @Override public void onCreate(final Bundle savedInstanceState) { final String action = getIntent().getAction(); mCurrentDirectory = getExternalStorageDirectory(); if (!INTENT_ACTION_PICK_FILE.equals(action) || mCurrentDirectory == null) { finish(); return; } super.onCreate(savedInstanceState); setContentView(R.layout.base_list); getSupportActionBar().setDisplayHomeAsUpEnabled(true); mAdapter = new FilesAdapter(this); mListView = (ListView) findViewById(android.R.id.list); mListView.setAdapter(mAdapter); mListView.setOnItemClickListener(this); getSupportLoaderManager().initLoader(0, null, this); } @Override public Loader<List<File>> onCreateLoader(final int id, Bundle args) { if (args == null) { args = getIntent().getExtras(); } final String[] extensions = args != null ? args.getStringArray(INTENT_KEY_FILE_EXTENSIONS) : new String[0]; return new FilesLoader(this, mCurrentDirectory, extensions); } @Override public boolean onCreateOptionsMenu(final Menu menu) { getMenuInflater().inflate(R.menu.menu_file_picker, menu); return super.onCreateOptionsMenu(menu); } @Override public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) { final File file = mAdapter.getItem(position); if (file == null) return; if (file.isDirectory()) { mCurrentDirectory = file; getSupportLoaderManager().restartLoader(0, null, this); } else if (file.isFile()) { final Intent intent = new Intent(); intent.setData(Uri.fromFile(file)); setResult(RESULT_OK, intent); finish(); } } @Override public void onLoaderReset(final Loader<List<File>> loader) { mAdapter.setData(null); } @Override public void onLoadFinished(final Loader<List<File>> loader, final List<File> data) { mAdapter.setData(data); } @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { case MENU_HOME: { onBackPressed(); break; } case MENU_CANCEL: { setResult(RESULT_CANCELED); finish(); } } return super.onOptionsItemSelected(item); } @Override protected void onSaveInstanceState(final Bundle outState) { super.onSaveInstanceState(outState); } static class FilesAdapter extends BaseAdapter { private final LayoutInflater mInflater; private final Context mContext; private final List<File> mData = new ArrayList<File>(); public FilesAdapter(final Context context) { mInflater = LayoutInflater.from(context); mContext = context; } @Override public int getCount() { return mData.size(); } @Override public File getItem(final int position) { return mData.get(position); } @Override public long getItemId(final int position) { return getItem(position).hashCode(); } @Override public View getView(final int position, final View convertView, final ViewGroup parent) { final View view = convertView != null ? convertView : mInflater.inflate(android.R.layout.simple_list_item_1, parent, false); final TextView text = (TextView) (view instanceof TextView ? view : view.findViewById(android.R.id.text1)); final File file = getItem(position); if (file == null || text == null) return view; text.setText(file.getName()); final int padding = (int) (4 * mContext.getResources().getDisplayMetrics().density); text.setSingleLine(true); text.setEllipsize(TruncateAt.MARQUEE); text.setPadding(padding, padding, position, padding); text.setCompoundDrawablesWithIntrinsicBounds( file.isDirectory() ? R.drawable.ic_folder : R.drawable.ic_file, 0, 0, 0); return view; } public void setData(final List<File> data) { mData.clear(); if (data != null) { mData.addAll(data); } notifyDataSetChanged(); } } static class FilesLoader extends AsyncTaskLoader<List<File>> { private final File path; private final Pattern extensions_regex; private static final Comparator<File> NAME_COMPARATOR = new Comparator<File>() { @Override public int compare(final File file1, final File file2) { return file1.getName().compareTo(file2.getName()); } }; public FilesLoader(final Context context, final File path, final String[] extensions) { super(context); this.path = path; extensions_regex = Pattern.compile(ArrayUtils.toString(extensions, '|', false), Pattern.CASE_INSENSITIVE); } @Override public List<File> loadInBackground() { final List<File> list = new ArrayList<File>(); if (path != null && path.isDirectory()) { final File[] files = path.listFiles(); if (files != null) { for (final File file : files) { if (file.canRead()) { if (file.isFile()) { final String name = file.getName(); final int idx = name.lastIndexOf("."); if (idx == -1) { continue; } final Matcher m = extensions_regex.matcher(name.substring(idx + 1)); if (!m.matches()) { continue; } } list.add(file); } } } Collections.sort(list, NAME_COMPARATOR); } return list; } @Override protected void onStartLoading() { forceLoad(); } @Override protected void onStopLoading() { cancelLoad(); } } }