关闭

安卓开发实例二:文件浏览器

1958人阅读 评论(0) 收藏 举报
分类:

概述:

需求:显示手机内所有文件、文件夹,显示文件内容,对文件拷贝、删除等。

实现:遍历文件,显示文件信息到ListView中;读取文件,显示到界面上;ListView添加菜单,处理文件操作。

扩展:自定义Activity标题栏,创建后台服务播放MP3文件。


代码:

<span style="font-family:Microsoft YaHei;font-size:12px;">public class MainActivity extends Activity {
	public static final int MENU_ID_BASE = 0;
	
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		switch( item.getItemId() ){
		case MENU_ID_BASE+1://删除
			Toast.makeText(this, "删除文件", Toast.LENGTH_LONG).show();
			break;
		case MENU_ID_BASE+2://复制
			Toast.makeText(this, "复制文件", Toast.LENGTH_LONG).show();
			break;
		case MENU_ID_BASE+3://重命名
			Toast.makeText(this, "重命名文件", Toast.LENGTH_LONG).show();
			break;
		}
		return super.onContextItemSelected(item);
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		if ( keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN ){
			if ( !isRoot() ){
				goBack();
				return true;
			}
		}
		return super.onKeyDown(keyCode, event);
	}
	private ListView m_lv = null;
	private TouchCallback m_tcb = null;
	private ArrayList<File> m_files = new ArrayList<File>();
	private String m_strDir = "./";
	private TextView m_tvFile = null;
	private OnItemLongClickListenerEx mItemLclickCb = null;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		m_lv = (ListView)findViewById(R.id.lv1);
		m_tvFile = (TextView)findViewById(R.id.tv_file);
		m_tcb = new TouchCallback();
		mItemLclickCb = new OnItemLongClickListenerEx();
	    m_tcb.setMainActivity(this);
	    m_lv.setOnItemClickListener(m_tcb);
	    mItemLclickCb.SetActivity(this);
	    mItemLclickCb.SetListView(m_lv);
	    m_lv.setOnItemLongClickListener(mItemLclickCb);
	    //m_lv.setOnClickListener(m_tcb);
		//生成动态数组,加入数据  
		File fRoot = new File(m_strDir);
        AddFiles(fRoot);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
	
	public class MyMapComparator implements Comparator{

		@Override
		public int compare(Object lhs, Object rhs) {
			// TODO Auto-generated method stub
			HashMap<String, Object> o1 = (HashMap<String, Object>)lhs;
			HashMap<String, Object> o2 = (HashMap<String, Object>)rhs;
			String strName1 = (String) o1.get("name");
			String strName2 = (String) o2.get("name");
			return strName1.compareTo(strName2);
		}
		
	}
	
	public class MyFileComparator implements Comparator{

		@Override
		public int compare(Object lhs, Object rhs) {
			// TODO Auto-generated method stub
			File o1 = (File)lhs;
			File o2 = (File)rhs;
			String strName1 = (String) o1.getName();
			String strName2 = (String) o2.getName();
			return strName1.compareTo(strName2);
		}
		
	}
	
	public void AddFiles(File f){
		if ( f.isFile() ){
			showFileDlg(f);
			return ;
		}
		File[] fs = f.listFiles();
		if ( fs == null || fs.length == 0 ){
			Toast.makeText(this, "没有权限", Toast.LENGTH_LONG).show();
			return ;
		}
		m_files.clear();
		m_strDir = f.getPath();
		if ( isRoot() )
			m_tvFile.setText(R.string.text_root);
		else
			m_tvFile.setText(m_strDir);
		for(File f1:fs)
			m_files.add(f1);
		//Arrays.sort(m_files);
		Collections.sort(m_files, new MyFileComparator());
		ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String, Object>>();
		for ( File f1:m_files ){
			 HashMap<String, Object> map = new HashMap<String, Object>();
			 String strName = f1.getName();
			 if ( f1.isDirectory() )
				 map.put("image", R.drawable.dir);
			 else
			 {
				 map.put("image", getFileImgId(strName));
			 }
			 map.put("attrs", GetFileAttrs(f1));
			 map.put("name", strName);
			 listItem.add(map);
		}
		SimpleAdapter sa = new SimpleAdapter(this, listItem, R.layout.lv1, new String[] {"image", "attrs", "name"}, 
	        		new int[]{R.id.iv, R.id.tv1, R.id.tv2});
	    m_lv.setAdapter(sa);
	}
	public String GetFileAttrs(File f){
		String str = "";
		if ( f.canRead() )
			str += "读 ";
		if ( f.canWrite() )
			str += "写 ";
		if ( f.canExecute() )
			str += "执行";
		if ( str.isEmpty() )
			str = "无权限";
		return str;
	}
	public File GetFileByIndex(int nIndex){
		if ( m_files == null )
			return null;
		int nCount = m_files.size();
		if ( nIndex<0 || nIndex>=nCount )
			return null;
		return m_files.get(nIndex);
	}
	public boolean isRoot(){
		if ( (m_strDir.compareTo(".") == 0) || (m_strDir.compareTo("./") == 0) )
			return true;
		return false;
	}
	public void goBack(){
		if ( isRoot() ){
			return ;
		}
		int nPos = m_strDir.lastIndexOf("/");
		String str = m_strDir.substring(0, nPos);
		File f = new File(str);
		AddFiles(f);
	}
	public int getFileImgId(String strFile){
		int nPos = strFile.lastIndexOf(".");
		if ( nPos == -1 || nPos == strFile.length()-1 )
			return R.drawable.file;
		int nPos1 = strFile.lastIndexOf("/");
		if ( nPos1 > nPos )
			return R.drawable.file;
		String strExt = strFile.substring(nPos+1);
		if ( strExt.compareToIgnoreCase("xml") == 0 )
			return R.drawable.xml;
		if ( strExt.compareToIgnoreCase("mp3") == 0 )
			return R.drawable.mp3;
		if ( strExt.compareToIgnoreCase("bat") == 0 )
			return R.drawable.bat;
		if ( strExt.compareToIgnoreCase("rc") == 0 )
			return R.drawable.rc;
		if ( strExt.compareToIgnoreCase("db") == 0 )
			return R.drawable.db;
		if ( strExt.compareToIgnoreCase("doc") == 0 )
			return R.drawable.doc;
		if ( strExt.compareToIgnoreCase("gif") == 0 )
			return R.drawable.gif;
		if ( strExt.compareToIgnoreCase("ico") == 0 )
			return R.drawable.ico;
		if ( strExt.compareToIgnoreCase("jpg") == 0
				|| strExt.compareToIgnoreCase("jpeg") == 0
				|| strExt.compareToIgnoreCase("bmp") == 0 )
			return R.drawable.jpg;
		if ( strExt.compareToIgnoreCase("png") == 0 )
			return R.drawable.png;
		return R.drawable.file;
	}
	public void showFileDlg(File f) {
		Intent in = new Intent(this, FileActivity.class);
		//Bundle b = new Bundle();
		//b.putString("filename", f.getPath());
		in.putExtra("filename", f.getPath());
		//in.putExtras(b);
		startActivity(in);
	}
}</span>
因为要对遍历的文件按照字母顺序排序,自定义一个比较类MyFileComparator;根据文件的扩展名设置ListView中显示的图标;点击ListView时,如果是文件夹则遍历并将列表清空后添加新的列表。

对于文件,则显示文件的部分内容(因为有的问价很大,加载完会把程序卡死),显示文件内容的Activity代码:

<span style="font-family:Microsoft YaHei;font-size:12px;">public class FileActivity extends Activity{
	
	private TextView m_tv = null;
	private MediaPlayer m_mp = null;
	private Intent m_it = new Intent("com.demo.SERVICE_PLAYER");
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
		setContentView(R.layout.titlebar);
		getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.titlebar);
		TextView tv = (TextView)findViewById(R.id.title_text);
		tv.setText("文件浏览");
		tv.setTextSize(20);
		tv = (TextView)findViewById(R.id.title_left_text);
		tv.setText("标题");
		tv.setTextSize(16);
		Button btn = (Button)findViewById(R.id.title_back);
		btn.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				finish();
			}
		});
		
		setContentView(R.layout.file_xml);
		m_tv = (TextView)findViewById(R.id.editText1);
		
		Intent in = getIntent();
		String strName = in.getStringExtra("filename");
		
		File f = new File(strName);
		long lSize = f.length();
		if ( lSize > 1024*1024 ){
			int nPos = strName.lastIndexOf('.');
			if ( nPos != -1 ){
				String strExt = strName.substring(nPos+1);
				if ( strExt.compareToIgnoreCase("mp3") == 0 ){
					m_it.putExtra("filename", strName);
					startService(m_it);
					Toast.makeText(this, "开始播放音乐", Toast.LENGTH_LONG).show();
					return ;
				}
			}
			
			Toast.makeText(this, "文件太大", Toast.LENGTH_LONG).show();
			
		}
		else
			ReadFile(f);
	}
	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		if ( m_mp != null ){
			m_mp.stop();
			m_mp.release();
		}
		stopService(m_it);
		super.onStop();
	}
	
	public void ReadFile(File f){
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(f);
			StringBuilder sb = new StringBuilder();
			int nBuffLen = 10*1024; //10KB
			byte[] buff = new byte[nBuffLen];
			while( true ){
				int nRead = fis.read(buff);
				if ( nRead<=0 )
					break;
				String str = new String(buff, 0, nRead);
				sb.append(str);
				if ( nRead<nBuffLen )
					break;
			}
			m_tv.setText(sb.toString());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch( IOException e ) {
			e.printStackTrace();
		}
		finally{
			if ( fis != null )
				try {
					fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
	}
	
}</span>

对于MP3文件,点击时创建服务播放,服务代码:

<span style="font-family:Microsoft YaHei;font-size:12px;">public class PlayerService extends Service{
	private static final String NAME = "PlayerService";
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		String strName = intent.getStringExtra("filename");
		playMp3(strName);
		Log.i(NAME, "onStartCommand");
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		initPlayer();
		super.onCreate();
		Log.i(NAME, "onCreate");
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		if ( m_player!=null ){
			m_player.stop();
			m_player.release();
		}
		Log.i(NAME, "onDestroy");
		super.onDestroy();
	}
	
	public void playMp3(String strName){
		if ( m_player == null )
			m_player = new MediaPlayer();
		else
			m_player.reset();
		try {
			m_player.setDataSource(strName);
			m_player.prepare();
			m_player.start();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void initPlayer(){
		m_player = new MediaPlayer();
		m_player.setOnCompletionListener(m_onCle);
		m_player.setOnPreparedListener(m_onPle);
	}

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		Log.i(NAME, "onBind");
		String strName = arg0.getStringExtra("filename");
		return null;
	}
	static public class OnCompletionListenerEx 
	implements OnCompletionListener{

		@Override
		public void onCompletion(MediaPlayer mp) {
			// TODO Auto-generated method stub
			
		}
		
	}
	static public class OnPreparedListenerEx
	implements OnPreparedListener{

		@Override
		public void onPrepared(MediaPlayer mp) {
			// TODO Auto-generated method stub
			
		}
		
	}
	private MediaPlayer m_player = null;
	private OnCompletionListenerEx m_onCle = new OnCompletionListenerEx();
	private OnPreparedListenerEx m_onPle = new OnPreparedListenerEx();
}</span>
<span style="font-family:Microsoft YaHei;font-size:12px;">
</span>

自定义标题栏方法:

<span style="font-family:Microsoft YaHei;font-size:12px;"><span style="white-space:pre">在</span>Activity的onCreate中设置自己的标题栏布局<span style="white-space:pre"></span></span><pre name="code" class="java">super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
		setContentView(R.layout.titlebar);
		getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.titlebar);



在styles.xml中添加自定义主题样式

<span style="font-family:Microsoft YaHei;font-size:12px;"> <style name="MyCustomTheme" parent="android:Theme">       
         <item name="android:windowBackground">@android:color/background_dark</item>  
         <item name="android:windowTitleSize">50dp</item>  
     </style></span>


然后在AndroidManifest.xml中设置自己的主题

<span style="font-family:Microsoft YaHei;font-size:12px;"><activity android:name=".FileActivity" 
            android:label="@string/text_file"
            android:theme="@style/MyCustomTheme" >
        </activity></span>





运行截图:



1
1

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:616989次
    • 积分:6399
    • 等级:
    • 排名:第3952名
    • 原创:104篇
    • 转载:53篇
    • 译文:0篇
    • 评论:175条
    打赏
    微信扫码
    最新评论