android_sdcard读写(三)

这次来个稍微复杂点的。

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表示类,连接类,在连接上的流类,值得研究。

原文地址:https://www.cnblogs.com/itblog/p/7236633.html