这次来个稍微复杂点的。

package cn.com.sxp;

import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.StatFs;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

public class AccessSDActivity extends Activity {
private final static String TAG = AccessSDActivity.class.getSimpleName();
private TextView tv = null;
private ImageView iv = null;
private Button btn = null;
private ProgressDialog pd = null;

private Bitmap bitmap = null;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

if (!Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
//
Log.d("sxp", "挖槽~~~屁的sd卡啊");
AccessSDActivity.this.finish();
}


// 下面开始将从网络上下载下来的图片放在sdcard上
iv = (ImageView)this.findViewById(R.id.iv);
btn = (Button)this.findViewById(R.id.btn);

String filePath = "http://localhost:8080/test.jpg";
String fileName = "handsome.jpg";



try {
// 以字节数组的形式存着图片
byte[] data = getPictureByBytes(filePath);
if(data!=null){
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
iv.setImageBitmap(bitmap);
}else{
Toast.makeText(this,"下载失败啦妈的!", 1).show();
}

// 这事以一段流的形式存储图片
bitmap = BitmapFactory.decodeStream(getPictureByStream(filePath));
if (bitmap != null) {
iv.setImageBitmap(bitmap);
}
} catch (Exception e) {
Toast.makeText(AccessSDActivity.this,"出什么问题了!", 1).show();
e.printStackTrace();
}

// 下载图片
btn.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
pd = ProgressDialog.show(AccessSDActivity.this, "保存着呢", "没看到正在保存吗", true);
new Thread(pictureSave).start();
}
});
}

public byte[] getPictureByBytes(String path) throws Exception{
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5 * 1000);
conn.setRequestMethod("GET");
InputStream inStream = conn.getInputStream();
if(conn.getResponseCode() == HttpURLConnection.HTTP_OK){
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while( (len=inStream.read(buffer)) != -1){
outStream.write(buffer, 0, len);
}
outStream.close();
inStream.close();
return outStream.toByteArray();
}
return null;
}

public InputStream getPictureByStream(String path) throws Exception{
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5 * 1000);
conn.setRequestMethod("GET");
if(conn.getResponseCode() == HttpURLConnection.HTTP_OK){
return conn.getInputStream();
}
return null;
}

private Runnable pictureSave = new Runnable(){
@Override
public void run() {
try {
File dir = new File("/mnt/sdcard/sxp/android/test");
if(!dir.exists()){
dir.mkdir();
}
File me = new File("/mnt/sdcard/sxp/android/test/test.jpg");
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(me));
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
bos.flush();
bos.close();
String message = "图片保存成功!";
} catch (IOException e) {
String message = "图片保存失败!";
e.printStackTrace();
}
messageHandler.sendMessage(messageHandler.obtainMessage());
}
};

private Handler messageHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
pd.dismiss();
Toast.makeText(AccessSDActivity.this, "主线程收到", Toast.LENGTH_SHORT).show();
}
};
}

意思很简单,就是从本机tomcat服务器上下载一个图片,然后显示。测试后发现,手机模拟器似乎无法访问本地的tomcat服务器,他妈的。不过也有招数,将代码的localhost改为10.0.2.2就可以了。这个地址是android特设的。

不过这段代码还是有很多地方需要学习的,还算是比较经典的。

1. 用字节数组储存一个图片。图片多大,数组分配的字节数就有多大,不能比图片的字节数小;

2. 如何将一堆字节转化为图片呢?好问题,BitmapFactory.decodeByteArray方法就可以做到,牛逼;

3. 也可以不要字节储存图片,直接通过流来储存图片,再解流。BitmapFactory.decodeStream方法即可。不过两者哪个好,不能判断,得看商用时看重什么性能。这两个方法还是要研究下。

4. 线程的使用。改代码中使用了线程,按下一个按钮后,响应事件是给一个线程去处理,同时线程完成任务后,使用消息处理句柄给主线程发送消息,这事很需要值得学习的一个技术,我得深入学习。不过,消除对话框为何在主线程中进行,我觉得奇怪。对话框是在子线程中分配的,不应该由子线程消掉吗?得测试下。

5. 另一个值得研究的是一票NET类的使用,包括url表示类,连接类,在连接上的流类,值得研究。

android_sdcard读写(三)的更多相关文章

  1. zedboard如何从PL端控制DDR读写(三)——AXI-FULL总线调试

    之前的项目和培训中,都只用到了AXI-Lite或者AXI-Stream,对于AXI-FULL知之甚少,主要是每次一看到那么多接口信号就望而却步了. 现在为了调试DDR,痛下决心要把AXI-FULL弄懂 ...

  2. Qt读写三种文件,QSettings读ini配置文件,QJsonDocument读JSON文件,QDomDocument读xml文件

    第一种INI配置文件 .ini 文件是Initialization File的缩写,即初始化文件. 除了windows现在很多其他操作系统下面的应用软件也有.ini文件,用来配置应用软件以实现不同用户 ...

  3. golang文件读写三种方式——bufio,ioutil和os.create

    package main import ( "bufio" "fmt" "io/ioutil" "os" ) func ...

  4. android_sdcard读写(二)

    接着上篇,继续研究sdcard的神秘之处.上篇代码不变,本篇新增代码都在下面~~~ 继续上代码~~ // 写文件 File path = new File("/mnt/sdcard/sxp/ ...

  5. android_sdcard读写(一)

    现在的android手机其实就是一个小小的掌上电脑,平时电脑有的硬件它估计也有了.这次本人研究下了其中充当手机硬盘的角色,就是sdcard.这是一个保存应用程序的好地方. 老规矩,上代码,学习代码才是 ...

  6. Delphi COM编程技术三类型库(库文件中的工具栏,很全)

    在COM组件的使用和开发过程中经常需要获取有关组件的信息.而COM组件以二进制代码的形式发布,如果不借助特定的工具这些相关信息将难以被获取.通过访问类型库就可以查看COM组件的信息. 一.类型库的基础 ...

  7. RT-Thread下的串口驱动程序分析【转载】

    编写本文稿的目的,在于通过分析stm32平台上的串口中断源码,学习 RTT中如何编写中断处理程序 如何编写RTT设备驱动接口代码 了解串行设备的常见处理机制 先以RTT官方源码中的STM32 BSP包 ...

  8. 降低磁盘IO使Oracle性能优化(转)

    文章转自:http://blog.chinaunix.net/uid-26813519-id-3207996.html 硬件方面虽然只占Oracle性能优化的一个方面(另一方面是软件),但是仍不可忽视 ...

  9. [Delphi]Delphi开发的一些技巧

    一.提高查询效率先进行准备查询操作: CustomerQuery.Close; if not (CustomerQuery.Prepared) then -->查询是否已准备好 Customer ...

随机推荐

  1. 反射:获取枚举类型的Name,Value,Description

    [Obsolete("请使用新的方法XXX")] //使用Obsolete特性来告诉使用者这是一个过期的方法 private static void Test() { Type t ...

  2. Win32 Application基本框架

    //程序入口 intAPIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdSh ...

  3. CKEditor 4.5 beta 发布,可视化 HTML 编辑器

    分享 <关于我> 分享  [中文纪录片]互联网时代                 http://pan.baidu.com/s/1qWkJfcS 分享 <HTML开发MacOSAp ...

  4. JavaScript MVC框架PK:Angular、Backbone、CanJS与Ember(转载)

    原文地址:http://sporto.github.io/.../comparison-angular-backbone-can-ember/ 原文作者:Sebastian Porto @Twitte ...

  5. Spring Cloud Ribbon配置详解

    概述 有时候需要自定义Ribbon的配置和客户端超时配置. 自动化配置 /* 使用属性自定义功能区客户端 从版本1.2.0开始,Spring Cloud Netflix现在支持使用属性与Ribbon文 ...

  6. 网站压力测试工具 Webbench简单介绍

    Webbech能测试处在相同硬件上,不同服务的性能以及不同硬件上同一个服务的运行状况.Webbench的标准测试可以向我们展示服务器的两项内容:每秒钟相应请求数和每秒钟传输数据量.Webbench不但 ...

  7. Zookeeper详解-基础(二)

    在深入了解ZooKeeper的运作之前,让我们来看看ZooKeeper的基本概念.我们将在本章中讨论以下主题: Architecture(架构) Hierarchical namespace(层次命名 ...

  8. iOS开发(4):录音AVAudioRecorder

    录音,声音的采集,一般有两种实现办法,一是使用AVAudioRecorder,一是使用AudioUnit.如果只是简单的录音,使用AVAudioRecorder就可以了,如果想更灵活地处理刚录到的声音 ...

  9. 前端Vue基础学习

    Vue基础 对与vue的简洁明了的干货分享,适合小白学习观看,如果有笔误或者想了解更多的,请给笔者留言,后续会继续分享,从零开始的vue相关经验 1.创建vue实例 <div id=" ...

  10. Kafka 学习之路(四)—— Kafka消费者详解

    一.消费者和消费者群组 在Kafka中,消费者通常是消费者群组的一部分,多个消费者群组共同读取同一个主题时,彼此之间互不影响.Kafka之所以要引入消费者群组这个概念是因为Kafka消费者经常会做一些 ...