转载请注明出处:
http://blog.csdn.net/iwanghang/article/details/65630703
觉得博文有用,请点赞,请评论,请关注,谢谢!~
转载请注明出处: http://blog.csdn.net/iwanghang/article/details/65630703
觉得博文有用,请点赞,请评论,请关注,谢谢!~
觉得博文有用,请点赞,请评论,请关注,谢谢!~
最近项目中实现多图提交,尝试了base64,16进制 异步上传多图。又尝试了一下Android模拟表单提交,
并且把最近学习的TP5用上,写了一个接收多图的接口,测试成功,在这里分享一下。
先上GIF动态图,看个效果,如果符合你的项目或者确定你要了解的内容,再往下看吧:完整项目下载地址:http://download.csdn.net/detail/iwanghang/9792576
首先,在开始动手前,PHP要和Android协商好字段信息。
比如图片image,标题title,内容desc等等等等,协商好了,我们就开工。
PHP:
PHP方面比较简单,先说一下PHP是如何接收的。
http://192.168.1.111/index.php/admin/article/add 这个是我的本地接口
\application\admin\controller\Article.php 这个是接口的文件
以下是接收表单数据、接收表单上传上来的多图的源码:
<?php
namespace app\admin\controller;
use think\Controller;
class Article extends Controller
{
public function add()
{
if (request()->isPost()) {
$data = [
'title' => input('title'),
'keywords' => input('keywords'),
'desc' => input('desc'),
'cateid' => input('cateid'),
'content' => input('content'),
'time' => time(),
];
// 接收多图
// 获取表单上传文件
$files = request()->file('image');
foreach($files as $file){
// 移动到框架应用根目录/public/uploads/ 目录下
$info = $file->move(ROOT_PATH . 'public' . DS . 'uploads');
if($info){
// 成功上传后 获取上传信息
$data['image'] = 'uploads/'.date('Ymd').'/'.$info->getFilename();
// 输出 jpg
echo "格式:";
echo $info->getExtension();
echo "<br>";
// 输出 42a79759f284b767dfcb2a0197904287.jpg
echo "目录:";
echo $info->getSaveName();
echo "<br>";
}else{
// 上传失败获取错误信息
echo $file->getError();
}
}
return json_encode(\think\Request::instance()->request(false));
return;
}
$cateres = db('cate')->select(); // 查询所有栏目名称
$this->assign('cateres',$cateres); // 分配模板
return $this->fetch();
}
}
Android:
1.首先在Manifest里,申请一堆权限:
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.iwanghang.moreimageupload">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.CAMERA"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.iwanghang.moreimageupload.logic.ImgFileListActivity"
android:label="@string/app_name" >
</activity>
<activity
android:name="com.iwanghang.moreimageupload.logic.ImgsActivity"
android:label="@string/app_name" >
</activity>
</application>
</manifest>
2.我们拆分开多图选择,和多图上传:
2.1.多图选择:
MainActivity.java:
public class MainActivity extends Activity {
// 图片选择
ListView listView;
ArrayList<String> listfile=new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 图片选择
listView=(ListView) findViewById(R.id.listView1);
Bundle bundle= getIntent().getExtras();
if (bundle!=null) {
if (bundle.getStringArrayList("files")!=null) {
listfile = bundle.getStringArrayList("files");
listView.setVisibility(View.VISIBLE);
ArrayAdapter<String> arryAdapter=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listfile);
listView.setAdapter(arryAdapter);
}
}
}
public void chise(View v){
Intent intent = new Intent();
intent.setClass(this,ImgFileListActivity.class);
startActivity(intent);
}
}
logic\FileTraversal.java:
package com.iwanghang.moreimageupload.logic;
import java.util.ArrayList;
import java.util.List;
import android.annotation.SuppressLint;
import android.os.Parcel;
import android.os.Parcelable;
// 文件的类
@SuppressLint("ParcelCreator")
public class FileTraversal implements Parcelable {
public String filename;//所属图片的文件名称
public List<String> filecontent=new ArrayList<String>();
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(filename);
dest.writeList(filecontent);
}
public static final Parcelable.Creator<FileTraversal> CREATOR=new Creator<FileTraversal>() {
@Override
public FileTraversal[] newArray(int size) {
return null;
}
@Override
public FileTraversal createFromParcel(Parcel source) {
FileTraversal ft=new FileTraversal();
ft.filename= source.readString();
ft.filecontent= source.readArrayList(FileTraversal.class.getClassLoader());
return ft;
}
};
}
logic\ImgCallBack.java:
package com.iwanghang.moreimageupload.logic;
import android.graphics.Bitmap;
import android.widget.ImageView;
public interface ImgCallBack {
public void resultImgCall(ImageView imageView, Bitmap bitmap);
}
logic\ImgFileListActivity.java:
package com.iwanghang.moreimageupload.logic;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import com.iwanghang.moreimageupload.R;
public class ImgFileListActivity extends Activity implements OnItemClickListener{
ListView listView;
Util util;
ImgFileListAdapter listAdapter;
List<FileTraversal> locallist;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.imgfilelist);
listView=(ListView) findViewById(R.id.listView1);
util=new Util(this);
locallist=util.LocalImgFileList();
List<HashMap<String, String>> listdata=new ArrayList<HashMap<String,String>>();
Bitmap bitmap[] = null;
if (locallist!=null) {
bitmap=new Bitmap[locallist.size()];
for (int i = 0; i < locallist.size(); i++) {
HashMap<String, String> map=new HashMap<String, String>();
map.put("filecount", locallist.get(i).filecontent.size()+"张");
map.put("imgpath", locallist.get(i).filecontent.get(0)==null?null:(locallist.get(i).filecontent.get(0)));
map.put("filename", locallist.get(i).filename);
listdata.add(map);
}
}
listAdapter=new ImgFileListAdapter(this, listdata);
listView.setAdapter(listAdapter);
listView.setOnItemClickListener(this);
}
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
Intent intent=new Intent(this,ImgsActivity.class);
Bundle bundle=new Bundle();
bundle.putParcelable("data", locallist.get(arg2));
intent.putExtras(bundle);
startActivity(intent);
}
}
logic\ImgFileListAdapter.java:
package com.iwanghang.moreimageupload.logic;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.iwanghang.moreimageupload.R;
public class ImgFileListAdapter extends BaseAdapter{
Context context;
String filecount="filecount";
String filename="filename";
String imgpath="imgpath";
List<HashMap<String, String>> listdata;
Util util;
Bitmap[] bitmaps;
private int index=-1;
List<View> holderlist;
public ImgFileListAdapter(Context context,List<HashMap<String, String>> listdata) {
this.context=context;
this.listdata=listdata;
bitmaps=new Bitmap[listdata.size()];
util=new Util(context);
holderlist=new ArrayList<View>();
}
@Override
public int getCount() {
return listdata.size();
}
@Override
public Object getItem(int arg0) {
return listdata.get(arg0);
}
@Override
public long getItemId(int arg0) {
return arg0;
}
@Override
public View getView(final int arg0, View arg1, ViewGroup arg2) {
Holder holder;
if (arg0 != index && arg0 > index) {
holder=new Holder();
arg1=LayoutInflater.from(context).inflate(R.layout.imgfileadapter, null);
holder.photo_imgview=(ImageView) arg1.findViewById(R.id.filephoto_imgview);
holder.filecount_textview=(TextView) arg1.findViewById(R.id.filecount_textview);
holder.filename_textView=(TextView) arg1.findViewById(R.id.filename_textview);
arg1.setTag(holder);
holderlist.add(arg1);
}else{
holder= (Holder)holderlist.get(arg0).getTag();
arg1=holderlist.get(arg0);
}
holder.filename_textView.setText(listdata.get(arg0).get(filename));
holder.filecount_textview.setText(listdata.get(arg0).get(filecount));
if (bitmaps[arg0] == null) {
util.imgExcute(holder.photo_imgview,new ImgCallBack() {
@Override
public void resultImgCall(ImageView imageView, Bitmap bitmap) {
bitmaps[arg0]=bitmap;
imageView.setImageBitmap(bitmap);
}
}, listdata.get(arg0).get(imgpath));
}
else {
holder.photo_imgview.setImageBitmap(bitmaps[arg0]);
}
return arg1;
}
class Holder{
public ImageView photo_imgview;
public TextView filecount_textview;
public TextView filename_textView;
}
}
logic\ImgsActivity.java:
package com.iwanghang.moreimageupload.logic;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.RelativeLayout;
import com.iwanghang.moreimageupload.MainActivity;
import com.iwanghang.moreimageupload.R;
public class ImgsActivity extends Activity {
Bundle bundle;
FileTraversal fileTraversal;
GridView imgGridView;
ImgsAdapter imgsAdapter;
LinearLayout select_layout;
Util util;
RelativeLayout relativeLayout2;
HashMap<Integer, ImageView> hashImage;
Button choise_button;
ArrayList<String> filelist;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.photogrally);
imgGridView=(GridView) findViewById(R.id.gridView1);
bundle= getIntent().getExtras();
fileTraversal=bundle.getParcelable("data");
imgsAdapter=new ImgsAdapter(this, fileTraversal.filecontent,onItemClickClass);
imgGridView.setAdapter(imgsAdapter);
select_layout=(LinearLayout) findViewById(R.id.selected_image_layout);
relativeLayout2=(RelativeLayout) findViewById(R.id.relativeLayout2);
choise_button=(Button) findViewById(R.id.button3);
hashImage=new HashMap<Integer, ImageView>();
filelist=new ArrayList<String>();
// imgGridView.setOnItemClickListener(this);
util=new Util(this);
}
class BottomImgIcon implements OnItemClickListener{
int index;
public BottomImgIcon(int index) {
this.index=index;
}
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
}
}
@SuppressLint("NewApi")
public ImageView iconImage(String filepath,int index,CheckBox checkBox) throws FileNotFoundException{
LinearLayout.LayoutParams params=new LayoutParams(relativeLayout2.getMeasuredHeight()-10, relativeLayout2.getMeasuredHeight()-10);
ImageView imageView=new ImageView(this);
imageView.setLayoutParams(params);
imageView.setBackgroundResource(R.drawable.imgbg);
float alpha=100;
imageView.setAlpha(alpha);
util.imgExcute(imageView, imgCallBack, filepath);
imageView.setOnClickListener(new ImgOnclick(filepath,checkBox));
return imageView;
}
ImgCallBack imgCallBack=new ImgCallBack() {
@Override
public void resultImgCall(ImageView imageView, Bitmap bitmap) {
imageView.setImageBitmap(bitmap);
}
};
class ImgOnclick implements OnClickListener{
String filepath;
CheckBox checkBox;
public ImgOnclick(String filepath,CheckBox checkBox) {
this.filepath=filepath;
this.checkBox=checkBox;
}
@Override
public void onClick(View arg0) {
checkBox.setChecked(false);
select_layout.removeView(arg0);
choise_button.setText("已选择("+select_layout.getChildCount()+")张");
filelist.remove(filepath);
}
}
ImgsAdapter.OnItemClickClass onItemClickClass=new ImgsAdapter.OnItemClickClass() {
@Override
public void OnItemClick(View v, int Position, CheckBox checkBox) {
String filapath=fileTraversal.filecontent.get(Position);
if (checkBox.isChecked()) {
checkBox.setChecked(false);
select_layout.removeView(hashImage.get(Position));
filelist.remove(filapath);
choise_button.setText("已选择("+select_layout.getChildCount()+")张");
}else {
try {
checkBox.setChecked(true);
Log.i("img", "img choise position->"+Position);
ImageView imageView=iconImage(filapath, Position,checkBox);
if (imageView !=null) {
hashImage.put(Position, imageView);
filelist.add(filapath);
Log.i("filapath", "choise filapath->"+filapath);
Log.i("filelist", "choise filelist->"+filelist);
select_layout.addView(imageView);
choise_button.setText("已选择("+select_layout.getChildCount()+")张");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
};
public void tobreak(View view){
finish();
}
/**
* FIXME
* 只需要在这个方法把选中的文档目录已list的形式传过去即可
* @param view
*/
public void sendfiles(View view){
Intent intent =new Intent(this, MainActivity.class);
Bundle bundle=new Bundle();
bundle.putStringArrayList("files", filelist);
intent.putExtras(bundle);
startActivity(intent);
}
}
logic\ImgsAdapter.java:
package com.iwanghang.moreimageupload.logic;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import com.iwanghang.moreimageupload.R;
public class ImgsAdapter extends BaseAdapter {
Context context;
List<String> data;
public Bitmap bitmaps[];
Util util;
OnItemClickClass onItemClickClass;
private int index=-1;
List<View> holderlist;
public ImgsAdapter(Context context,List<String> data,OnItemClickClass onItemClickClass) {
this.context=context;
this.data=data;
this.onItemClickClass=onItemClickClass;
bitmaps=new Bitmap[data.size()];
util=new Util(context);
holderlist=new ArrayList<View>();
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int arg0) {
return data.get(arg0);
}
@Override
public long getItemId(int arg0) {
return arg0;
}
public void setIndex(int index) {
this.index = index;
}
@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
Holder holder;
if (arg0 != index && arg0 > index) {
index=arg0;
arg1=LayoutInflater.from(context).inflate(R.layout.imgsitem, null);
holder=new Holder();
holder.imageView=(ImageView) arg1.findViewById(R.id.imageView1);
holder.checkBox=(CheckBox) arg1.findViewById(R.id.checkBox1);
arg1.setTag(holder);
holderlist.add(arg1);
}else {
holder= (Holder)holderlist.get(arg0).getTag();
arg1=holderlist.get(arg0);
}
if (bitmaps[arg0] == null) {
util.imgExcute(holder.imageView,new ImgClallBackLisner(arg0), data.get(arg0));
}
else {
holder.imageView.setImageBitmap(bitmaps[arg0]);
}
arg1.setOnClickListener(new OnPhotoClick(arg0, holder.checkBox));
return arg1;
}
class Holder{
ImageView imageView;
CheckBox checkBox;
}
public class ImgClallBackLisner implements ImgCallBack{
int num;
public ImgClallBackLisner(int num) {
this.num=num;
}
@Override
public void resultImgCall(ImageView imageView, Bitmap bitmap) {
bitmaps[num]=bitmap;
imageView.setImageBitmap(bitmap);
}
}
public interface OnItemClickClass{
public void OnItemClick(View v, int Position, CheckBox checkBox);
}
class OnPhotoClick implements OnClickListener{
int position;
CheckBox checkBox;
public OnPhotoClick(int position,CheckBox checkBox) {
this.position=position;
this.checkBox=checkBox;
}
@Override
public void onClick(View v) {
if (data!=null && onItemClickClass!=null ) {
onItemClickClass.OnItemClick(v, position, checkBox);
}
}
}
}
logic\Util.java:
package com.iwanghang.moreimageupload.logic;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.view.Display;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
public class Util {
Context context;
public Util(Context context) {
this.context=context;
}
/**
* 获取全部图片地址
* @return
*/
public ArrayList<String> listAlldir(){
Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Uri uri = intent.getData();
ArrayList<String> list = new ArrayList<String>();
String[] proj ={MediaStore.Images.Media.DATA};
Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null);//managedQuery(uri, proj, null, null, null);
while(cursor.moveToNext()){
String path =cursor.getString(0);
list.add(new File(path).getAbsolutePath());
}
return list;
}
public List<FileTraversal> LocalImgFileList(){
List<FileTraversal> data=new ArrayList<FileTraversal>();
String filename="";
List<String> allimglist=listAlldir();
List<String> retulist=new ArrayList<String>();
if (allimglist!=null) {
Set set = new TreeSet();
String []str;
for (int i = 0; i < allimglist.size(); i++) {
retulist.add(getfileinfo(allimglist.get(i)));
}
for (int i = 0; i < retulist.size(); i++) {
set.add(retulist.get(i));
}
str= (String[]) set.toArray(new String[0]);
for (int i = 0; i < str.length; i++) {
filename=str[i];
FileTraversal ftl= new FileTraversal();
ftl.filename=filename;
data.add(ftl);
}
for (int i = 0; i < data.size(); i++) {
for (int j = 0; j < allimglist.size(); j++) {
if (data.get(i).filename.equals(getfileinfo(allimglist.get(j)))) {
data.get(i).filecontent.add(allimglist.get(j));
}
}
}
}
return data;
}
// 显示原生图片尺寸大小
public Bitmap getPathBitmap(Uri imageFilePath,int dw,int dh)throws FileNotFoundException{
//获取屏幕的宽和高
/**
* 为了计算缩放的比例,我们需要获取整个图片的尺寸,而不是图片
* BitmapFactory.Options类中有一个布尔型变量inJustDecodeBounds,将其设置为true
* 这样,我们获取到的就是图片的尺寸,而不用加载图片了。
* 当我们设置这个值的时候,我们接着就可以从BitmapFactory.Options的outWidth和outHeight中获取到值
*/
BitmapFactory.Options op = new BitmapFactory.Options();
op.inJustDecodeBounds = true;
//由于使用了MediaStore存储,这里根据URI获取输入流的形式
Bitmap pic = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(imageFilePath),
null, op);
int wRatio = (int) Math.ceil(op.outWidth / (float) dw); //计算宽度比例
int hRatio = (int) Math.ceil(op.outHeight / (float) dh); //计算高度比例
/**
* 接下来,我们就需要判断是否需要缩放以及到底对宽还是高进行缩放。
* 如果高和宽不是全都超出了屏幕,那么无需缩放。
* 如果高和宽都超出了屏幕大小,则如何选择缩放呢》
* 这需要判断wRatio和hRatio的大小
* 大的一个将被缩放,因为缩放大的时,小的应该自动进行同比率缩放。
* 缩放使用的还是inSampleSize变量
*/
if (wRatio > 1 && hRatio > 1) {
if (wRatio > hRatio) {
op.inSampleSize = wRatio;
} else {
op.inSampleSize = hRatio;
}
}
op.inJustDecodeBounds = false; //注意这里,一定要设置为false,因为上面我们将其设置为true来获取图片尺寸了
pic = BitmapFactory.decodeStream(context.getContentResolver()
.openInputStream(imageFilePath), null, op);
return pic;
}
public String getfileinfo(String data){
String filename[]= data.split("/");
if (filename!=null) {
return filename[filename.length-2];
}
return null;
}
public void imgExcute(ImageView imageView,ImgCallBack icb, String... params){
LoadBitAsynk loadBitAsynk=new LoadBitAsynk(imageView,icb);
loadBitAsynk.execute(params);
}
public class LoadBitAsynk extends AsyncTask<String, Integer, Bitmap>{
ImageView imageView;
ImgCallBack icb;
LoadBitAsynk(ImageView imageView,ImgCallBack icb){
this.imageView=imageView;
this.icb=icb;
}
@Override
protected Bitmap doInBackground(String... params) {
Bitmap bitmap=null;
try {
if (params!=null) {
for (int i = 0; i < params.length; i++) {
bitmap=getPathBitmap(Uri.fromFile(new File(params[i])), 200, 200);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (result!=null) {
// imageView.setImageBitmap(result);
icb.resultImgCall(imageView, result);
}
}
}
}
2.2.多图上传:
MainActivity.java:
public class MainActivity extends Activity {
// 图片上传
/**
* 上传的进度
*/
private SeekBar progress;
/**
* 后台返回的结果
*/
private TextView tv_result;
private String url = "http://192.168.1.111/index.php/admin/article/add";
private EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 图片上传
progress = (SeekBar) findViewById(R.id.seekBar1);
tv_result = (TextView) findViewById(R.id.textView2);
editText = (EditText) findViewById(R.id.editText); // API url
findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MultiUpload.IuploadProgress iuploadProgress = new MultiUpload.IuploadProgress() {
@Override
public void uploadProgress(int progress) {
// 进度条显示进度
MainActivity.this.progress.setMax(100);
MainActivity.this.progress.setProgress(progress);
}
@Override
public void connectTimeOut() {
}
@Override
public void uploadSuccess(String success) {
tv_result.setText(success);
}
};
List<BasicNameValuePair> texts = new ArrayList<BasicNameValuePair>();
// 随便写了一些键名 键名 添加到数组
texts.add(new BasicNameValuePair("title", "777"));
texts.add(new BasicNameValuePair("keywords", "777"));
texts.add(new BasicNameValuePair("desc", "777"));
texts.add(new BasicNameValuePair("cateid", "777"));
texts.add(new BasicNameValuePair("content", "777"));
texts.add(new BasicNameValuePair("aaa", "1"));
texts.add(new BasicNameValuePair("bbb", "1"));
texts.add(new BasicNameValuePair("ccc", "1"));
HashMap<File, String> files = new HashMap<File, String>();
// 把内存卡的图片1.jpg 2.jpg 3.jpg 添加到数组
//files.put(new File(Environment.getExternalStorageDirectory(),"1.jpg"), "image[]");
//files.put(new File(Environment.getExternalStorageDirectory(),"2.jpg"), "image[]");
//files.put(new File(Environment.getExternalStorageDirectory(),"3.jpg"), "image[]");
// 把多图选择的图片 添加到数组
Log.e("listfile.size()", String.valueOf(listfile.size()));
for (int i=0;i<listfile.size();i++){
File file = new File(listfile.get(i));
files.put(file, "image[]");
}
url = editText.getText().toString();
new MultiUpload(url, iuploadProgress).upload(texts, files);
}
});
}
}
MultiUpload.java:
package com.iwanghang.moreimageupload;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.util.EntityUtils;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
/**
* 上传表单数据(多文件和多文本)
*/
public class MultiUpload {
/**
* 请求的服务器地址
*/
private String url;
private Handler handler;
private DefaultHttpClient defaultHttpClient;
/**
* 上传的文本集合...........
*/
private List<BasicNameValuePair> texts;
/**
* 上传的文件集合..........
*/
private HashMap<File, String> files;
public MultiUpload(String url, final IuploadProgress iuploadProgress) {
this.url = url;
this.handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0:
// 上传进度...........
iuploadProgress.uploadProgress((Integer) msg.obj);
break;
case 1:
// 连接超时
iuploadProgress.connectTimeOut();
break;
case 2:
// 上传成功,看服务返回的结果...........
iuploadProgress.uploadSuccess((String) msg.obj);
break;
default:
break;
}
}
};
// 死机........
if (TextUtils.isEmpty(url)) {
throw new IllegalArgumentException("请求的服务器地址为空");
}
}
/**
* @param texts
* 文本数据集合
* @param files
* 文件数据集合 因为上传文件的key有可能相同(name="files[]),所以HashMap<File, String>
*
*
* <form method="post"
* action="http://192.168.2.145/wuxifu/test/uploadMulti.php"
* enctype="multipart/form-data"> <input type="file"
* name="files[]"><br/>
* <input type="file" name="files[]"><br/>
* <input type="file" name="files[]"><br/>
* <input type="text" name="name"></br/> <input type="text"
* name="age"></br/> <input type="submit" value="submit"> </form>
*/
public void upload(List<BasicNameValuePair> texts, HashMap<File, String> files) {
this.texts = texts;
this.files = files;
new Thread() {
public void run() {
iniClient();
HttpPost httpPost = iniHttpPost();
try {
HttpResponse httpResponse = defaultHttpClient
.execute(httpPost);
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
// 上传成功
closeConnect();
//由于我这边服务器编码为gbk,所以编码设置gbk,如果乱码就改为utf-8
String result = EntityUtils.toString(
httpResponse.getEntity(), "utf-8");
Log.e("上传成功........", result);
Message msg = handler.obtainMessage(2, result);
handler.sendMessage(msg);
}
} catch (ClientProtocolException e) {
// e.printStackTrace();
handler.sendEmptyMessage(1);
} catch (IOException e) {
// e.printStackTrace();
handler.sendEmptyMessage(1);
}
}
}.start();
}
/**
* 初始化post的内容
*
* @return HttpPost
*/
protected HttpPost iniHttpPost() {
HttpPost httpPost = new HttpPost(url);
// MultipartEntityBuilder
MultipartEntityBuilder create = MultipartEntityBuilder.create();
// 普通文本的发送,用户名&密码等
if (texts != null && texts.size() > 0) {
for (BasicNameValuePair iterable_element : texts) {
create.addTextBody(iterable_element.getName(),
iterable_element.getValue());
Log.i("key",iterable_element.getName());
Log.i("value",iterable_element.getValue());
}
}
// 二进制的发送,文件
if (files != null && files.size() > 0) {
Set<Entry<File, String>> entrySet = files.entrySet();
for (Entry<File, String> iterable_element : entrySet) {
create.addBinaryBody(iterable_element.getValue(), iterable_element.getKey());
//create.addBinaryBody("111", iterable_element.getKey());
//create.addBinaryBody("albumFile", iterable_element.getKey(), ContentType.create("image/jpeg"), iterable_element.getValue());
Log.i("key", String.valueOf(iterable_element.getKey()));
Log.i("value", String.valueOf(iterable_element.getValue()));
}
}
HttpEntity httpEntity = create.build();
// 上传内容的长度.............
final long contentLength = httpEntity.getContentLength();
ProgressOutHttpEntity progressOutHttpEntity = new ProgressOutHttpEntity(
httpEntity, new ProgressOutHttpEntity.ProgressListener() {
@Override
public void transferred(long transferedBytes) {
int currentProgress = (int) (100 * transferedBytes / contentLength);
// 当前进度.............
Message msg = handler.obtainMessage(0, currentProgress);
handler.sendMessage(msg);
}
});
// post内容的设置............
httpPost.setEntity(progressOutHttpEntity);
return httpPost;
}
/**
* 初始化httpClient
*/
private void iniClient() {
if (defaultHttpClient == null) {
defaultHttpClient = new DefaultHttpClient();
// HTTP协议版本1.1
defaultHttpClient.getParams().setParameter(
CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
// 连接超时
defaultHttpClient.getParams().setParameter(
CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);
}
};
/**
* 关闭连接
*/
private void closeConnect(){
if(defaultHttpClient!=null){
ClientConnectionManager connectionManager = defaultHttpClient.getConnectionManager();
if(connectionManager!=null)
connectionManager.shutdown();
defaultHttpClient=null;
}
}
public interface IuploadProgress {
/**
* 上传的进度
*
* @param progress
* (1-100)100就是上传完毕.......
*/
public void uploadProgress(int progress);
/**
* @param success
* 上传成功...........
*/
public void uploadSuccess(String success);
/**
* 连接超时
*/
public void connectTimeOut();
}
}
ProgressOutHttpEntity.java:
package com.iwanghang.moreimageupload;
import org.apache.http.HttpEntity;
import org.apache.http.entity.HttpEntityWrapper;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* ProgressOutHttpEntity:输出流(OutputStream)时记录已发送字节数
*/
public class ProgressOutHttpEntity extends HttpEntityWrapper {
/**进度监听对象**/
private final ProgressListener listener;
public ProgressOutHttpEntity(final HttpEntity entity,final ProgressListener listener) {
super(entity);
this.listener = listener;
}
@Override
public void writeTo(final OutputStream out) throws IOException {
this.wrappedEntity.writeTo(out instanceof CountingOutputStream ? out
: new CountingOutputStream(out, this.listener));
}
/**
* 进度监听器接口
*/
public interface ProgressListener {
public void transferred(long transferedBytes);
}
/**
* @author wuxif_000 内部类...........
*
*/
public static class CountingOutputStream extends FilterOutputStream {
private final ProgressListener listener;
private long transferred;
CountingOutputStream(final OutputStream out,
final ProgressListener listener) {
super(out);
this.listener = listener;
this.transferred = 0;
}
@Override
public void write(final byte[] b, final int off, final int len)
throws IOException {
out.write(b, off, len);
this.transferred += len;
this.listener.transferred(this.transferred);
}
@Override
public void write(final int b) throws IOException {
out.write(b);
this.transferred++;
this.listener.transferred(this.transferred);
}
}
}
最后,不要忘记jar包:
httpclient-4.2.5.jar
httpcore-4.3.3.jar
httpmime-4.3.6.jar
还有,暴力解决冲突的方法:以下代码加入build.gradle:
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
}
补充,Layout忘记贴出来了:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
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="com.iwanghang.moreimageupload.MainActivity">
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/button1" >
</ListView>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:text="http://192.168.1.111/index.php/admin/article/add"
android:ems="10"
android:textSize="12dp"
android:layout_alignParentTop="true"
android:id="@+id/editText"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_toRightOf="@+id/textView"
android:layout_toEndOf="@+id/textView" />
<TextView
android:text="接口地址"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView"
android:layout_alignBaseline="@+id/editText"
android:layout_alignBottom="@+id/editText"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:layout_below="@+id/seekBar1"
android:layout_centerHorizontal="true"
android:layout_marginTop="40dp" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始上传"
android:layout_below="@+id/textView2"
android:layout_alignLeft="@+id/button1"
android:layout_alignStart="@+id/button1" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="hello"
android:layout_below="@+id/button2"
android:layout_centerHorizontal="true"
android:layout_marginTop="18dp" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="选择图片"
android:onClick="chise"
android:layout_below="@+id/textView1"
android:layout_centerHorizontal="true" />
<SeekBar
android:id="@+id/seekBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="26dp"
android:layout_below="@+id/editText"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:text="图片键名为image[],还有字段title、keywords、desc等"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textColor="@color/colorPrimaryDark"
android:id="@+id/textView3"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
imgfileadapter.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:id="@+id/filephoto_imgview"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/imgbg"
android:layout_marginLeft="10dp"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginLeft="10dp"
android:gravity="left|center_vertical"
>
<TextView
android:id="@+id/filename_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="文件名称"
android:textColor="@android:color/black"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<TextView
android:id="@+id/filecount_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="几张"
android:textSize="16dp"
android:textColor="#8B7D7B"
/>
</LinearLayout>
</LinearLayout>
imgfilelist.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#EFEFEF"
>
<ListView
android:id="@+id/listView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ListView>
</LinearLayout>
imgsitem.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/imageView1"
android:layout_margin="4dp"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:layout_centerInParent="true"
android:src="@drawable/imgbg"
/>
<CheckBox
android:id="@+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="@+id/imageView1"
android:layout_alignTop="@+id/imageView1"
android:checked="false"
android:focusable="false"
android:clickable="false"
/>
</RelativeLayout>
photogrally.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#EFEFEF"
>
<RelativeLayout
android:id="@+id/relativeLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="@android:color/white"
>
<Button
android:id="@+id/button1"
android:layout_margin="2dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="返回"
android:textColor="@android:color/black"
android:background="#ADD8E6"
android:onClick="tobreak"
/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:background="#ADFF2F"
android:textColor="@android:color/black"
android:layout_margin="2dp"
android:onClick="sendfiles"
android:text="发送" />
</RelativeLayout>
<GridView
android:id="@+id/gridView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_below="@+id/relativeLayout1"
android:listSelector="@color/bule_overlay"
android:numColumns="3" >
</GridView>
<RelativeLayout
android:id="@+id/relativeLayout2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:alpha="0.8"
android:background="@android:color/black" >
<HorizontalScrollView
android:id="@+id/scrollview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/button3"
android:scrollbars="none" >
<LinearLayout
android:id="@+id/selected_image_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal" >
</LinearLayout>
</HorizontalScrollView>
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:background="#ADD8E6"
android:visibility="visible"
android:textColor="@android:color/black"
android:text="已选择(0)张" />
</RelativeLayout>
</RelativeLayout>
完整项目下载地址:http://download.csdn.net/detail/iwanghang/9792576
转载请注明出处: http://blog.csdn.net/iwanghang/article/details/65630703
欢迎移动开发爱好者交流
沈阳或周边城市公司有意开发Android,请与我联系
联系方式
微信:iwanghang
QQ:413711276
邮箱:iwanghang@qq.com
沈阳或周边城市公司有意开发Android,请与我联系
联系方式
微信:iwanghang
QQ:413711276
邮箱:iwanghang@qq.com
觉得博文有用,请点赞,请评论,请关注,谢谢!~