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 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(){// 经过Root处理的android系统即有su命令Process process;try {process = Runtime.getRuntime().exec("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 DataOutputStream(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 len = 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;}}


更多相关文章

  1. Android 清空系统wifi记录
  2. Android 4.0允许用户禁用所有系统自带程序
  3. PC&移动平台设备检测库(平台、版本、操作系统、方向)
  4. Android技术内幕.系统卷
  5. 拷贝的Android源码不能单独编译mmm命令提示找不到
  6. android pm 命令总结
  7. [CSDN]Android系统进程Zygote启动过程的源代码分析

随机推荐

  1. Android消息机制
  2. Android(安卓)内存泄露分析
  3. 五大媒体播放器的Android
  4. 《Android经验分享》周刊第12期
  5. android:padding 和 android:margin的区
  6. Android(安卓)NDK 面试题汇总
  7. Android8.0 在framework中添加KeyCode
  8. Invalidate和postInvalidate的区别
  9. 《深入解析Android(安卓)5.0系统》——导
  10. Flutter笔记(二)