标签:des android style blog io color ar os sp
1 package com.supermario.filemanager; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileNotFoundException; 6 import java.io.FileOutputStream; 7 import java.io.IOException; 8 import java.util.ArrayList; 9 import java.util.HashMap; 10 import java.util.List; 11 12 import com.supermario.filemanager.MainActivity.FileAdapter.ViewHolder; 13 14 import android.app.AlertDialog; 15 import android.app.ListActivity; 16 import android.app.ProgressDialog; 17 import android.app.AlertDialog.Builder; 18 import android.content.BroadcastReceiver; 19 import android.content.Context; 20 import android.content.DialogInterface; 21 import android.content.Intent; 22 import android.content.IntentFilter; 23 import android.content.ServiceConnection; 24 import android.content.DialogInterface.OnClickListener; 25 import android.graphics.Bitmap; 26 import android.graphics.BitmapFactory; 27 import android.net.Uri; 28 import android.os.Bundle; 29 import android.os.Environment; 30 import android.util.Log; 31 import android.view.Gravity; 32 import android.view.LayoutInflater; 33 import android.view.View; 34 import android.view.ViewGroup; 35 import android.widget.AdapterView; 36 import android.widget.BaseAdapter; 37 import android.widget.EditText; 38 import android.widget.GridView; 39 import android.widget.ImageView; 40 import android.widget.LinearLayout; 41 import android.widget.ListView; 42 import android.widget.RadioButton; 43 import android.widget.RadioGroup; 44 import android.widget.SimpleAdapter; 45 import android.widget.TextView; 46 import android.widget.Toast; 47 import android.widget.AdapterView.OnItemClickListener; 48 import android.widget.AdapterView.OnItemLongClickListener; 49 50 public class MainActivity extends ListActivity implements OnItemLongClickListener{ 51 // 声明成员变量: 52 //存放显示的文件列表的名称 53 private List<String> mFileNames = null; 54 //存放显示的文件列表的相对应的路径 55 private List<String> mFilePaths = null; 56 //起始目录“/” 57 private String mRootPath = java.io.File.separator; 58 // SD卡根目录 59 private String mSDCard = Environment.getExternalStorageDirectory().toString(); 60 private String mOldFilePath = ""; 61 private String mNewFilePath = ""; 62 private String keyWords; 63 //用于显示当前路径 64 private TextView mPathTextView; 65 //用于放置工具栏 66 private GridView mToolbarGridView; 67 private int[] girdview_menu_image = {R.drawable.menu_phone,R.drawable.menu_sdcard,R.drawable.menu_search, 68 R.drawable.menu_create,R.drawable.menu_palse,R.drawable.menu_exit}; 69 private String[] gridview_menu_title = {"手机","SD卡","搜索","创建","粘贴","退出"}; 70 // 代表手机或SD卡,1代表手机,2代表SD卡 71 private static int menuPosition = 1; 72 73 @Override 74 public void onCreate(Bundle savedInstanceState) { 75 super.onCreate(savedInstanceState); 76 setContentView(R.layout.main); 77 mPathTextView = (TextView)findViewById(R.id.mPath); 78 mToolbarGridView = (GridView)findViewById(R.id.file_gridview_toolbar); 79 //一开始程序的时候加载手机目录下的文件列表 80 initFileListInfo(mRootPath); 81 //初始化菜单视图 82 initGridViewMenu(); 83 //初始化菜单监听器 84 initMenuListener(); 85 //为列表项绑定长按监听器 86 getListView().setOnItemLongClickListener(this); 87 88 89 90 } 91 92 public static String mCurrentFilePath=""; 93 private void initFileListInfo(String filePath) { 94 mCurrentFilePath = filePath; 95 //显示当前的路径 96 mPathTextView.setText(filePath); 97 mFileNames = new ArrayList<String>(); 98 mFilePaths = new ArrayList<String>(); 99 File mFile = new File(filePath); 100 //遍历出该文件夹路径下的所有文件/文件夹 101 File[] mFiles = mFile.listFiles(); 102 //只要当前路径不是手机根目录或者是sd卡根目录则显示“返回根目录”和“返回上一级” 103 if(menuPosition == 1&&!mCurrentFilePath.equals(mRootPath)){ 104 initAddBackUp(filePath,mRootPath); 105 }else if(menuPosition == 2&&!mCurrentFilePath.equals(mSDCard)){ 106 initAddBackUp(filePath,mSDCard); 107 } 108 109 /*将所有文件信息添加到集合中*/ 110 for(File mCurrentFile:mFiles){ 111 mFileNames.add(mCurrentFile.getName()); 112 mFilePaths.add(mCurrentFile.getPath()); 113 } 114 115 /*适配数据*/ 116 setListAdapter(new FileAdapter(MainActivity.this,mFileNames,mFilePaths)); 117 } 118 119 private boolean isAddBackUp = false; 120 private void initAddBackUp(String filePath,String phone_sdcard){ 121 if(!filePath.equals(phone_sdcard)){ 122 /*列表项的第一项设置为返回根目录*/ 123 mFileNames.add("BacktoRoot"); 124 mFilePaths.add(phone_sdcard); 125 126 /*列表项的第二项设置为返回上一级*/ 127 mFileNames.add("BacktoUp"); 128 //回到当前目录的父目录即回到上级 129 mFilePaths.add(new File(filePath).getParent()); 130 //将添加返回按键标识位置为true 131 isAddBackUp = true; 132 } 133 134 } 135 136 /**为GridView配饰菜单资源*/ 137 private void initGridViewMenu(){ 138 139 //设置选中时候的背景图片 140 mToolbarGridView.setSelector(R.drawable.menu_item_selected); 141 //设置背景图片 142 mToolbarGridView.setBackgroundResource(R.drawable.menu_background); 143 //设置列数 144 mToolbarGridView.setNumColumns(6); 145 //设置剧中对齐 146 mToolbarGridView.setGravity(Gravity.CENTER); 147 //设置水平,垂直间距为10 148 mToolbarGridView.setVerticalSpacing(10); 149 mToolbarGridView.setHorizontalSpacing(10); 150 //设置适配器 151 mToolbarGridView.setAdapter(getMenuAdapter(gridview_menu_title,girdview_menu_image)); 152 } 153 154 /**菜单项的监听*/ 155 protected void initMenuListener(){ 156 mToolbarGridView.setOnItemClickListener(new OnItemClickListener(){ 157 158 public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) { 159 switch(arg2) 160 { 161 //回到根目录 162 case 0: 163 menuPosition = 1; 164 initFileListInfo(mRootPath); 165 break; 166 //回到SD卡根目录 167 case 1: 168 menuPosition = 2; 169 initFileListInfo(mSDCard); 170 break; 171 //显示搜索对话框 172 case 2: 173 searchDilalog(); 174 break; 175 // //创建文件夹 176 case 3: 177 createFolder(); 178 break; 179 // //粘贴文件 180 case 4: 181 palseFile(); 182 break; 183 //退出 184 case 5: 185 MainActivity.this.finish(); 186 break; 187 } 188 } 189 }); 190 } 191 192 193 private String mNewFolderName = ""; 194 private File mCreateFile; 195 private RadioGroup mCreateRadioGroup; 196 private static int mChecked; 197 /**创建文件夹的方法:当用户点击软件下面的创建菜单的时候,是在当前目录下创建的一个文件夹 198 * 静态变量mCurrentFilePath存储的就是当前路径 199 * java.io.File.separator是JAVA给我们提供的一个File类中的静态成员,它会根据系统的不同来创建分隔符 200 * mNewFolderName正是我们要创建的新文件的名称,从EditText组件上得到的*/ 201 private void createFolder(){ 202 //用于标识当前选中的是文件或者文件夹 203 mChecked = 2; 204 LayoutInflater mLI = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 205 //初始化对话框布局 206 final LinearLayout mLL = (LinearLayout)mLI.inflate(R.layout.create_dialog, null); 207 mCreateRadioGroup = (RadioGroup)mLL.findViewById(R.id.radiogroup_create); 208 final RadioButton mCreateFileButton = (RadioButton)mLL.findViewById(R.id.create_file); 209 final RadioButton mCreateFolderButton = (RadioButton)mLL.findViewById(R.id.create_folder); 210 //设置默认为创建文件夹 211 mCreateFolderButton.setChecked(true); 212 //为按钮设置监听器 213 mCreateRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener(){ 214 //当选择改变时触发 215 public void onCheckedChanged(RadioGroup arg0, int arg1) { 216 if(arg1 == mCreateFileButton.getId()){ 217 mChecked = 1; 218 }else if(arg1 == mCreateFolderButton.getId()){ 219 mChecked = 2; 220 } 221 } 222 }); 223 //显示对话框 224 Builder mBuilder = new AlertDialog.Builder(MainActivity.this) 225 .setTitle("新建") 226 .setView(mLL) 227 .setPositiveButton("创建", new DialogInterface.OnClickListener(){ 228 public void onClick(DialogInterface dialog, int which) { 229 //或者用户输入的名称 230 mNewFolderName = ((EditText)mLL.findViewById(R.id.new_filename)).getText().toString(); 231 if(mChecked == 1){ 232 try { 233 mCreateFile = new File(mCurrentFilePath+java.io.File.separator+mNewFolderName+".txt"); 234 mCreateFile.createNewFile(); 235 //刷新当前目录文件列表 236 initFileListInfo(mCurrentFilePath); 237 } catch (IOException e) { 238 Toast.makeText(MainActivity.this, "文件名拼接出错..!!", Toast.LENGTH_SHORT).show(); 239 } 240 }else if(mChecked == 2){ 241 mCreateFile = new File(mCurrentFilePath+java.io.File.separator+mNewFolderName); 242 if(!mCreateFile.exists()&&!mCreateFile.isDirectory()&&mNewFolderName.length() != 0){ 243 if(mCreateFile.mkdirs()){ 244 //刷新当前目录文件列表 245 initFileListInfo(mCurrentFilePath); 246 }else{ 247 Toast.makeText(MainActivity.this, "创建失败,可能是系统权限不够,root一下?!", Toast.LENGTH_SHORT).show(); 248 } 249 }else{ 250 Toast.makeText(MainActivity.this, "文件名为空,还是重名了呢?", Toast.LENGTH_SHORT).show(); 251 } 252 } 253 } 254 }).setNeutralButton("取消", null); 255 mBuilder.show(); 256 } 257 /**粘贴*/ 258 private void palseFile(){ 259 mNewFilePath = mCurrentFilePath+java.io.File.separator+mCopyFileName;//得到新路径 260 Log.d("copy", "mOldFilePath is "+mOldFilePath+"| mNewFilePath is "+mNewFilePath+"| isCopy is "+isCopy); 261 if(!mOldFilePath.equals(mNewFilePath)&&isCopy == true){//在不同路径下复制才起效 262 if(!new File(mNewFilePath).exists()){ 263 copyFile(mOldFilePath,mNewFilePath); 264 Toast.makeText(MainActivity.this, "执行了粘贴", Toast.LENGTH_SHORT).show(); 265 initFileListInfo(mCurrentFilePath); 266 }else{ 267 new AlertDialog.Builder(MainActivity.this) 268 .setTitle("提示!") 269 .setMessage("该文件名已存在,是否要覆盖?") 270 .setPositiveButton("确定", new DialogInterface.OnClickListener(){ 271 public void onClick(DialogInterface dialog,int which){ 272 copyFile(mOldFilePath,mNewFilePath); 273 initFileListInfo(mCurrentFilePath); 274 } 275 }) 276 .setNegativeButton("取消", null).show(); 277 } 278 }else{ 279 Toast.makeText(MainActivity.this, "未复制文件!", Toast.LENGTH_LONG).show(); 280 } 281 } 282 283 private int i; 284 FileInputStream fis; 285 FileOutputStream fos; 286 //复制文件 287 private void copyFile(String oldFile,String newFile){ 288 try { 289 fis = new FileInputStream(oldFile); 290 fos = new FileOutputStream(newFile); 291 do{ 292 //逐个byte读取文件,并写入另一个文件中 293 if((i = fis.read()) != -1){ 294 fos.write(i); 295 } 296 }while(i != -1); 297 //关闭输入文件流 298 if(fis != null){ 299 fis.close(); 300 } 301 //关闭输出文件流 302 if(fos != null){ 303 fos.close(); 304 } 305 } catch (FileNotFoundException e) { 306 e.printStackTrace(); 307 } catch (IOException e) { 308 e.printStackTrace(); 309 } 310 } 311 312 /**菜单适配器*/ 313 private SimpleAdapter getMenuAdapter(String[] menuNameArray, 314 int[] imageResourceArray) { 315 //数组列表用于存放映射表 316 ArrayList<HashMap<String, Object>> mData = new ArrayList<HashMap<String, Object>>(); 317 for (int i = 0; i < menuNameArray.length; i++) { 318 HashMap<String, Object> mMap = new HashMap<String, Object>(); 319 //将“image”映射成图片资源 320 mMap.put("image", imageResourceArray[i]); 321 //将“title”映射成标题 322 mMap.put("title", menuNameArray[i]); 323 mData.add(mMap); 324 } 325 //新建简单适配器,设置适配器的布局文件,映射关系 326 SimpleAdapter mAdapter = new SimpleAdapter(this, mData,R.layout.item_menu, new String[] { "image", "title" },new int[] { R.id.item_image, R.id.item_text }); 327 return mAdapter; 328 } 329 /**列表项点击时的事件监听*/ 330 @Override 331 protected void onListItemClick(ListView listView, View view, int position, long id){ 332 final File mFile = new File(mFilePaths.get(position)); 333 //如果该文件是可读的,我们进去查看文件 334 if(mFile.canRead()){ 335 if(mFile.isDirectory()){ 336 //如果是文件夹,则直接进入该文件夹,查看文件目录 337 initFileListInfo(mFilePaths.get(position)); 338 } 339 else 340 { 341 openFile(mFile); 342 } 343 344 } 345 else 346 { 347 //如果该文件不可读,我们给出提示不能访问,防止用户操作系统文件造成系统崩溃等 348 Toast.makeText(MainActivity.this, "对不起,您的访问权限不足!", Toast.LENGTH_SHORT).show(); 349 } 350 } 351 352 /**调用系统的方法,来打开文件的方法*/ 353 private void openFile(File file){ 354 if(file.isDirectory()){ 355 initFileListInfo(file.getPath()); 356 }else{ 357 Intent intent = new Intent(); 358 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 359 intent.setAction(android.content.Intent.ACTION_VIEW); 360 //设置当前文件类型 361 intent.setDataAndType(Uri.fromFile(file), getMIMEType(file)); 362 startActivity(intent); 363 } 364 } 365 /**获得MIME类型的方法*/ 366 private String getMIMEType(File file){ 367 String type = ""; 368 String fileName = file.getName(); 369 //取出文件后缀名并转成小写 370 String fileEnds = fileName.substring(fileName.lastIndexOf(".")+1,fileName.length()).toLowerCase(); 371 if(fileEnds.equals("m4a")||fileEnds.equals("mp3")||fileEnds.equals("mid")||fileEnds.equals("xmf")||fileEnds.equals("ogg")||fileEnds.equals("wav")){ 372 type = "audio/*";// 系统将列出所有可能打开音频文件的程序选择器 373 }else if(fileEnds.equals("3gp")||fileEnds.equals("mp4")){ 374 type = "video/*";// 系统将列出所有可能打开视频文件的程序选择器 375 }else if(fileEnds.equals("jpg")||fileEnds.equals("gif")||fileEnds.equals("png")||fileEnds.equals("jpeg")||fileEnds.equals("bmp")){ 376 type = "image/*";// 系统将列出所有可能打开图片文件的程序选择器 377 }else{ 378 type = "*/*"; // 系统将列出所有可能打开该文件的程序选择器 379 } 380 return type; 381 } 382 383 384 //长按列表项的事件监听:对长按需要进行一个控制,当列表中包括”返回根目录“和”返回上一级“时,需要对这两列进行屏蔽 385 386 @Override 387 public boolean onItemLongClick(AdapterView<?> arg0, View arg1, final int position, long arg3) { 388 if(isAddBackUp == true){//说明存在返回根目录和返回上一级两列,接下来要对这两列进行屏蔽 389 if(position != 0 && position != 1){ 390 initItemLongClickListener(new File(mFilePaths.get(position))); 391 } 392 } 393 else{ 394 initItemLongClickListener(new File(mFilePaths.get(position))); 395 } 396 return false; 397 } 398 399 private String mCopyFileName; 400 private boolean isCopy = false; 401 /**长按文件或文件夹时弹出的带ListView效果的功能菜单*/ 402 private void initItemLongClickListener(final File file){ 403 OnClickListener listener = new DialogInterface.OnClickListener(){ 404 //item的值就是从0开始的索引值(从列表的第一项开始) 405 public void onClick(DialogInterface dialog, int item) { 406 if(file.canRead()){//注意,所有对文件的操作必须是在该文件可读的情况下才可以,否则报错 407 if(item == 0){//复制 408 if(file.isFile()&&"txt".equals((file.getName().substring(file.getName().lastIndexOf(".")+1, file.getName().length())).toLowerCase())){ 409 Toast.makeText(MainActivity.this, "已复制!", Toast.LENGTH_SHORT).show(); 410 //复制标志位,表明已复制文件 411 isCopy = true; 412 //取得复制文件的名字 413 mCopyFileName = file.getName(); 414 //记录复制文件的路径 415 mOldFilePath = mCurrentFilePath+java.io.File.separator+mCopyFileName; 416 }else{ 417 Toast.makeText(MainActivity.this, "对不起,目前只支持复制文本文件!", Toast.LENGTH_SHORT).show(); 418 } 419 }else if(item == 1){//重命名 420 initRenameDialog(file); 421 }else if(item == 2){//删除 422 initDeleteDialog(file); 423 } 424 }else{ 425 Toast.makeText(MainActivity.this, "对不起,您的访问权限不足!", Toast.LENGTH_SHORT).show(); 426 } 427 } 428 }; 429 //列表项名称 430 String[] mMenu = {"复制","重命名","删除"}; 431 //显示操作选择对话框 432 new AlertDialog.Builder(MainActivity.this) 433 .setTitle("请选择操作!") 434 .setItems(mMenu, listener) 435 .setPositiveButton("取消",null).show(); 436 } 437 438 439 440 EditText mET; 441 //显示重命名对话框 442 private void initRenameDialog(final File file){ 443 LayoutInflater mLI = LayoutInflater.from(MainActivity.this); 444 //初始化重命名对话框 445 LinearLayout mLL = (LinearLayout)mLI.inflate(R.layout.rename_dialog, null); 446 mET = (EditText)mLL.findViewById(R.id.new_filename); 447 //显示当前的文件名 448 mET.setText(file.getName()); 449 //设置监听器 450 OnClickListener listener = new DialogInterface.OnClickListener(){ 451 public void onClick(DialogInterface dialog,int which){ 452 String modifyName = mET.getText().toString(); 453 final String modifyFilePath = file.getParentFile().getPath()+java.io.File.separator; 454 final String newFilePath = modifyFilePath+modifyName; 455 //判断该新的文件名是否已经在当前目录下存在 456 if(new File(newFilePath).exists()){ 457 if(!modifyName.equals(file.getName())){//把“重命名”操作时没做任何修改的情况过滤掉 458 //弹出该新命名后的文件已经存在的提示,并提示接下来的操作 459 new AlertDialog.Builder(MainActivity.this) 460 .setTitle("提示!") 461 .setMessage("该文件名已存在,是否要覆盖?") 462 .setPositiveButton("确定", new DialogInterface.OnClickListener(){ 463 public void onClick(DialogInterface dialog,int which){ 464 file.renameTo(new File(newFilePath)); 465 Toast.makeText(MainActivity.this, 466 "the file path is "+new File(newFilePath), Toast.LENGTH_SHORT).show(); 467 //更新当前目录信息 468 initFileListInfo(file.getParentFile().getPath()); 469 } 470 }) 471 .setNegativeButton("取消", null).show(); 472 } 473 }else{ 474 //文件名不重复时直接修改文件名后再次刷新列表 475 file.renameTo(new File(newFilePath)); 476 initFileListInfo(file.getParentFile().getPath()); 477 } 478 } 479 480 }; 481 //显示对话框 482 AlertDialog renameDialog = new AlertDialog.Builder(MainActivity.this).create(); 483 renameDialog.setView(mLL); 484 renameDialog.setButton("确定", listener); 485 renameDialog.setButton2("取消", new DialogInterface.OnClickListener(){ 486 public void onClick(DialogInterface dialog,int which){ 487 //什么都不做,关闭当前对话框 488 } 489 }); 490 renameDialog.show(); 491 } 492 493 //弹出删除文件/文件夹的对话框 494 private void initDeleteDialog(final File file){ 495 new AlertDialog.Builder(MainActivity.this) 496 .setTitle("提示!") 497 .setMessage("您确定要删除该"+(file.isDirectory()?"文件夹":"文件")+"吗?") 498 .setPositiveButton("确定", new DialogInterface.OnClickListener(){ 499 public void onClick(DialogInterface dialog,int which){ 500 if(file.isFile()){ 501 //是文件则直接删除 502 file.delete(); 503 }else{ 504 //是文件夹则用这个方法删除 505 deleteFolder(file); 506 } 507 //重新遍历该文件的父目录 508 initFileListInfo(file.getParent()); 509 } 510 }) 511 .setNegativeButton("取消", null).show(); 512 } 513 514 //删除文件夹的方法(递归删除该文件夹下的所有文件) 515 public void deleteFolder(File folder){ 516 File[] fileArray = folder.listFiles(); 517 if(fileArray.length == 0){ 518 //空文件夹则直接删除 519 folder.delete(); 520 }else{ 521 //遍历该目录 522 for(File currentFile:fileArray){ 523 if(currentFile.exists()&¤tFile.isFile()){ 524 //文件则直接删除 525 currentFile.delete(); 526 }else{ 527 //递归删除 528 deleteFolder(currentFile); 529 } 530 } 531 folder.delete(); 532 } 533 } 534 535 Intent serviceIntent; 536 ServiceConnection mSC; 537 RadioGroup mRadioGroup; 538 static int mRadioChecked; 539 public static final String KEYWORD_BROADCAST = "com.supermario.file.KEYWORD_BROADCAST"; 540 //显示搜索对话框 541 private void searchDilalog(){ 542 //用于确定是在当前目录搜索或者是在整个目录搜索的标志 543 mRadioChecked = 1; 544 LayoutInflater mLI = LayoutInflater.from(MainActivity.this); 545 final View mLL = (View)mLI.inflate(R.layout.search_dialog, null); 546 mRadioGroup = (RadioGroup)mLL.findViewById(R.id.radiogroup_search); 547 final RadioButton mCurrentPathButton = (RadioButton)mLL.findViewById(R.id.radio_currentpath); 548 final RadioButton mWholePathButton = (RadioButton)mLL.findViewById(R.id.radio_wholepath); 549 //设置默认选择在当前路径搜 550 mCurrentPathButton.setChecked(true); 551 mRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener(){ 552 //当选择改变时触发 553 public void onCheckedChanged(RadioGroup radiogroup, int checkId) { 554 //当前路径的标志为1 555 if(checkId == mCurrentPathButton.getId()){ 556 mRadioChecked = 1; 557 //整个目录的标志为2 558 }else if(checkId == mWholePathButton.getId()){ 559 mRadioChecked = 2; 560 } 561 } 562 }); 563 Builder mBuilder = new AlertDialog.Builder(MainActivity.this) 564 .setTitle("搜索").setView(mLL) 565 .setPositiveButton("确定", new OnClickListener(){ 566 public void onClick(DialogInterface arg0, int arg1) { 567 keyWords = ((EditText)mLL.findViewById(R.id.edit_search)).getText().toString(); 568 if(keyWords.length() == 0){ 569 Toast.makeText(MainActivity.this, "关键字不能为空!", Toast.LENGTH_SHORT).show(); 570 searchDilalog(); 571 }else{ 572 if(menuPosition == 1){ 573 mPathTextView.setText(mRootPath); 574 }else{ 575 mPathTextView.setText(mSDCard); 576 } 577 //获取用户输入的关键字并发送广播-开始 578 Intent keywordIntent = new Intent(); 579 keywordIntent.setAction(KEYWORD_BROADCAST); 580 //传递搜索的范围区间:1.当前路径下搜索 2.SD卡下搜索 581 if(mRadioChecked == 1){ 582 keywordIntent.putExtra("searchpath", mCurrentFilePath); 583 }else{ 584 keywordIntent.putExtra("searchpath", mSDCard); 585 } 586 //传递关键字 587 keywordIntent.putExtra("keyword", keyWords); 588 //到这里为止是携带关键字信息并发送了广播,会在Service服务当中接收该广播并提取关键字进行搜索 589 getApplicationContext().sendBroadcast(keywordIntent); 590 serviceIntent = new Intent("com.android.service.FILE_SEARCH_START"); 591 MainActivity.this.startService(serviceIntent);//开启服务,启动搜索 592 isComeBackFromNotification = false; 593 } 594 } 595 }) 596 .setNegativeButton("取消", null); 597 mBuilder.create().show(); 598 } 599 600 /**注册广播*/ 601 private IntentFilter mFilter; 602 private FileBroadcast mFileBroadcast; 603 private IntentFilter mIntentFilter; 604 private SearchBroadCast mServiceBroadCast; 605 @Override 606 protected void onStart() { 607 super.onStart(); 608 mFilter = new IntentFilter(); 609 mFilter.addAction(FileService.FILE_SEARCH_COMPLETED); 610 mFilter.addAction(FileService.FILE_NOTIFICATION); 611 mIntentFilter = new IntentFilter(); 612 mIntentFilter.addAction(KEYWORD_BROADCAST); 613 if(mFileBroadcast == null){ 614 mFileBroadcast = new FileBroadcast(); 615 } 616 if(mServiceBroadCast == null){ 617 mServiceBroadCast = new SearchBroadCast(); 618 } 619 this.registerReceiver(mFileBroadcast, mFilter); 620 this.registerReceiver(mServiceBroadCast, mIntentFilter); 621 } 622 623 624 /**注销广播*/ 625 @Override 626 protected void onDestroy() { 627 super.onDestroy(); 628 Log.d("NullPointError", "onDestroy"); 629 mFileNames.clear(); 630 mFilePaths.clear(); 631 this.unregisterReceiver(mFileBroadcast); 632 this.unregisterReceiver(mServiceBroadCast); 633 } 634 635 private String mAction; 636 public static boolean isComeBackFromNotification = false; 637 /**内部广播类*/ 638 class FileBroadcast extends BroadcastReceiver{ 639 @Override 640 public void onReceive(Context context, Intent intent) { 641 mAction = intent.getAction(); 642 // 搜索完毕的广播 643 if(FileService.FILE_SEARCH_COMPLETED.equals(mAction)){ 644 mFileNames = intent.getStringArrayListExtra("mFileNameList"); 645 mFilePaths = intent.getStringArrayListExtra("mFilePathsList"); 646 Toast.makeText(MainActivity.this, "搜索完毕!", Toast.LENGTH_SHORT).show(); 647 //这里搜索完毕之后应该弹出一个弹出框提示用户要不要显示数据 648 searchCompletedDialog("搜索完毕,是否马上显示结果?"); 649 getApplicationContext().stopService(serviceIntent);//当搜索完毕的时候停止服务,然后在服务中取消通知 650 // 点击通知栏跳转过来的广播 651 }else if(FileService.FILE_NOTIFICATION.equals(mAction)){//点击通知回到当前Activity,读取其中信息 652 String mNotification = intent.getStringExtra("notification"); 653 Toast.makeText(MainActivity.this, mNotification, Toast.LENGTH_LONG).show(); 654 searchCompletedDialog("你确定要取消搜索吗?"); 655 } 656 } 657 } 658 659 //搜索完毕和点击通知过来时的提示框 660 private void searchCompletedDialog(String message){ 661 Builder searchDialog = new AlertDialog.Builder(MainActivity.this) 662 .setTitle("提示") 663 .setMessage(message) 664 .setPositiveButton("确定", new OnClickListener(){ 665 public void onClick(DialogInterface dialog,int which) { 666 //当弹出框时,需要对这个确定按钮进行一个判断,因为要对不同的情况做不同的处理(2种情况) 667 // 1.搜索完毕 668 // 2.取消搜索 669 if(FileService.FILE_SEARCH_COMPLETED.equals(mAction)){ 670 if(mFileNames.size() == 0){ 671 Toast.makeText(MainActivity.this, "无相关文件/文件夹!", Toast.LENGTH_SHORT).show(); 672 setListAdapter(new FileAdapter(MainActivity.this,mFileNames,mFilePaths));//清空列表 673 }else{ 674 //显示文件列表 675 setListAdapter(new FileAdapter(MainActivity.this,mFileNames,mFilePaths)); 676 } 677 }else{ 678 //设置搜索标志为true, 679 isComeBackFromNotification = true; 680 //关闭服务,取消搜索 681 getApplicationContext().stopService(serviceIntent); 682 } 683 } 684 }) 685 .setNegativeButton("取消", null); 686 searchDialog.create(); 687 searchDialog.show(); 688 } 689 690 691 692 693 class FileAdapter extends BaseAdapter{ 694 //返回键,各种格式的文件的图标 695 private Bitmap mBackRoot; 696 private Bitmap mBackUp; 697 private Bitmap mImage; 698 private Bitmap mAudio; 699 private Bitmap mRar; 700 private Bitmap mVideo; 701 private Bitmap mFolder; 702 private Bitmap mApk; 703 private Bitmap mOthers; 704 private Bitmap mTxt; 705 private Bitmap mWeb; 706 private Context mContext; 707 //文件名列表 708 private List<String> mFileNameList; 709 //文件对应的路径列表 710 private List<String> mFilePathList; 711 712 public FileAdapter(Context context,List<String> fileName,List<String> filePath){ 713 mContext = context; 714 mFileNameList = fileName; 715 mFilePathList = filePath; 716 //初始化图片资源 717 //返回到根目录 718 mBackRoot = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.back_to_root); 719 //返回到上一级目录 720 mBackUp = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.back_to_up); 721 //图片文件对应的icon 722 mImage = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.image); 723 //音频文件对应的icon 724 mAudio = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.audio); 725 //视频文件对应的icon 726 mVideo = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.video); 727 //可执行文件对应的icon 728 mApk = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.apk); 729 //文本文档对应的icon 730 mTxt = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.txt); 731 //其他类型文件对应的icon 732 mOthers = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.others); 733 //文件夹对应的icon 734 mFolder = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.folder); 735 //zip文件对应的icon 736 mRar = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.zip_icon); 737 //网页文件对应的icon 738 mWeb = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.web_browser); 739 } 740 //获得文件的总数 741 @Override 742 public int getCount() { 743 return mFilePathList.size(); 744 } 745 //获得当前位置对应的文件名 746 @Override 747 public Object getItem(int position) { 748 return mFileNameList.get(position); 749 } 750 //获得当前的位置 751 @Override 752 public long getItemId(int position) { 753 return position; 754 } 755 //获得视图 756 @Override 757 public View getView(int position, View convertView, ViewGroup viewgroup) { 758 ViewHolder viewHolder = null; 759 if (convertView == null) { 760 viewHolder = new ViewHolder(); 761 LayoutInflater mLI = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 762 //初始化列表元素界面 763 convertView = mLI.inflate(R.layout.list_child, null); 764 //获取列表布局界面元素 765 viewHolder.mIV = (ImageView)convertView.findViewById(R.id.image_list_childs); 766 viewHolder.mTV = (TextView)convertView.findViewById(R.id.text_list_childs); 767 //将每一行的元素集合设置成标签 768 convertView.setTag(viewHolder); 769 } else { 770 //获取视图标签 771 viewHolder = (ViewHolder) convertView.getTag(); 772 } 773 File mFile = new File(mFilePathList.get(position).toString()); 774 //如果 775 if(mFileNameList.get(position).toString().equals("BacktoRoot")){ 776 //添加返回根目录的按钮 777 viewHolder.mIV.setImageBitmap(mBackRoot); 778 viewHolder.mTV.setText("返回根目录"); 779 }else if(mFileNameList.get(position).toString().equals("BacktoUp")){ 780 //添加返回上一级菜单的按钮 781 viewHolder.mIV.setImageBitmap(mBackUp); 782 viewHolder.mTV.setText("返回上一级"); 783 }else if(mFileNameList.get(position).toString().equals("BacktoSearchBefore")){ 784 //添加返回搜索之前目录的按钮 785 viewHolder.mIV.setImageBitmap(mBackRoot); 786 viewHolder.mTV.setText("返回搜索之前目录"); 787 }else{ 788 String fileName = mFile.getName(); 789 viewHolder.mTV.setText(fileName); 790 if(mFile.isDirectory()){ 791 viewHolder.mIV.setImageBitmap(mFolder); 792 }else{ 793 String fileEnds = fileName.substring(fileName.lastIndexOf(".")+1,fileName.length()).toLowerCase();//取出文件后缀名并转成小写 794 if(fileEnds.equals("m4a")||fileEnds.equals("mp3")||fileEnds.equals("mid")||fileEnds.equals("xmf")||fileEnds.equals("ogg")||fileEnds.equals("wav")){ 795 viewHolder.mIV.setImageBitmap(mVideo); 796 }else if(fileEnds.equals("3gp")||fileEnds.equals("mp4")){ 797 viewHolder.mIV.setImageBitmap(mAudio); 798 }else if(fileEnds.equals("jpg")||fileEnds.equals("gif")||fileEnds.equals("png")||fileEnds.equals("jpeg")||fileEnds.equals("bmp")){ 799 viewHolder.mIV.setImageBitmap(mImage); 800 }else if(fileEnds.equals("apk")){ 801 viewHolder.mIV.setImageBitmap(mApk); 802 }else if(fileEnds.equals("txt")){ 803 viewHolder.mIV.setImageBitmap(mTxt); 804 }else if(fileEnds.equals("zip")||fileEnds.equals("rar")){ 805 viewHolder.mIV.setImageBitmap(mRar); 806 }else if(fileEnds.equals("html")||fileEnds.equals("htm")||fileEnds.equals("mht")){ 807 viewHolder.mIV.setImageBitmap(mWeb); 808 }else { 809 viewHolder.mIV.setImageBitmap(mOthers); 810 } 811 } 812 } 813 return convertView; 814 } 815 //用于存储列表每一行元素的图片和文本 816 class ViewHolder { 817 ImageView mIV; 818 TextView mTV; 819 } 820 821 822 } 823 824 825 826 } 827 828 829
MainActivity.java
package com.supermario.filemanager; import java.io.File; import java.util.ArrayList; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Intent; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.util.Log; public class FileService extends Service { private Looper mLooper; private FileHandler mFileHandler; private ArrayList<String> mFileName = null; private ArrayList<String> mFilePaths = null; public static final String FILE_SEARCH_COMPLETED = "com.supermario.file.FILE_SEARCH_COMPLETED"; public static final String FILE_NOTIFICATION = "com.supermario.file.FILE_NOTIFICATION"; @Override public IBinder onBind(Intent arg0) { return null; } //创建服务 @Override public void onCreate() { super.onCreate(); Log.d("FileService", "file service is onCreate"); //新建处理线程 HandlerThread mHT = new HandlerThread("FileService",HandlerThread.NORM_PRIORITY); mHT.start(); mLooper = mHT.getLooper(); mFileHandler = new FileHandler(mLooper); } //服务开始 @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); Log.d("FileService", "file service is onStart"); mFileName = new ArrayList<String>(); mFilePaths = new ArrayList<String>(); mFileHandler.sendEmptyMessage(0); //发出通知表明正在进行搜索 fileSearchNotification(); } @Override public void onDestroy() { super.onDestroy(); //取消通知 mNF.cancel(R.string.app_name); } class FileHandler extends Handler{ public FileHandler(Looper looper){ super(looper); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); Log.d("FileService", "file service is handleMessage"); //在指定范围搜索 initFileArray(new File(SearchBroadCast.mServiceSearchPath)); //当用户点击了取消搜索则不发生广播 if(!MainActivity.isComeBackFromNotification == true){ Intent intent = new Intent(FILE_SEARCH_COMPLETED); intent.putStringArrayListExtra("mFileNameList", mFileName); intent.putStringArrayListExtra("mFilePathsList", mFilePaths); //搜索完毕之后携带数据并发送广播 sendBroadcast(intent); } } } private int m = -1; /**具体做搜索事件的可回调函数*/ private void initFileArray(File file){ Log.d("FileService", "currentArray is "+file.getPath()); //只能遍历可读的文件夹,否则会报错 if(file.canRead()){ File[] mFileArray = file.listFiles(); for(File currentArray:mFileArray){ if(currentArray.getName().indexOf(SearchBroadCast.mServiceKeyword) != -1){ if (m == -1) { m++; // 返回搜索之前目录 mFileName.add("BacktoSearchBefore"); mFilePaths.add(MainActivity.mCurrentFilePath); } mFileName.add(currentArray.getName()); mFilePaths.add(currentArray.getPath()); } //如果是文件夹则回调该方法 if(currentArray.exists()&¤tArray.isDirectory()){ //如果用户取消了搜索,应该停止搜索的过程 if(MainActivity.isComeBackFromNotification == true){ return; } initFileArray(currentArray); } } } } NotificationManager mNF; /**通知*/ private void fileSearchNotification(){ Notification mNotification = new Notification(R.drawable.logo,"后台搜索中...",System.currentTimeMillis()); Intent intent = new Intent(FILE_NOTIFICATION); //打开notice时的提示内容 intent.putExtra("notification", "当通知还存在,说明搜索未完成,可以在这里触发一个事件,当点击通知回到Activity之后,可以弹出一个框,提示是否取消搜索!"); PendingIntent mPI = PendingIntent.getBroadcast(this,0,intent,0); mNotification.setLatestEventInfo(this, "在"+SearchBroadCast.mServiceSearchPath+"下搜索", "搜索关键字为"+SearchBroadCast.mServiceKeyword+"【点击可取消搜索】", mPI); if(mNF == null){ mNF = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); } mNF.notify(R.string.app_name, mNotification); } }
FileService.JAVA 搜索服务
package com.supermario.filemanager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; public class SearchBroadCast extends BroadcastReceiver { public static String mServiceKeyword = "";//接收搜索关键字的静态变量 public static String mServiceSearchPath = "";//接收搜索路径的静态变量 @Override public void onReceive(Context context, Intent intent) { //取得intent String mAction = intent.getAction(); if(MainActivity.KEYWORD_BROADCAST.equals(mAction)){ //取得intent传递过来的信息 mServiceKeyword = intent.getStringExtra("keyword"); mServiceSearchPath = intent.getStringExtra("searchpath"); } } }
SearchBroadCast.JAVA
标签:des android style blog io color ar os sp
原文地址:http://www.cnblogs.com/hixin/p/4098299.html