源码下载:
https://github.com/kkman2008/androidbrowseuploadfile
项目演示及讲解
优酷 http://v.youku.com/v_show/id_XODk5NjkwOTg4.html
爱奇艺 http://www.iqiyi.com/w_19rs1v2m15.html#vfrm=8-7-0-1
土豆 http://www.tudou.com/programs/view/fv0H93IHfhM
大家在调试的同时一定要注意
1、网络下载、上传这些操作,就是耗时的操作,要另外开线程操作,不能放到主线程里面。
2、网络下载、上传里面不能有ui操作,不能在里面显示ui。就是不能在子线程里面操作UI。如果操作完毕ui提示用户等操作,可以使用利用handler结合Thread更新UI,或者AsyncTask异步更新UI。
3、上传到本地Tomcat服务器,要关闭防火墙
接下来将给出两个项目部分代码,当然两个项目都有一个工具类HttpPost
public class HttpPost {
/**
* 通过拼接的方式构造请求内容,实现参数传输以及文件传输
*
* @param acti
* .nUrl
* @param params
* @param files
* @return
* @throws IOException
*/
public static String post(String actionUrl, Map
String BOUNDARY = java.util.UUID.randomUUID().toString();
String PREFIX = "--", LINEND = "\r\n";
String MULTIPART_FROM_DATA = "multipart/form-data";
String CHARSET = "UTF-8";
URL uri = new URL(actionUrl);
HttpURLConnection conn = (HttpURLConnection) uri.openConnection();
conn.setReadTimeout(5 * 1000); // 缓存的最长时间
conn.setDoInput(true);// 允许输入
conn.setDoOutput(true);// 允许输出
conn.setUseCaches(false); // 不允许使用缓存
conn.setRequestMethod("POST");
conn.setRequestProperty("connection", "keep-alive");
conn.setRequestProperty("Charsert", "UTF-8");
conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA + ";boundary=" + BOUNDARY);
// 首先组拼文本类型的参数
StringBuilder sb = new StringBuilder();
for (Map.Entry
sb.append(PREFIX);
sb.append(BOUNDARY);
sb.append(LINEND);
sb.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + LINEND);
sb.append("Content-Type: text/plain; charset=" + CHARSET + LINEND);
sb.append("Content-Transfer-Encoding: 8bit" + LINEND);
sb.append(LINEND);
sb.append(entry.getValue());
sb.append(LINEND);
}
DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
outStream.write(sb.toString().getBytes());
// 发送文件数据
if (files != null)
for (Map.Entry
StringBuilder sb1 = new StringBuilder();
sb1.append(PREFIX);
sb1.append(BOUNDARY);
sb1.append(LINEND);
sb1.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getKey() + "\"" + LINEND);
sb1.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINEND);
sb1.append(LINEND);
outStream.write(sb1.toString().getBytes());
InputStream is = new FileInputStream(file.getValue());
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
is.close();
outStream.write(LINEND.getBytes());
}
// 请求结束标志
byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
outStream.write(end_data);
outStream.flush();
// 得到响应码
int res = conn.getResponseCode();
InputStream in = conn.getInputStream();
if (res == 200) {
int ch;
StringBuilder sb2 = new StringBuilder();
while ((ch = in.read()) != -1) {
sb2.append((char) ch);
}
}
outStream.close();
conn.disconnect();
return in.toString();
}
}
这个工具类两个项目所共有
接下来是拍照上传至服务器的主要代码(界面代码不再给出)
public class MainActivity extends Activity {
private static final int PHOTO_CAPTURE = 0x11;
private static String photoPath = "/sdcard/AnBo/";
private static String photoName = photoPath + "laolisb.jpg";
Uri imageUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "image.jpg"));//第二个参数是临时文件,在后面将会被修改
private Button photo, sc_photo;//拍照与下载
private ImageView img_photo;//显示图片
//private String newName = "laoli.jpg";
/*
* 这里的代码应该有问题
*/
private String uploadFile = "/sdcard/AnBo/laolisb.jpg";
private String actionUrl = "http://192.168.0.104:8080/UploadPhoto1/UploadServlet";
// private String actionUrl = "http://192.168.0.104:8080/File/UploadAction";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
photo = (Button) findViewById(R.id.photo);
sc_photo = (Button) findViewById(R.id.sc_photo);
img_photo = (ImageView) findViewById(R.id.imt_photo);
/*
* android.os.NetworkOnMainThreadException
* 耗时操作,加如下代码,可在主线程中进行,但不推荐
*/
// StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());
// StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().penaltyLog().penaltyDeath().build());
sc_photo.setOnClickListener(new Sc_photo());
photo.setOnClickListener(new Photo());
}
class Sc_photo implements View.OnClickListener {
@Override
public void onClick(View arg0) {
dialog();
}
}
class Photo implements View.OnClickListener {
@Override
public void onClick(View v) {
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
//"/sdcard/AnBo/";
File file = new File(photoPath);
if (!file.exists()) { // 检查图片存放的文件夹是否存在
file.mkdir(); // 不存在的话 创建文件夹
}
//photoPath + "laolisb.jpg"
File photo = new File(photoName);
imageUri = Uri.fromFile(photo);
// 这样就将文件的存储方式和uri指定到了Camera应用中
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, PHOTO_CAPTURE);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
String sdStatus = Environment.getExternalStorageState();
switch (requestCode) {
case PHOTO_CAPTURE:
if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) {
Log.i("内存卡错误", "请检查您的内存卡");
} else {
BitmapFactory.Options op = new BitmapFactory.Options();
// 设置图片的大小
Bitmap bitMap = BitmapFactory.decodeFile(photoName);
int width = bitMap.getWidth();
int height = bitMap.getHeight();
// 设置想要的大小
int newWidth = 480;
int newHeight = 640;
// 计算缩放比例
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// 取得想要缩放的matrix参数
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
// 得到新的图片
bitMap = Bitmap.createBitmap(bitMap, 0, 0, width, height, matrix, true);
// canvas.drawBitmap(bitMap, 0, 0, paint)
// 防止内存溢出
op.inSampleSize = 4; // 这个数字越大,图片大小越小.
Bitmap pic = null;
pic = BitmapFactory.decodeFile(photoName, op);
img_photo.setImageBitmap(pic); // 这个ImageView是拍照完成后显示图片
FileOutputStream b = null;
;
try {
b = new FileOutputStream(photoName);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (pic != null) {
pic.compress(Bitmap.CompressFormat.JPEG, 50, b);
}
}
break;
default:
return;
}
}
protected void dialog() {
AlertDialog.Builder builder = new Builder(MainActivity.this);
builder.setMessage("确认上传图片吗?");
builder.setTitle("提示");
builder.setPositiveButton("确认", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
new Thread(new Runnable() {
@Override
public void run() {
uploadPhoto();
//uploadFile();
}
}).start();
}
});
builder.setNegativeButton("取消", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create().show();
}
//第二种上传方式
public void uploadPhoto() {
Map
params.put("strParamName", "strParamValue");
Map
files.put(System.currentTimeMillis()+".jpg", new File(uploadFile));//uploadFile = "/sdcard/AnBo/laolisb.jpg";
try {
String str = HttpPost.post(actionUrl, params, files);
System.out.println("str--->>>" + str);
} catch (Exception e) {
}
}
/* 显示Dialog的method */
private void showDialog(String mess) {
new AlertDialog.Builder(MainActivity.this).setTitle("提示").setMessage(mess).setNegativeButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
}).show();
}
}
以上就是拍照上传至服务器的主要代码,接下来是选择文件上传至服务器主要代码
界面布局
三个xml代码给出
activity_file_upload.xml
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_gravity="center"
android:background="#ededed"
android:gravity="center_vertical"
android:paddingLeft="10dip"
android:paddingRight="10dip" >
android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/selector_message_button"
android:gravity="center"
android:padding="5dip"
android:text="@string/cancel_back"
android:textColor="@color/tab_indicator" />
android:id="@+id/title"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight="10"
android:gravity="center"
android:text="@string/upload_title"
android:textColor="@color/blank" />
android:id="@+id/upload"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/selector_message_button"
android:gravity="center"
android:padding="5dip"
android:text="@string/upload_begin"
android:textColor="@color/tab_indicator" />
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff" >
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:orientation="vertical" >
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:gravity="center"
android:orientation="horizontal" >
android:layout_width="wrap_content"
android:layout_height="40dp"
android:gravity="right|center_vertical"
android:text="@string/file_upload" />
android:id="@+id/file_path"
android:layout_width="match_parent"
android:layout_height="40dp"
android:focusable="false"
android:focusableInTouchMode="false"
android:singleLine="true"
android:gravity="center_vertical"
android:inputType="text" />
android:id="@+id/buttonLoadPicture"
android:layout_width="100dip"
android:layout_height="30dip"
android:layout_gravity="center"
android:layout_marginBottom="10dip"
android:layout_marginTop="30dip"
android:background="@drawable/selector_message_button"
android:text="@string/look_pictrue" >
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00000000" >
android:id="@+id/show"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#30000000"
android:gravity="center"
android:visibility="gone" >
android:id="@+id/show_pb"
android:layout_width="30dip"
android:layout_height="30dip"
android:indeterminateDrawable="@drawable/progressbar" />
activity_fileupload.xml
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
android:id="@+id/currPath"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/currPath" >
item_fileuplaod.xml
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center_vertical">
android:id="@+id/adapter_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp" />
android:id="@+id/adapter_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
/>
FileSelectActivity.class
public class FileSelectActivity extends ListActivity {
private static final String root = new String(Environment
.getExternalStorageDirectory().getPath() + File.separator);
private TextView tv;// 显示文件的目录
private File[] files;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fileupload);
tv = (TextView) findViewById(R.id.currPath);
getFiles(root);
}
public void getFiles(String path) {
tv.setText(path);
File f = new File(path);
// 得到所有子文件和文件夹
File[] tem = f.listFiles();
// 如果当前的目录不是在顶层目录,就把父目录要到files数组中的第一个
if (!path.equals(root)) {
files = new File[tem.length + 1];
System.arraycopy(tem, 0, files, 1, tem.length);
files[0] = f.getParentFile();
} else {
files = tem;
}
sortFilesByDirectory(files);
// 为ListActivity设置Adapter
setListAdapter(new Adapter(this, files, files.length == tem.length));
}
// 对文件进行排序
private void sortFilesByDirectory(File[] files) {
Arrays.sort(files, new Comparator
public int compare(File f1, File f2) {
return Long.valueOf(f1.length()).compareTo(f2.length());
}
});
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
File f = files[position];
if (!f.canRead()) {
Toast.makeText(this, "文件不可读", Toast.LENGTH_SHORT).show();
return;
}
if (f.isFile()) {// 为文件
String path = f.getAbsolutePath();
Intent intent = new Intent();
intent.putExtra("path", path);
setResult(FileUploadActivity.RESULT_LOAD_FILE, intent);
finish();
} else {
getFiles(f.getAbsolutePath());
}
}
class Adapter extends BaseAdapter {
private File[] files;
private boolean istop;
private Context context;
public Adapter(Context context, File[] files, boolean istop) {
this.context = context;
this.files = files;
this.istop = istop;
}
@Override
public int getCount() {
return files.length;
}
@Override
public Object getItem(int position) {
return files[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder = null;
if (convertView == null) {
holder = new Holder();
convertView = View.inflate(context, R.layout.item_fileupload,
null);
holder.iv = (ImageView) convertView
.findViewById(R.id.adapter_icon);
holder.tv = (TextView) convertView
.findViewById(R.id.adapter_txt);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
// 设置convertView中控件的值
setconvertViewRow(position, holder);
return convertView;
}
private void setconvertViewRow(int position, Holder holder) {
File f = files[position];
holder.tv.setText(f.getName());
if (!istop && position == 0) {// 不是在顶层目录
// 加载后退图标
holder.iv.setImageResource(R.drawable.back_up);
} else if (f.isFile()) {// 是文件
// 加载文件图标
holder.iv.setImageResource(R.drawable.file);
} else {// 文件夹
// 加载文件夹图标
holder.iv.setImageResource(R.drawable.dir);
}
}
class Holder {
private ImageView iv;
private TextView tv;
}
}
}
FileUploadActivity.class
public class FileUploadActivity extends Activity implements OnClickListener {
protected static final int SUCCESS = 2;
protected static final int FAILD = 3;
protected static int RESULT_LOAD_FILE = 1;
private TextView cancel;
private TextView upload;
private EditText pathView;
private Button buttonLoadImage;
private String picturePath;
private View show;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_upload);
initView();
initData();
}
private Handler mHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case SUCCESS:
show.setVisibility(View.INVISIBLE);
picturePath = "";
pathView.setText(picturePath);
Toast.makeText(getApplicationContext(), "上传成功!", Toast.LENGTH_LONG).show();
break;
case FAILD:
show.setVisibility(View.INVISIBLE);
Toast.makeText(getApplicationContext(), "上传失败!", Toast.LENGTH_LONG).show();
break;
default:
break;
}
return false;
}
});
private void initView() {
cancel = (TextView) findViewById(R.id.cancel);
upload = (TextView) findViewById(R.id.upload);
buttonLoadImage = (Button) findViewById(R.id.buttonLoadPicture);
cancel.setOnClickListener(this);
upload.setOnClickListener(this);
buttonLoadImage.setOnClickListener(this);
show = findViewById(R.id.show);
pathView = (EditText) findViewById(R.id.file_path);
pathView.setKeyListener(null);
}
private void initData() {
picturePath = "";
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.cancel:
finish();
break;
case R.id.buttonLoadPicture:
Intent intent = new Intent(getApplicationContext(), FileSelectActivity.class);
startActivityForResult(intent, RESULT_LOAD_FILE);
break;
case R.id.upload:
uploadFile();
break;
default:
break;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_FILE && resultCode == RESULT_LOAD_FILE && data != null) {
picturePath = data.getStringExtra("path");
pathView.setText(picturePath);
}
}
/******************************************************/
private String fun(String msg){
int i = msg.length();
int j = msg.lastIndexOf("/") + 1;
String a = msg.substring(j, i) ;
System.out.println(a);
return a;
}
/******************************************************/
private void uploadFile() {
show.setVisibility(View.VISIBLE);
new Thread() {
@Override
public void run() {
Message msg = Message.obtain();
// 服务器的访问路径
String uploadUrl = "http://192.168.0.104:8080/UploadPhoto1/UploadServlet";
Map
String name = fun(picturePath);
files.put(name, new File(picturePath));
//files.put("test.jpg", new File(picturePath));
Log.d("str--->>>", picturePath);
try {
String str = HttpPost.post(uploadUrl, new HashMap
System.out.println("str--->>>" + str);
msg.what = SUCCESS;
} catch (Exception e) {
msg.what = FAILD;
}
mHandler.sendMessage(msg);
}
}.start();
}
@Override
protected void onDestroy() {
show.setVisibility(View.INVISIBLE);
super.onDestroy();
}
}