package talent.fm;import java.io.File;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import android.content.Context;import android.content.res.TypedArray;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.AdapterView;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.ListView;import android.widget.TextView;public class FileView extends ListView{private FileAdapter browser;public interface OnPathChanged{abstract boolean onChanged(String old,String path);}public void SetOnPathChangedListener(OnPathChanged listener){if(browser==null) return;browser.onChanged = listener;}public FileView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init();}public FileView(Context context, AttributeSet attrs) {super(context, attrs);init(); TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.FileView); String path = a.getString(R.styleable.FileView_path); a.recycle(); if(path!=null) browser.SetPath(path); }public FileView(Context context) {super(context);init();}private void init(){browser = new FileAdapter();setAdapter(browser); setOnItemClickListener(onItemClick);} private OnItemClickListener onItemClick = new OnItemClickListener(){@Overridepublic void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {//com.Logi("item:"+arg2);if(!browser.OpenChild(arg2)){com.Toast(arg1.getContext(),"folder is empty or can't open");return;}} }; /**goto parent folder,return false if no parent folder.*/ public boolean Up(){ return browser.Up(); } public void SetPath(String path){ browser.SetPath(path); } public String GetPath(){ return browser.GetPath(); }}class FileAdapter extends BaseAdapter{private String path = "/";private List<FileInfo> contents = new ArrayList<FileInfo>();protectedFileView.OnPathChanged onChanged; Console cs = new Console(); private final static int BROWS_MODE_SU = 1, BROWS_MODE_APK = 2; private int mode = BROWS_MODE_SU; private class FileInfo{ StringName; intIconId; FileInfo(String name,int id){ Name = name; IconId = id; } boolean IsFolder(){ return R.drawable.icon_folder==IconId; } } public boolean SetSUMode(){ mode = BROWS_MODE_SU; return true; } public void SetAPKMode(){ mode = BROWS_MODE_APK; SetPath(path); }public FileAdapter(){cs.SetOnOutput(onConsoleOutput);if(!cs.Create())SetAPKMode();}@Overridepublic int getCount() {return contents.size();}/**return a File Object*/@Overridepublic Object getItem(int position) {if(position>=contents.size()) return null;return contents.get(position);}@Overridepublic long getItemId(int position) {return 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {if (convertView == null) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); convertView = inflater.inflate(R.layout.item_explorer,null);} FileInfo fi = contents.get(position);ImageView iv = (ImageView)convertView.findViewById(R.id.explorer_iv_image);iv.setImageResource(fi.IconId);TextView tv = (TextView)convertView.findViewById(R.id.explorer_iv_text);tv.setText(fi.Name);return convertView;}public void SetPath(String path){com.Logi(path);if(path==null||path.length()==0)path = "/";contents.clear();notifyDataSetChanged();if(onChanged!=null) onChanged.onChanged(this.path,path);this.path = path;if(this.mode==BROWS_MODE_APK){File file = new File(path);String[] fnl = file.list();com.Logw("fnl:"+fnl);File[] fl = file.listFiles();if(fl==null){com.Loge("init path:"+path);return;}Arrays.sort(fl);folderInsertPos = 0;for(int i=0;i<fl.length;i++){insertByFile(fl[i]);}notifyDataSetChanged();}else if(mode==BROWS_MODE_SU){String cmd = "ls " + path;if(!cs.Exec(cmd))SetAPKMode();}}public String GetPath(){return path;}public boolean OpenChild(int index){if(index<0||index>=contents.size()) return false;FileInfo fi = contents.get(index);if(!fi.IsFolder()) return false;if(path.equals("/")) path = "";SetPath(path+"/"+fi.Name);return true;}public boolean Up(){File file = new File(path);File root = file.getParentFile();if(root==null) return false;SetPath(root.getPath());return true;}private Console.OnOutput onConsoleOutput = new Console.OnOutput(){@Overridepublic void onOutput(String str) {Message msg = new Message();msg.what = MSG_NOTIFY_STR;Bundle bundle = new Bundle();bundle.putString("output_str",str);msg.setData(bundle);notifyHandler.sendMessage(msg);}};private int folderInsertPos = 0;/**insert FileInfo object in contents set,and position by name*/private void insertByName(String str){ String fp = path + "/" + str; File file = new File(fp); insertByFile(file); }private void insertByFile(File file){int icon;if(file.isDirectory()){icon = R.drawable.icon_folder;contents.add(folderInsertPos,new FileInfo(file.getName(),icon));folderInsertPos++;}else{ if(file.isFile()){ icon = R.drawable.icon_file; } else{ icon = R.drawable.icon_script; }contents.add(new FileInfo(file.getName(),icon));}}private final static int MSG_NOTIFY_DATA = 1,MSG_NOTIFY_STR = 2;private Handler notifyHandler = new Handler(){@Overridepublic void handleMessage(Message msg){if(msg.what==MSG_NOTIFY_STR){String str = msg.getData().getString("output_str");if(str.length()==0) return;String[] fns = str.split("\\|");Arrays.sort(fns);folderInsertPos = 0;for(int i=0;i<fns.length;i++){insertByName(fns[i]);}notifyDataSetChanged();}else if(msg.what==MSG_NOTIFY_DATA){}}};}
Package talent. FM; import Java. io. datainputstream; import Java. io. dataoutputstream; import Java. io. ioexception; public class console {private Boolean notexit = true; private readthread readth = new readthread (); Private datainputstream input; private dataoutputstream output; private onoutput; public interface onoutput {void onoutput (string Str);}/** must call this function or thread will not terminate */Public void close () {notexit = false; If (input! = NULL) {try {input. close ();} catch (ioexception e) {COM. logE ("console. close input: "+ E. getmessage () ;}} public Boolean create () {// The root-processed Android system has the su command process; try {process = runtime.getruntime(cmd.exe C ("Su");} catch (ioexception e) {COM. logE ("console. create: "+ E. getmessage (); Return false;} catch (securityexception e) {COM. logE ("console. create: "+ E. getmessage (); Return false;} output = new dat Aoutputstream (process. getoutputstream (); input = new datainputstream (process. getinputstream (); readth. start (); Return true;} public Boolean exec (string cmd) {try {output. writebytes (CMD + "\ n"); output. flush (); Return true;} catch (ioexception e) {COM. logE ("console. exec: "+ E. getmessage ();} return false;} class readthread extends thread {@ overridepublic void run () {string outstr = ""; while (notexit) {try {int L En = input. Available (); If (0 = Len) {If (onoutput! = NULL) onoutput. onoutput (outstr); outstr = "";} string STR = input. readline (); If (STR = NULL) break; outstr + = STR + "|";} catch (ioexception e) {COM. logE ("console. thread. run: "+ E. getmessage (); break ;}}} public void setonoutput (onoutput OPT) {onoutput = opt ;}}