• 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牛仔

  • 相关阅读:
    Code Review
    关于calendar修改前的代码和修改后的代码
    程序员必备的代码审查(Code Review)清单
    一个数组中最大子数组的和并且加上测试用例
    阅读build to win的个人感想
    结对编码(柳祎、张许君)
    Review(patener)
    Review [myself]
    Impressions
    Array
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3303912.html
Copyright © 2020-2023  润新知