Android网络:开发浏览器(五)——功能完善之保存图片实现

 

最近几天开学,所以没有更新博客。今天开始更新。最近我打算每天抽出一些事件看点Thinkin Java这本书,仔细研究下java,当然也会出这个博客关于Think in java系列的博客,大家可以一起研究下。

 

不多说,正式进入主题。这篇主要叙述的是关于保存图片的具体功能实现。

 

我们先来看看UC的

       

图10.2.13   UC保存图片对话框

图10.2.14   UC文件管理

       

        我们可以看到UC在点击“保存图片”选项后,弹出了一个保存图片的对话框

        既然有了参照物,那么我们就首先来进行界面的实现。

       

        为了简单起见,对话框的编写仍旧采用AlertDialog的构建,只需要替换其中的布 局文件就可以了。我们可以简单的将内容的View采用LinearLayout,其中包含两个 LinearLayout,具体的看下面的xml布局配置文件:

       

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:layout_margin="5dp"

    android:background="@android:color/white"

    android:orientation="vertical">

   

    <LinearLayout

       android:id="@+id/dialog_fileName"

       android:layout_width="match_parent"

       android:layout_height="30dp"

       android:orientation="horizontal"

       android:layout_marginTop="30dp"

       android:layout_marginLeft="10dp"

       android:layout_marginRight="10dp"

       android:background="@drawable/dialog_back"

       >

 

        <TextView

           android:id="@+id/dialog_fileName_title"

           android:layout_width="80dp"

           android:layout_height="match_parent"

           android:gravity="center"

           android:textSize="15sp"

           android:text="@string/fileName"

           android:layout_marginLeft="5dp"

           android:layout_marginTop="5dp"

           android:layout_marginBottom="5dp"

           />

 

        <EditText

           android:id="@+id/dialog_fileName_input"

           android:layout_width="match_parent"

           android:layout_height="match_parent"

           android:hint="@string/blank"

           android:layout_marginRight="5dp"

           android:layout_marginTop="5dp"

           android:layout_marginBottom="5dp"

           android:background="@null"

           />

    </LinearLayout>

   

    <LinearLayout

       android:id="@+id/dialog_savePath"

       android:layout_width="match_parent"

       android:layout_height="wrap_content"

       android:orientation="horizontal"

       android:layout_marginLeft="10dp"

       android:layout_marginRight="10dp"

       android:layout_marginTop="20dp"

       android:layout_marginBottom="30dp"

       android:background="@drawable/dialog_back"

       >

       

        <TextView

           android:id="@+id/dialog_savePath_title"

           android:layout_width="80dp"

           android:layout_height="match_parent"

           android:gravity="center"

           android:textSize="15sp"

           android:text="@string/savePath"

           android:layout_marginLeft="5dp"

           android:layout_marginTop="5dp"

           android:layout_marginBottom="5dp"

           />

 

        <TextView

           android:id="@+id/dialog_savePath_enter"

           android:layout_width="match_parent"

           android:layout_height="match_parent"

           android:hint="@string/defaultPath"

           android:text="@string/defaultPath"

           android:layout_marginRight="5dp"

           android:layout_marginTop="5dp"

           android:layout_marginBottom="5dp"

           android:background="@null"

           />

    </LinearLayout>

   

</LinearLayout>

代码片段10.2.36 保存图片对话框的xml布局文件

       

        具体的预览效果如下:

       

图10.2.15   对话框内容预览图

       

        因为我们没有权限在手机内存中进行相关操作,所以为了方便起见,我们所有的路    径基础都是以sdcad的路径为基础的。

       

        现在有了保存的界面,我们就可以编写关于文件管理的界面了。不过为了管理方便,  我们将所有的文件操作都放到file包下。现在我们只需要两种操作即可,分别为文件 列表展示与图片下载操作。图片下载先不管他,我们先进行文件展示方面的编写。

       

        文件展示因为需要耗费一定的时间,Android建议我们将所有的耗时操作都放到子 线程中进行。所以,我通过继承了AsynTask类来进行文件展示的操作。

       

        这里需要注意的是所有的耗时操作都是放在doInBackground这个方法当中的,  并且不能将UI线程中的操作放在这个类中,否则会报错。

     

      现在我将这个文件展示类的具体代码放上来:

     

package com.example.file;

 

import java.io.File;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.Collections;

import java.util.HashMap;

import java.util.List;

import java.util.Locale;

 

import android.app.Activity;

import android.app.AlertDialog;

import android.app.Dialog;

import android.os.AsyncTask;

import android.os.Environment;

import android.util.Log;

import android.widget.ListView;

import android.widget.SimpleAdapter;

 

import com.example.androidstudy_web.R;

import com.example.util.SortComparator;

 

/**

 * 文件管理类

 * @version     1.0

 * @author     本人dddd牛仔

 * <hr/>

 * */

public class FileShowManager extends AsyncTask<String, String,List<HashMap<String, Object>>>{

 

   private static final String DEG_TAG ="webbrowser_FileManager";

   public static final String SDCARD_HOME = Environment.getExternalStorageDirectory().toString();

   public static final String DEFAULT_PATH =SDCARD_HOME + "/webbrowserX/download/";

  

   public enum SORTTYPE {

      LETTER, DATE,CHILDNUMS

   }

  

   private Activityactivity;

  

   private ListViewfileList;

  

   private DialogwaitDialog;

  

   public FileShowManager(Activity activity, ListViewfileListView){

      this.activity = activity;

      this.fileList = fileListView;

   }

  

   @Override

   protected void onPreExecute() {

      //初始化控件

      this.waitDialog =new AlertDialog.Builder(this.activity)

         .setMessage("正在加载中...")

         .create();

      this.waitDialog.setCancelable(false);

      this.waitDialog.setCanceledOnTouchOutside(false);

      this.waitDialog.show();

      super.onPreExecute();

   }

 

   @Override

   protected List<HashMap<String, Object>>doInBackground(String... params) {

      List<HashMap<String, Object>> fileLists =buildListForAdapter(params[0]);

      //默认以首字母排序

      this.sortByKey(fileLists, SORTTYPE.LETTER);

      return fileLists;

   }

 

   @Override

   protected void onPostExecute(List<HashMap<String, Object>>result) {

      //初始化数据

      this.initData(result);

      fileList.invalidate();

      this.waitDialog.dismiss();

      super.onPostExecute(result);

   }

  

   /**

    * 初始化数据

    * */

   public void initData(List<HashMap<String, Object>>fileLists){

      SimpleAdapter adapter = new  

SimpleAdapter(this.activity.getApplicationContext(),fileLists,

            R.layout.filemanager_list_item,

            new String[]{"name","path","childnums","date","img"},

            new int[]{R.id.filemanager_item_info_name,R.id.filemanager_item_filePath,

            R.id.filemanager_item_info_numsAndDate_nums,R.id.filemanager_item_info_numsAndDate_date,

                R.id.filemanager_item_icon});

      this.fileList.setAdapter(adapter);

   }

  

   /**

    * 构建文件List的适配器

    * @param path    文件路径

    * */

   public List<HashMap<String, Object>>buildListForAdapter(String path){

      List<HashMap<String, Object>> list = newArrayList<HashMap<String,Object>>();

      File rootFile = new File(path);

      if(!rootFile.exists()){

         //以默认位置打开

         rootFile = new File(DEFAULT_PATH);

         if(!rootFile.exists()){

            //默认位置不存在,进行创建

            rootFile.mkdirs();

         }

      }

      File[] currentPathFiles = rootFile.listFiles();

      Log.d(DEG_TAG,DEFAULT_PATH+":"+currentPathFiles);

      if(!path.equals(SDCARD_HOME)){

         HashMap<String, Object> root = new HashMap<String,Object>();

         root.put("name", "/");

         root.put("img", R.drawable.floder_home_back);

         root.put("path", SDCARD_HOME);

         root.put("childnums","返回根目录");

         root.put("date", "");

         list.add(root);

         HashMap<String, Object> pmap = new HashMap<String,  

Object>();

         pmap.put("name", "..");

         pmap.put("img", R.drawable.floder_up_back);

         pmap.put("path", rootFile.getParent());

         pmap.put("childnums","返回上一级");

         pmap.put("date", "");

         list.add(pmap);

      }

      if(currentPathFiles!=null){

         //如果存在子文件则进行遍历

         for (File file : currentPathFiles){

            //根据是否为文件夹选择不同的图标

            if(file.isDirectory()){

                HashMap<String, Object> item = new HashMap<String,Object>();

                item.put("img", R.drawable.floder_back);

                item.put("name", file.getName());

                item.put("path", file.getPath());

                item.put("childnums","共有"+this.getDirectoryNums(file)+"");

                item.put("date",new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.CHINA).format(file.lastModified()));

                list.add(item);

            }

         }

      }

      return list;

   }

  

   /**

    * 统计文件夹中的文件夹数量

    * @param directory文件夹

    * */

   public int getDirectoryNums(File directory){

      if(directory.isDirectory()){

         File[] files = directory.listFiles();

         return this.getDirectoryNums(files);

      }

      return -1;

   }

  

   /**

    * 统计文件夹中的文件夹数量

    * @param files   文件夹下的所有文件

    * */

   public int getDirectoryNums(File[] files){

      int nums = 0;

      if(files!=null){

         for(File file : files){

            if(file.isDirectory()){

                nums++;

            }

         }

      }

      return nums;

   }

  

   /**

    * List排序

    * @param lists   待排序的数组

    * @param sortType排列种类

    * */

   public List<HashMap<String, Object>>sortByKey(List<HashMap<String, Object>> lists, SORTTYPE sortType){

      Collections.sort(lists, new SortComparator(sortType));

      Log.d(DEG_TAG,"list.sort:["+lists+"]");

      return lists;

   }

  

}

代码片段10.2.37 文件列表展示具体代码实现

       

        这里最主要的一个函数就是buildListForAdapter。我通过传入当前的文件   路径来列出当前的所有文件夹以及通过getDirectoryNums这个函数得到每个  子文件夹的具体文件数量。至于为什么只选择显示文件夹,列出的子项数量也为子   文件夹的数量。这是因为UC的功能就是这么实现的,不过UC在删除文件夹的时 候会显示出其他文件,这个不知道是不是UC的一个BUG。

       

        现在这样的文件显示效果是没有顺序可言的。我通过sortByKey的函数,将文 件列表以字母的数序来进行排列,为了以后的扩展性需要,我这里并没有将它写死,   而是传入了枚举变量,通过这个变量类分辨以何种顺序排列。

     

      文件的排列我是通过Collections.sort来实现的,不过这个函数的实现需  要构建一个自定义的Comparator比较器。

     

      具体的比较器实现方法如下:

     

package com.example.util;

 

import java.util.Comparator;

import java.util.HashMap;

 

import com.example.file.FileShowManager;

 

public class SortComparator implementsComparator<HashMap<String, Object>> {

  

   private FileShowManager.SORTTYPEsortType;

  

   public SortComparator(FileShowManager.SORTTYPE sortType){

      this.sortType = sortType;

   }

 

   @Override

   public int compare(HashMap<String, Object> lhs,HashMap<String, Object> rhs) {

      switch(sortType){

      case LETTER:

         //字母排序

         return String.valueOf(lhs.get("name")).compareTo(String.valueOf(rhs.get("name")));

      case DATE:

         //日期排序

         return String.valueOf(lhs.get("date")).compareTo(String.valueOf(rhs.get("date")));

      case CHILDNUMS:

         //含文件夹数排序

         return String.valueOf(lhs.get("childnums")).compareTo(String.valueOf(rhs.get("childnums")));

      }

      return 0;

   }

  

}

代码片段10.2.38 比较器代码实现

       

        我们根据传入的枚举值,来进行比较,如果为字母排序,则通过传入的单项为    HashMap的实现取得name值来比较,后面的日期与文件数排序也是相同的实现。至于   为什么日期也可以这样实现,那是因为日期的传入是一个字符串的形式。

       

        现在我们可以看下文件列表展示的效果:

       

图10.2.16   文件列表的展示

       

        如何实现这个界面呢?还是老样子,显示定义xml文件布局,再是根据布局编写相 应的Activity和其功能。

        现在放上代码:

       

<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:background="@android:color/white"

    >

   

    <FrameLayout

       android:id="@+id/fileManager_title"

       android:layout_width="fill_parent"

       android:layout_height="46dp"

       android:background="@android:color/holo_blue_light"

       >

        <TextView

           android:id="@+id/fileManager_title_text"

           android:layout_width="wrap_content"

           android:layout_height="wrap_content"

           android:text="@string/filemanagerTitle"

           android:textSize="18sp"

           android:textColor="@android:color/white"

           android:textStyle="bold"

           android:layout_gravity="center"

           />

        <Button

           android:id="@+id/fileManager_title_newDirectory"

           android:layout_width="wrap_content"

           android:layout_height="wrap_content"

           android:text="@string/filemanagerNewDirectory"

           android:layout_gravity="right|center_vertical"

            android:layout_marginRight="3dp"

           android:layout_marginTop="3dp"

           android:layout_marginBottom="3dp"

           />

    </FrameLayout>

  

    <ListView

       android:id="@+id/fileManager_list"

       android:layout_width="fill_parent"

       android:layout_height="fill_parent"

       android:layout_below="@id/fileManager_title"

       android:layout_above="@+id/fileManager_toolbar"

       >

       

    </ListView>

   

    <RelativeLayout

       android:id="@+id/fileManager_toolbar"

       android:layout_width="fill_parent"

       android:layout_height="35dp"

       android:layout_alignParentBottom="true"

       android:background="@drawable/tools_back"

       >

        <TextView

           android:id="@+id/fileManager_toolbar_sure"

           android:layout_width="wrap_content"

           android:layout_height="wrap_content"

           android:text="@string/sure"

           android:textSize="17sp"

           android:textColor="@android:color/black"

           android:layout_centerVertical="true"

           android:layout_alignParentLeft="true"

           android:layout_marginLeft="20dp"

           />

        <TextView

           android:id="@+id/fileManager_toolbar_cancel"

           android:layout_width="wrap_content"

           android:layout_height="wrap_content"

           android:text="@string/cancel"

           android:textSize="17sp"

           android:textColor="@android:color/black"

           android:layout_centerVertical="true"

           android:layout_alignParentRight="true"

           android:layout_marginRight="20dp"

           />

    </RelativeLayout>

   

</RelativeLayout>

代码片段10.2.39 文件列表展示xml布局页面

       

        我们可以来看看这个布局文件的预览效果:

       


图10.2.17   文件列表展示预览

       

        文件列表的点击功能可以这样分析,我们在每个列表中加入一个向上的项和返回 根目录的项。这个功能已经在上述的文件展示类中实现了的。在我们点击确定按钮后,   返回当前的url,按取消则是不做任何处理。

        因此,我们在activity中需要设置一个全局变量currentPath记录当前的相对路 径。

       

package com.example.androidstudy_web;

 

import java.io.File;

 

import android.app.Activity;

import android.app.AlertDialog;

import android.content.DialogInterface;

import android.content.Intent;

import android.os.Bundle;

import android.util.Log;

import android.view.LayoutInflater;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.AdapterView.OnItemLongClickListener;

import android.widget.Button;

import android.widget.EditText;

import android.widget.ListView;

import android.widget.TextView;

import android.widget.Toast;

 

import com.example.file.FileShowManager;

import com.example.other.ItemLongClickedPopWindow;

 

public class FileActivity extends Activity{

  

   private static final String DEG_TAG ="webbrowser_FileManager";

   public static final int RESULT_FILEMANAGER = 1;

  

   //文件列表

   private ListViewfileList;

  

   //确定取消按钮

   private TextViewsure;

   private TextViewcancel;

  

   //新建目录按钮

   private ButtoncreateNewFloder;

  

   //监听器

   private FileManagerOnItemListenerfileManagerOnItemListener;

   private FileManagerOnClickListenerfileManagerOnClickListener;

   private FileManagerOnItemLongListenerfileManagerOnItemLongListener;

   private FileListPopWindowMenufileListPopWindowMenu;

  

   //长按文件列表单项弹出菜单

   private ItemLongClickedPopWindowfileListItemLongClickedPopWindow;

  

   //文件管理线程类

   private FileShowManagerfileManager;

  

   //当前的路径

   private StringcurrentPath;

  

   /**

    * 文件管理Actvity

    * @param savedInstanceStateActivity信息

    * */

   @Override

   protected void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);

      setContentView(R.layout.activity_filemanager);

     

      //初始化控件

      this.fileList = (ListView)this.findViewById(R.id.fileManager_list);

     

      this.sure = (TextView)this.findViewById(R.id.fileManager_toolbar_sure);

      this.cancel = (TextView)this.findViewById(R.id.fileManager_toolbar_cancel);

     

      this.createNewFloder = (Button)this.findViewById(R.id.fileManager_title_newDirectory);

     

      this.fileManager =new FileShowManager(this,this.fileList);

      this.fileManagerOnItemListener =new FileManagerOnItemListener();

      this.fileManagerOnClickListener =new FileManagerOnClickListener();

      this.fileManagerOnItemLongListener =new FileManagerOnItemLongListener();

     

      //注册监听

      this.fileList.setOnItemClickListener(this.fileManagerOnItemListener);

     this.fileList.setOnItemLongClickListener(this.fileManagerOnItemLongListener);

     

      this.sure.setOnClickListener(this.fileManagerOnClickListener);

      this.cancel.setOnClickListener(this.fileManagerOnClickListener);

     

      this.createNewFloder.setOnClickListener(this.fileManagerOnClickListener);

     

      //启动文件查询线程

      currentPath = getIntent().getStringExtra("savePath");

      this.fileManager.execute(currentPath);

   }

  

   /**

    * OnItemClickListener自定义继承类

    * 覆盖如下方法:

    * 1. onItemClick

    * */

   private class FileManagerOnItemListener implements OnItemClickListener{

 

      @Override

      public void onItemClick(AdapterView<?> parent, View view, int position,

            long id) {

         TextView path = (TextView) view.findViewById(R.id.filemanager_item_filePath);

         currentPath = path.getText().toString();

         Log.d(DEG_TAG,"path:"+currentPath);

         fileManager = new FileShowManager(FileActivity.this,fileList);

         fileManager.execute(currentPath);

      }

     

   }

  

   /**

    * OnItemLongClickListener自定义继承类

    * 覆盖如下方法:

    * 1. onItemLongClick

    * */

   private class FileManagerOnItemLongListener implementsOnItemLongClickListener{

 

      @Override

      public boolean onItemLongClick(AdapterView<?> parent, View view,

            int position,long id) {

         TextView date = (TextView) view.findViewById(R.id.filemanager_item_info_numsAndDate_date);

         if(date.getText().toString().equals("")){

            return false;

         }

         fileListItemLongClickedPopWindow =new ItemLongClickedPopWindow(FileActivity.this,ItemLongClickedPopWindow.FILEMANAGER_ITEM_POPUPWINDOW, 200, 200);

         fileListItemLongClickedPopWindow.showAsDropDown(view, view.getWidth()/2,-view.getHeight()/2);

         TextView deleteFloder = (TextView) fileListItemLongClickedPopWindow.getView(R.id.item_longclicked_deleteFloder);

         TextViewnewNameForFloder = (TextView) fileListItemLongClickedPopWindow.getView(R.id.item_longclicked_newNameForFloder);

         fileListPopWindowMenu =new FileListPopWindowMenu(view);

         deleteFloder.setOnClickListener(fileListPopWindowMenu);

         newNameForFloder.setOnClickListener(fileListPopWindowMenu);

         return true;

      }

     

   }

  

   /**

    * OnClickListener自定义继承类

    * */

   private class FileListPopWindowMenu implements OnClickListener{

     

      private ViewbeLongClickedView;

     

      public FileListPopWindowMenu(View beLongClickedView){

         this.beLongClickedView = beLongClickedView;

      }

 

      @Override

      public void onClick(View v) {

         fileListItemLongClickedPopWindow.dismiss();

         TextView floderPath = (TextView) beLongClickedView.findViewById(R.id.filemanager_item_filePath);

         TextView oldFloderName = (TextView) beLongClickedView.findViewById(R.id.filemanager_item_info_name);

         final String floderPathStr = floderPath.getText().toString();

         if(v.getId()==R.id.item_longclicked_deleteFloder){

            //删除文件夹的实现

            new AlertDialog.Builder(FileActivity.this)

                .setTitle("删除目录")

                .setMessage("是否删除\""+floderPathStr+"\"目录")

                .setPositiveButton("删除",new DialogInterface.OnClickListener() {

                  

                   @Override

                   publicvoid onClick(DialogInterface dialog, int which) {

                      File deleteDirectory = newFile(floderPathStr);

                      if(deleteDirectory.exists()){

                         deleteDirectory.delete();

                         fileManager =new FileShowManager(FileActivity.this,fileList);

                         fileManager.execute(currentPath);

                      }

                   }

                })

                .setNegativeButton("取消",null)

                .create()

                .show();

         }else if(v.getId()==R.id.item_longclicked_newNameForFloder){

            //重命名文件夹的实现

            View newNameForFloderView = LayoutInflater.from(FileActivity.this).inflate(R.layout.dialog_newnameforfloder,null);

            final TextView floderName = (TextView)  newNameForFloderView.findViewById(R.id.dialog_newNameForFloder

_floderName);

            floderName.setText(oldFloderName.getText().toString());

            new AlertDialog.Builder(FileActivity.this)

            .setTitle("重命名")

            .setView(newNameForFloderView)

            .setPositiveButton("确定",new DialogInterface.OnClickListener() {

               

                @Override

                publicvoid onClick(DialogInterface dialog, int which) {

                   String newFloderName =floderName.getText().toString();

                   File newNameFloder = new File(floderPathStr);

                   newNameFloder.renameTo(new File(currentPath +"/" + newFloderName));

                   fileManager =new FileShowManager(FileActivity.this,fileList);

                   fileManager.execute(currentPath);

                }

            })

            .setNegativeButton("取消",null)

            .create()

            .show();

         }

      }

     

   }

  

   /**

    * OnClickListener自定义继承类

    * 覆盖如下方法

    * 1. onClick

    * */

   private class FileManagerOnClickListener implements OnClickListener{

 

      @Override

      public void onClick(View v) {

         if(v.getId()==R.id.fileManager_toolbar_sure){

            //确定操作,返回确定的url

            Intent intentExtraUrl = new Intent();

            intentExtraUrl.putExtra("savePath",currentPath);

            setResult(RESULT_FILEMANAGER, intentExtraUrl);

            finish();

         }else if(v.getId()==R.id.fileManager_toolbar_cancel){

            //取消操作,不更改url

            setResult(MainActivity.REQUEST_DEFAULT);

            finish();

         }else if(v.getId()==R.id.fileManager_title_newDirectory){

            //新建目录操作

            View createNewFolderView = LayoutInflater.from(FileActivity.this).inflate(R.layout.dialog_createnewfloder,null);

            final EditText newFloderName = (EditText)createNewFolderView.findViewById(R.id.dialog_createNewFloder_floderName);

            new AlertDialog.Builder(FileActivity.this)

                .setTitle("创建新目录")

                .setView(createNewFolderView)

                .setPositiveButton("确定",new DialogInterface.OnClickListener() {

                  

                   @Override

                   publicvoid onClick(DialogInterface dialog, int which) {

                      StringcreateNewpath = currentPath + "/" + newFloderName.getText().toString();

                      Log.d(DEG_TAG,"createNewpath:"+createNewpath);

                      File file = new File(createNewpath);

                      if(!file.exists()){

                         file.mkdir();

                         fileManager =new FileShowManager(FileActivity.this,fileList);

                         fileManager.execute(currentPath);

                      }else{

                         //目录已存在,提示无法创建

                         Toast.makeText(FileActivity.this,"目录已存在", Toast.LENGTH_SHORT).show();

                      }

                   }

                })

                .setNegativeButton("取消",null)

                .create()

                .show();

         }

      }

     

   }

 

   @Override

   public void onBackPressed() {

      setResult(MainActivity.REQUEST_DEFAULT);

      super.onBackPressed();

   }

  

  

}

代码片段10.2.40  文件展示列表的具体实现

       

        注意:这里在默认打开界面的时候就需要加载文件列表,而默认的位置就是保存图  片对话框所显示出来的保存路径。我们每次进行加载的时候都需要重新实例化一个文 件列表展示类,因为继承自AsynTask,只能执行一次execute方法。

       

        因为我们要实现列表单项长按弹出菜单的实现,所以这就需要监听长按的事件。而    对于弹出菜单实现单击事件。上述代码中都有所提及。

       

        至于在弹出保存对话框中的具体代码实现如下:

       

else if(v.getId()==R.id.item_longclicked_saveImage){

            //图片菜单-保存图片

            View dialogSaveImg = LayoutInflater.from(MainActivity.this).inflate(R.layout.dialog_saveimg,null);

            choosePath = (TextView) dialogSaveImg.findViewById(R.id.dialog_savePath_enter);

            imgSaveName = (TextView) dialogSaveImg.findViewById(R.id.dialog_fileName_input);

            final String imgName =value.substring(value.lastIndexOf("/") + 1);

            imgSaveName.setText(imgName);

            choosePath.setOnClickListener(buttonClickedListener);

            saveImageToChoosePath =new AlertDialog.Builder(MainActivity.this)

                .setTitle("选择保存路径")

                .setView(dialogSaveImg) 

                .setPositiveButton("确定",new

DialogInterface.OnClickListener(){

                  

                   @Override

                   publicvoid onClick(DialogInterface dialog, int which) {

                      Log.d(DEG_TAG,"fileName:"+imgName+",filePath:"+choosePath.getText().toString());

                      new ImageDownloadManager(MainActivity.this).execute(imgName,value, choosePath.getText().toString());

                   }

                })

                .setNegativeButton("取消",null)

                .create();

            saveImageToChoosePath.show();

         }

代码片段10.2.41 弹出保存对话框的具体实现

       

        这里的ImageDownloadManager就是管理下载图片的类,因为耗时的缘故,我们这里仍旧使用AsynTask类。

     

package com.example.file;

 

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.net.HttpURLConnection;

import java.net.URL;

 

import android.annotation.SuppressLint;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.os.AsyncTask;

import android.os.Environment;

import android.util.Log;

import android.widget.Toast;

 

public class ImageDownloadManager extends AsyncTask<String, String,String>{

  

   private static final String DEG_TAG ="webbrowser_FileDownloadManager";

  

   private Filefile;

  

   private Contextcontext;

  

   public ImageDownloadManager(Context context){

      this.context = context;

   }

 

   @SuppressLint("SdCardPath")

   @Override

   protected String doInBackground(String... params) {

      Log.d(DEG_TAG,"fileName:"+params[0]+",filePath:"+params[2]);

      if(params[2].startsWith("/sdcard/")){

         //如果是以/sdcard/为开头的,则应保存为sdcard

         params[2] = Environment.getExternalStorageDirectory()+params[2].substring(8);

         Log.d(DEG_TAG,"saveImagePath:"+params[2]);

      }

      try{

         URL  url = new URL(params[1]);

           HttpURLConnectionconn  =(HttpURLConnection)url.openConnection();

           conn.setDoInput(true);

           conn.connect();

           InputStreaminputStream=conn.getInputStream();

           Bitmap imgSave =BitmapFactory.decodeStream(inputStream);

           this.writeFile(params[0],params[2], imgSave);

           inputStream.close();

      }catch(IOException e){

         e.printStackTrace();

      }

      return null;

   }

 

   @Override

   protected void onPostExecute(String result) {

      Toast.makeText(context,"成功下载", Toast.LENGTH_SHORT).show();

      super.onPostExecute(result);

   }

  

   /**

    * 将图片写入

    * @param fileName图片名

    * @param dirPath    图片路径

    * @param Bitmap  图片内容

    * */

   public void writeFile(String fileName, String dirPath, BitmapimgSave){

      try{

         File directory = new File(dirPath);

         if((directory.exists())&&(directory.isFile())){

            directory.delete();

         }else{

            directory.mkdirs();

         }

         this.file =new File(dirPath, fileName);

         if(this.file.exists()){

            this.file.delete();

         }

         this.file.createNewFile();

         FileOutputStream fo = new FileOutputStream(this.file);

         imgSave.compress(Bitmap.CompressFormat.PNG, 100, fo);

         fo.flush();

         fo.close();

      }catch(FileNotFoundException e1){

         Log.d(DEG_TAG,"文件未找到:"+e1.getMessage());

      }catch(IOException e2){

         Log.d(DEG_TAG,"文件创建错误:"+e2.getMessage());

         e2.printStackTrace();

      }

   }

}

代码片段10.2.41  下载文件管理类

     

      至此我们的保存图片功能已经完成。

     

      案例:

      AndroidStudy_web_v3.1_by 本人dddd牛仔

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值