package com.novelbook.android.filechooser; import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.graphics.drawable.Drawable; import android.graphics.pdf.PdfDocument; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.StatFs; import android.support.v4.app.Fragment; import android.text.TextUtils; import android.util.Log; import android.util.StateSet; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.Button; import android.widget.CompoundButton; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import com.novelbook.android.MyApp; import com.novelbook.android.R; import com.novelbook.android.ReadActivity; import com.novelbook.android.db.Novel; import com.novelbook.android.utils.FileUtils; import com.novelbook.android.utils.PageFactory; import org.litepal.LitePal; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.List; public class DirectoryFragment extends Fragment implements View.OnClickListener { public static final String TAG =DirectoryFragment.class.getSimpleName(); private View fragmentView; private boolean receiverRegistered = false; private File currentDir; private ListView listView; private ListAdapter listAdapter; private TextView emptyView; private LinearLayout layout_bottom; private Button btn_choose_all; private Button btn_delete; private Button btn_add_file; private DocumentSelectActivityDelegate delegate; private static String title_ = ""; private ArrayList items = new ArrayList(); private ArrayList checkItems = new ArrayList(); private ArrayList history = new ArrayList(); private HashMap selectedFiles = new HashMap(); private List bookLists; private long sizeLimit = 1024 * 1024 * 1024; private String[] chhosefileType = {".txt"}; private class HistoryEntry { int scrollItem, scrollOffset; File dir; String title; } public static abstract interface DocumentSelectActivityDelegate { public void didSelectFiles(DirectoryFragment activity, ArrayList files); public void startDocumentSelectActivity(); public void updateToolBarName(String name); } public boolean onBackPressed_() { if (history.size() > 0) { HistoryEntry he = history.remove(history.size() - 1); title_ = he.title; updateName(title_); if (he.dir != null) { listFiles(he.dir); } else { listRoots(); } listView.setSelectionFromTop(he.scrollItem, he.scrollOffset); return false; } else { return true; } } private void updateName(String title_) { if (delegate != null) { delegate.updateToolBarName(title_); } } public void onFragmentDestroy() { try { if (receiverRegistered) { getActivity().unregisterReceiver(receiver); } } catch (Exception e) { Log.e("tmessages", e.toString()); } } private BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context arg0, Intent intent) { Runnable r = new Runnable() { public void run() { try { if (currentDir == null) { listRoots(); } else { listFiles(currentDir); } } catch (Exception e) { Log.e("tmessages", e.toString()); } } }; if (Intent.ACTION_MEDIA_UNMOUNTED.equals(intent.getAction())) { listView.postDelayed(r, 1000); } else { r.run(); } } }; public void setDelegate(DocumentSelectActivityDelegate delegate) { this.delegate = delegate; } private class ListItem { int icon; String title; String subtitle = ""; String ext = ""; String thumb; File file; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (!receiverRegistered) { receiverRegistered = true; IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_MEDIA_BAD_REMOVAL); filter.addAction(Intent.ACTION_MEDIA_CHECKING); filter.addAction(Intent.ACTION_MEDIA_EJECT); filter.addAction(Intent.ACTION_MEDIA_MOUNTED); filter.addAction(Intent.ACTION_MEDIA_NOFS); filter.addAction(Intent.ACTION_MEDIA_REMOVED); filter.addAction(Intent.ACTION_MEDIA_SHARED); filter.addAction(Intent.ACTION_MEDIA_UNMOUNTABLE); filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); filter.addDataScheme("file"); getActivity().registerReceiver(receiver, filter); } // bookLists = LitePal.findAll(Novel.class); if (fragmentView == null) { fragmentView = inflater.inflate(R.layout.zdocument_select_layout, container, false); layout_bottom = (LinearLayout) fragmentView .findViewById(R.id.layout_bottom); btn_choose_all = (Button) fragmentView .findViewById(R.id.btn_choose_all); btn_delete = (Button) fragmentView .findViewById(R.id.btn_delete); btn_add_file = (Button) fragmentView .findViewById(R.id.btn_add_file); btn_choose_all.setOnClickListener(this); btn_delete.setOnClickListener(this); btn_add_file.setOnClickListener(this); listAdapter = new ListAdapter(getActivity()); emptyView = (TextView) fragmentView .findViewById(R.id.searchEmptyView); emptyView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return true; } }); listView = (ListView) fragmentView.findViewById(R.id.listView); listView.setEmptyView(emptyView); listView.setAdapter(listAdapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView adapterView, View view, int i, long l) { if (i < 0 || i >= items.size()) { return; } ListItem item = items.get(i); File file = item.file; if (file == null) { HistoryEntry he = history.remove(history.size() - 1); title_ = he.title; updateName(title_); if (he.dir != null) { listFiles(he.dir); } else { listRoots(); } listView.setSelectionFromTop(he.scrollItem, he.scrollOffset); } else if (file.isDirectory()) { HistoryEntry he = new HistoryEntry(); he.scrollItem = listView.getFirstVisiblePosition(); he.scrollOffset = listView.getChildAt(0).getTop(); he.dir = currentDir; he.title = title_.toString(); updateName(title_); if (!listFiles(file)) { return; } history.add(he); title_ = item.title; updateName(title_); listView.setSelection(0); } else { if (!file.canRead()) { showErrorBox("没有权限!"); return; } if (sizeLimit != 0) { if (file.length() > sizeLimit) { showErrorBox("文件大小超出限制!"); return; } } if (file.length() == 0) { return; } if (file.toString().contains(chhosefileType[0]) || file.toString().contains(chhosefileType[1]) || file.toString().contains(chhosefileType[2]) || file.toString().contains(chhosefileType[3]) || file.toString().contains(chhosefileType[4])) { if (delegate != null) { ArrayList files = new ArrayList(); files.add(file.getAbsolutePath()); delegate.didSelectFiles(DirectoryFragment.this, files); } } else { showErrorBox("请选择正确的文件!"); return; } } } }); changgeCheckBookNum(); listRoots(); } else { ViewGroup parent = (ViewGroup) fragmentView.getParent(); if (parent != null) { parent.removeView(fragmentView); } } return fragmentView; } @Override public void onResume() { super.onResume(); bookLists = Novel.getLocalNovels(); // LitePal.where("isOnShelf=?","1").find( Novel.class); listAdapter.notifyDataSetChanged(); } @Override public void onClick(View v) { int id = v.getId(); switch (id){ case R.id.btn_choose_all: checkAll(); changgeCheckBookNum(); listAdapter.notifyDataSetChanged(); changgeCheckBookNum(); break; case R.id.btn_delete: checkItems.clear(); listAdapter.notifyDataSetChanged(); changgeCheckBookNum(); break; case R.id.btn_add_file: // changgeCheckBookNum(); addCheckBook(); break; } } private void addCheckBook(){ if (checkItems.size() > 0) { List bookLists = new ArrayList(); for (ListItem item : checkItems) { Novel bookList = new Novel(); String bookName = FileUtils.getFileName(item.thumb); bookList.setName(bookName); bookList.setNovelPath(item.thumb); bookList.setOnShelf(true); bookLists.add(bookList); } SaveBookToSqlLiteTask mSaveBookToSqlLiteTask = new SaveBookToSqlLiteTask(); mSaveBookToSqlLiteTask.execute(bookLists); } } private void checkAll(){ for (ListItem listItem : items){ if (!TextUtils.isEmpty(listItem.thumb)){ boolean isCheck = false; for (ListItem item : checkItems){ if (item.thumb.equals(listItem.thumb)){ isCheck = true; break; } } for (Novel list : bookLists){ if (list.getNovelPath().equals(listItem.thumb)){ isCheck = true; break; } } if (!isCheck) { checkItems.add(listItem); } } } } private class SaveBookToSqlLiteTask extends AsyncTask,Void,Integer> { private static final int FAIL = 0; private static final int SUCCESS = 1; private static final int REPEAT = 2; private Novel repeatBookList; @Override protected Integer doInBackground(List... params) { List bookLists = params[0]; for (Novel bookList : bookLists){ List books = LitePal.where("novelPath = ?", bookList.getNovelPath()).find(Novel.class); if (books.size() > 0){ repeatBookList = bookList; return REPEAT; } } try { LitePal.saveAll(bookLists); } catch (Exception e){ e.printStackTrace(); return FAIL; } return SUCCESS; } @Override protected void onPostExecute(Integer result) { super.onPostExecute(result); String msg = ""; switch (result){ case FAIL: msg = "由于一些原因添加书本失败"; break; case SUCCESS: msg = "导入书本成功"; checkItems.clear(); bookLists = Novel.getLocalNovels();//LitePal.where("isOnShelf=?","1").find( Novel.class);//LitePal.findAll(Novel.class); listAdapter.notifyDataSetChanged(); changgeCheckBookNum(); break; case REPEAT: msg = "书本" + repeatBookList.getName() + "重复了"; break; } Toast.makeText(getActivity().getApplicationContext(), msg, Toast.LENGTH_SHORT).show(); } } private void listRoots() { currentDir = null; items.clear(); String extStorage = Environment.getExternalStorageDirectory() .getAbsolutePath(); ListItem ext = new ListItem(); if (Build.VERSION.SDK_INT < 9 || Environment.isExternalStorageRemovable()) { ext.title = "SdCard"; } else { ext.title = "InternalStorage"; } ext.icon = Build.VERSION.SDK_INT < 9 || Environment.isExternalStorageRemovable() ? R.mipmap.ic_external_storage : R.mipmap.ic_storage; ext.subtitle = getRootSubtitle(extStorage); ext.file = Environment.getExternalStorageDirectory(); items.add(ext); try { BufferedReader reader = new BufferedReader(new FileReader( "/proc/mounts")); String line; HashMap> aliases = new HashMap>(); ArrayList result = new ArrayList(); String extDevice = null; while ((line = reader.readLine()) != null) { if ((!line.contains("/mnt") && !line.contains("/storage") && !line .contains("/sdcard")) || line.contains("asec") || line.contains("tmpfs") || line.contains("none")) { continue; } String[] info = line.split(" "); if (!aliases.containsKey(info[0])) { aliases.put(info[0], new ArrayList()); } aliases.get(info[0]).add(info[1]); if (info[1].equals(extStorage)) { extDevice = info[0]; } result.add(info[1]); } reader.close(); if (extDevice != null) { result.removeAll(aliases.get(extDevice)); for (String path : result) { try { ListItem item = new ListItem(); if (path.toLowerCase().contains("sd")) { ext.title = "SdCard"; } else { ext.title = "外部存储"; } item.icon = R.mipmap.ic_external_storage; item.subtitle = getRootSubtitle(path); item.file = new File(path); items.add(item); } catch (Exception e) { Log.e("tmessages", e.toString()); } } } } catch (Exception e) { Log.e("tmessages", e.toString()); } ListItem fs = new ListItem(); fs.title = "/"; fs.subtitle = "系统目录"; fs.icon = R.mipmap.ic_directory; fs.file = new File("/"); items.add(fs); // try { // File telegramPath = new // File(Environment.getExternalStorageDirectory(), "Telegram"); // if (telegramPath.exists()) { // fs = new ListItem(); // fs.title = "Telegram"; // fs.subtitle = telegramPath.toString(); // fs.icon = R.drawable.ic_directory; // fs.file = telegramPath; // items.add(fs); // } // } catch (Exception e) { // FileLog.e("tmessages", e); // } // AndroidUtilities.clearDrawableAnimation(listView); // scrolling = true; listAdapter.notifyDataSetChanged(); } private boolean listFiles(File dir) { if (!dir.canRead()) { if (dir.getAbsolutePath().startsWith( Environment.getExternalStorageDirectory().toString()) || dir.getAbsolutePath().startsWith("/sdcard") || dir.getAbsolutePath().startsWith("/mnt/sdcard")) { if (!Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED) && !Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED_READ_ONLY)) { currentDir = dir; items.clear(); String state = Environment.getExternalStorageState(); if (Environment.MEDIA_SHARED.equals(state)) { emptyView.setText("UsbActive"); } else { emptyView.setText("NotMounted"); } clearDrawableAnimation(listView); // scrolling = true; listAdapter.notifyDataSetChanged(); return true; } } showErrorBox("没有权限!"); return false; } emptyView.setText("没有文件!"); File[] files = null; try { files = dir.listFiles(); } catch (Exception e) { showErrorBox(e.getLocalizedMessage()); return false; } if (files == null) { showErrorBox("未知错误!"); return false; } currentDir = dir; items.clear(); Arrays.sort(files, new Comparator() { @Override public int compare(File lhs, File rhs) { if (lhs.isDirectory() != rhs.isDirectory()) { return lhs.isDirectory() ? -1 : 1; } return lhs.getName().compareToIgnoreCase(rhs.getName()); /* * long lm = lhs.lastModified(); long rm = lhs.lastModified(); * if (lm == rm) { return 0; } else if (lm > rm) { return -1; } * else { return 1; } */ } }); for (File file : files) { if (file.getName().startsWith(".") || (!file.isDirectory() && !file.getName().endsWith(".txt"))) { continue; } ListItem item = new ListItem(); item.title = file.getName(); item.file = file; if (file.isDirectory()) { item.icon = R.mipmap.ic_directory; item.subtitle = "文件夹"; } else { String fname = file.getName(); String[] sp = fname.split("\\."); item.ext = sp.length > 1 ? sp[sp.length - 1] : "?"; item.subtitle = formatFileSize(file.length()); fname = fname.toLowerCase(); if (fname.endsWith(".jpg") || fname.endsWith(".png") || fname.endsWith(".gif") || fname.endsWith(".jpeg") || fname.endsWith(".txt")) { item.thumb = file.getAbsolutePath(); } } items.add(item); } ListItem item = new ListItem(); item.title = ".."; item.subtitle = "文件夹"; item.icon = R.mipmap.ic_directory; item.file = null; items.add(0, item); clearDrawableAnimation(listView); // scrolling = true; listAdapter.notifyDataSetChanged(); return true; } public static String formatFileSize(long size) { if (size < 1024) { return String.format("%d B", size); } else if (size < 1024 * 1024) { return String.format("%.1f KB", size / 1024.0f); } else if (size < 1024 * 1024 * 1024) { return String.format("%.1f MB", size / 1024.0f / 1024.0f); } else { return String.format("%.1f GB", size / 1024.0f / 1024.0f / 1024.0f); } } public static void clearDrawableAnimation(View view) { if (Build.VERSION.SDK_INT < 21 || view == null) { return; } Drawable drawable = null; if (view instanceof ListView) { drawable = ((ListView) view).getSelector(); if (drawable != null) { drawable.setState(StateSet.NOTHING); } } else { drawable = view.getBackground(); if (drawable != null) { drawable.setState(StateSet.NOTHING); drawable.jumpToCurrentState(); } } } public void showErrorBox(String error) { if (getActivity() == null) { return; } new AlertDialog.Builder(getActivity()) .setTitle(getActivity().getString(R.string.app_name)) .setMessage(error).setPositiveButton("OK", null).show(); } public void showReadBox(final String path) { if (getActivity() == null) { return; } new AlertDialog.Builder(getActivity()) .setTitle(getActivity().getString(R.string.app_name)) .setMessage(path).setPositiveButton("阅读", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Novel bookList = new Novel(); String bookName = FileUtils.getFileName(path); bookList.setName(bookName); bookList.setNovelPath(path); boolean isSave = false; for (Novel book : bookLists){ if (book.getNovelPath().equals(bookList.getNovelPath())){ isSave = true; bookList =book; break; } } if (!isSave){ bookList.save(); } // PageFactory.getInstance(MyApp.applicationContext).prepareBook(bookList); ReadActivity.openBook(bookList, getActivity()); } }).show(); } private String getRootSubtitle(String path) { StatFs stat = new StatFs(path); long total = (long) stat.getBlockCount() * (long) stat.getBlockSize(); long free = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize(); if (total == 0) { return ""; } return "Free " + formatFileSize(free) + " of " + formatFileSize(total); } private void changgeCheckBookNum(){ btn_add_file.setText("加入书架(" + checkItems.size() + ")"); } private class ListAdapter extends BaseFragmentAdapter { private Context mContext; public ListAdapter(Context context) { mContext = context; } @Override public int getCount() { return items.size(); } @Override public Object getItem(int position) { return items.get(position); } @Override public long getItemId(int position) { return 0; } public int getViewTypeCount() { return 2; } public int getItemViewType(int pos) { return items.get(pos).subtitle.length() > 0 ? 0 : 1; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = new TextDetailDocumentsCell(mContext); } TextDetailDocumentsCell textDetailCell = (TextDetailDocumentsCell) convertView; final ListItem item = items.get(position); if (item.icon != 0) { ((TextDetailDocumentsCell) convertView) .setTextAndValueAndTypeAndThumb(item.title, item.subtitle, null, null, item.icon,false); } else { String type = item.ext.toUpperCase().substring(0, Math.min(item.ext.length(), 4)); ((TextDetailDocumentsCell) convertView) .setTextAndValueAndTypeAndThumb(item.title, item.subtitle, type, item.thumb, 0,isStorage(item.thumb)); } textDetailCell.getCheckBox().setOnCheckedChangeListener(null); textDetailCell.setChecked(isCheck(item.thumb)); textDetailCell.getCheckBox().setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked){ checkItems.add(item); }else{ removeCheckItem(item.thumb); } changgeCheckBookNum(); } }); // if (item.file != null && actionBar.isActionModeShowed()) { // textDetailCell.setChecked(selectedFiles.containsKey(item.file.toString()), // !scrolling); // } else { // textDetailCell.setChecked(false, !scrolling); // } return convertView; } private boolean isCheck(String path){ for (ListItem item : checkItems){ if (item.thumb.equals(path)){ return true; } } return false; } private void removeCheckItem(String path){ for (ListItem item : checkItems){ if (item.thumb.equals(path)){ checkItems.remove(item); break; } } } private boolean isStorage(String path){ boolean isStore = false; for (Novel bookList : bookLists){ if (bookList.getNovelPath().equals(path)){ return true; } } return false; } } public void finishFragment() { } }