最近几天开学,所以没有更新博客。今天开始更新。最近我打算每天抽出一些事件看点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 savedInstanceState父Activity信息

* */

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

Android网络:开发浏览器(五)——功能完善之保存图片实现的更多相关文章

  1. 《精通android网络开发》--HTTP数据通信

    No1: 例如:http://www.*****.com/china/index.htm 1)http:// 代表超文本传送协议,通知*****.com服务器显示web页,通常不用输入 2)www 代 ...

  2. android网络开发之测试机连接到服务器上面

    1:本人使用Tomcat作为服务器软件,首先打开Tomcat.(可以在浏览器中输入http://www.127.0.0.1:8080/查看) 2:服务器后台使用Servelt开发,这里不再讲解. 3: ...

  3. Android网络开发实例(基于抓包实现的网络模拟登录,登出和强制登出)

    学习Android有几个月了,最近喜欢上了网络编程,于是想通过Android写一些一个小程序用于连接外网.在这里非常感谢雪夜圣诞的支持,非常感谢,给我打开新的一扇门. 1.声明,本程序只能用于西南大学 ...

  4. Android网络开发

    1. WebView用法 ①布局文件新建一个WebView,特别注意线性布局和控件的宽高都要匹配父控件 <LinearLayout xmlns:android="http://sche ...

  5. Android网络开发之蓝牙

    蓝牙采用分散式网络结构以及快调频和短包技术,支持点对点及点对多点通信,工作在全球通用的2.4GHz ISM(I-工业.S-科学.M-医学)频段,其数据速率为1Mbps,采用时分双工传输方案.   蓝牙 ...

  6. Android网络开发之基本介绍

    Android平台浏览器采用WebKit引擎,名为ChormeLite,拥有强大扩展特性,每个开发者都可以编写自己的插件. 目前,Android平台有3种网络接口可以使用,分别是:java.net, ...

  7. Android网络开发之实时获取最新数据

    在实际开发中更多的是需要我们实时获取最新数据,比如道路流量.实时天气信息等,这时就需要通过一个线程来控制视图的更新. 示例:我们首先创建一个网页来显示系统当前的时间,然后在Android程序中每隔5秒 ...

  8. Android NDK开发(五)--C代码回调Java代码【转】

    转载请注明出处:http://blog.csdn.net/allen315410/article/details/41862479 在上篇博客里了解了Java层是怎样传递数据到C层代码,并且熟悉了大部 ...

  9. Android NDK开发篇(五):Java与原生代码通信(数据操作)

    尽管说使用NDK能够提高Android程序的运行效率,可是调用起来还是略微有点麻烦.NDK能够直接使用Java的原生数据类型,而引用类型,由于Java的引用类型的实如今NDK被屏蔽了,所以在NDK使用 ...

随机推荐

  1. Ural 1450 求最长路 SPFA

    题意就是求S点到T点的有向无环图中的最长路. 用SPFA可以解决. 一开始一直RE的原因 QAQ 竟然是在开Edge 邻接表的时候开小了 改了一下4Y #include <stdio.h> ...

  2. AsyncTask究竟需要多少个线程

    最起码两个:主线程和工作线程; 可以参考:http://zhidao.baidu.com/link?url=ho4UEcEbaogRZUFHwig1neSKR25b2zT9iXyM36hEgWTmvJ ...

  3. Java进阶04 RTTI

    链接地址:http://www.cnblogs.com/vamei/archive/2013/04/14/3013985.html 作者:Vamei 出处:http://www.cnblogs.com ...

  4. PL/SQL连64位Oracle11g R2 win7 64旗舰环境

    说明:使用的软件版本是PL/SQL Developer 7.0.1,Oracle服务器端安装在Windows7旗舰版上. 以下是我的步骤 1,先到Oracle网站下载客户端:http://www.or ...

  5. Xcode4 布置Git环境Your working copy is out of date. Try pulling from the remote to get the latest change

    今天布置环境的时候发现一个问题:Your working copy is out of date. Try pulling from the remote to get the latest chan ...

  6. three.js 源代码凝视(十)Math/Line3.js

    商域无疆 (http://blog.csdn.net/omni360/) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:商域无疆 -  本博客专注于 敏捷开发 ...

  7. Apache Flink

    Flink 剖析 1.概述 在如今数据爆炸的时代,企业的数据量与日俱增,大数据产品层出不穷.今天给大家分享一款产品—— Apache Flink,目前,已是 Apache 顶级项目之一.那么,接下来, ...

  8. 关于PEER - PEER毅恒挚友 - Powered by Discuz!

    关于PEER - PEER毅恒挚友 - Powered by Discuz! PEER Experience Exchange Rostrum(PEER)由海外中国留学生和中国知名高校学生组成,服务中 ...

  9. eclipse不能自己主动弹出提示的解决的方法

    曾经碰到过好几次eclipse不能自己主动弹出提示的情况,每次总是弄好之后就不再管它,结果下次遇到同样的问题,又到网上去搜索一大堆答案非常多都不能解决实际问题,费了时间还没有效果,如今这里记录下来下面 ...

  10. hdu1391(Number Steps )

    Problem Description Starting from point (0,0) on a plane, we have written all non-negative integers ...