使用命令行ls命令的Android文件浏览控件,适合于root过的设备,可以读取系统文件
16lz
2021-01-23
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;}}
更多相关文章
- Android 清空系统wifi记录
- Android 4.0允许用户禁用所有系统自带程序
- PC&移动平台设备检测库(平台、版本、操作系统、方向)
- Android技术内幕.系统卷
- 拷贝的Android源码不能单独编译mmm命令提示找不到
- android pm 命令总结
- [CSDN]Android系统进程Zygote启动过程的源代码分析