Android原生模拟表单提交上传多图+PHP接收表单数据和多图存储

时间:2022-08-28 09:31:50
转载请注明出处: http://blog.csdn.net/iwanghang/article/details/65630703
觉得博文有用,请点赞,请评论,请关注,谢谢!~

最近项目中实现多图提交,尝试了base64,16进制 异步上传多图。又尝试了一下Android模拟表单提交,

并且把最近学习的TP5用上,写了一个接收多图的接口,测试成功,在这里分享一下。

先上GIF动态图,看个效果,如果符合你的项目或者确定你要了解的内容,再往下看吧:

Android原生模拟表单提交上传多图+PHP接收表单数据和多图存储


完整项目下载地址: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 这个是接口的文件

以下是接收表单数据、接收表单上传上来的多图的源码:

<?phpnamespace 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>();@Overridepublic int describeContents() {return 0;}@Overridepublic void writeToParcel(Parcel dest, int flags) {dest.writeString(filename);dest.writeList(filecontent);}public static final Parcelable.Creator<FileTraversal> CREATOR=new Creator<FileTraversal>() {@Overridepublic FileTraversal[] newArray(int size) {return null;}@Overridepublic 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;@Overrideprotected 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);}@Overridepublic 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>();}@Overridepublic int getCount() {return listdata.size();}@Overridepublic Object getItem(int arg0) {return listdata.get(arg0);}@Overridepublic long getItemId(int arg0) {return arg0;}@Overridepublic 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() {@Overridepublic 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;@Overrideprotected 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;}@Overridepublic 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() {@Overridepublic 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;}@Overridepublic 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() {@Overridepublic 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>();}@Overridepublic int getCount() {return data.size();}@Overridepublic Object getItem(int arg0) {return data.get(arg0);}@Overridepublic long getItemId(int arg0) {return arg0;}public void setIndex(int index) {this.index = index;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overrideprotected 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;}@Overrideprotected 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() {@Overridepublic 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-8String 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);// MultipartEntityBuilderMultipartEntityBuilder 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() {@Overridepublic 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.1defaultHttpClient.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,请与我联系
联系方式
Android原生模拟表单提交上传多图+PHP接收表单数据和多图存储
微信:iwanghang
QQ:413711276
邮箱:iwanghang@qq.com



觉得博文有用,请点赞,请评论,请关注,谢谢!~