首页 > 代码库 > 安卓上传图片

安卓上传图片

原理Android客户端模拟一个HTTP的Post请求到服务器端,服务器端接收相应的Post请求后,返回响应信息给给客户端。 PHP服务器<?php   move_uploaded_file($_FILES[file][tmp_name], "./upload/".$_FILES["file"]["name"]); ?> Android客户端复制代码package com.example.uploadfile.app;import android.app.Activity;import android.os.Bundle;import android.os.Environment;import android.os.StrictMode;import android.view.View;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;import java.io.DataOutputStream;import java.io.FileInputStream;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;public class MainActivity extends Activity{    private String fileName = "image.jpg";  //报文中的文件名参数    private String path = Environment.getExternalStorageDirectory().getPath();  //Don‘t use "/sdcard/" here    private String uploadFile = path + "/" + fileName;    //待上传的文件路径    private String postUrl = "http://mycloudnote.sinaapp.com/upload.php"; //处理POST请求的页面    private TextView mText1;    private TextView mText2;    private Button mButton;    @Override    public void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //"文件路径:\n"+        mText1 = (TextView) findViewById(R.id.myText1);        mText1.setText(uploadFile);        //"上传网址:\n"+        mText2 = (TextView) findViewById(R.id.myText2);        mText2.setText(postUrl);        /* 设置mButton的onClick事件处理 */        mButton = (Button) findViewById(R.id.myButton);        mButton.setOnClickListener(new View.OnClickListener()        {            public void onClick(View v)            {                uploadFile();            }        });    }    /* 上传文件至Server的方法 */    private void uploadFile()    {        String end = "\r\n";        String twoHyphens = "--";        String boundary = "*****";        try        {            URL url = new URL(postUrl);            HttpURLConnection con = (HttpURLConnection) url.openConnection();          /* Output to the connection. Default is false,             set to true because post method must write something to the connection */            con.setDoOutput(true);          /* Read from the connection. Default is true.*/            con.setDoInput(true);          /* Post cannot use caches */            con.setUseCaches(false);          /* Set the post method. Default is GET*/            con.setRequestMethod("POST");          /* 设置请求属性 */            con.setRequestProperty("Connection", "Keep-Alive");            con.setRequestProperty("Charset", "UTF-8");            con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);          /*设置StrictMode 否则HTTPURLConnection连接失败,因为这是在主进程中进行网络连接*/            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());          /* 设置DataOutputStream,getOutputStream中默认调用connect()*/            DataOutputStream ds = new DataOutputStream(con.getOutputStream());  //output to the connection            ds.writeBytes(twoHyphens + boundary + end);            ds.writeBytes("Content-Disposition: form-data; " +                    "name=\"file\";filename=\"" +                    fileName + "\"" + end);            ds.writeBytes(end);          /* 取得文件的FileInputStream */            FileInputStream fStream = new FileInputStream(uploadFile);          /* 设置每次写入8192bytes */            int bufferSize = 8192;            byte[] buffer = new byte[bufferSize];   //8k            int length = -1;          /* 从文件读取数据至缓冲区 */            while ((length = fStream.read(buffer)) != -1)            {            /* 将资料写入DataOutputStream中 */                ds.write(buffer, 0, length);            }            ds.writeBytes(end);            ds.writeBytes(twoHyphens + boundary + twoHyphens + end);          /* 关闭流,写入的东西自动生成Http正文*/            fStream.close();          /* 关闭DataOutputStream */            ds.close();          /* 从返回的输入流读取响应信息 */            InputStream is = con.getInputStream();  //input from the connection 正式建立HTTP连接            int ch;            StringBuffer b = new StringBuffer();            while ((ch = is.read()) != -1)            {                b.append((char) ch);            }          /* 显示网页响应内容 */            Toast.makeText(MainActivity.this, b.toString().trim(), Toast.LENGTH_SHORT).show();//Post成功        } catch (Exception e)        {            /* 显示异常信息 */            Toast.makeText(MainActivity.this, "Fail:" + e, Toast.LENGTH_SHORT).show();//Post失败        }    }}复制代码设置连接(HTTP头) -> 建立TCP连接 -> 设置HTTP正文 -> 建立HTTP连接(正式Post)-> 从返回的输入流读取响应信息 1.设置连接(HTTP头)复制代码URL url = new URL(postUrl);HttpURLConnection con = (HttpURLConnection) url.openConnection();/* Output to the connection. Default is false,set to true because post method must write something to the connection */con.setDoOutput(true);/* Read from the connection. Default is true.*/con.setDoInput(true);/* Post cannot use caches */con.setUseCaches(false);/* Set the post method. Default is GET*/con.setRequestMethod("POST");/* 设置请求属性 */con.setRequestProperty("Connection", "Keep-Alive");con.setRequestProperty("Charset", "UTF-8");con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);复制代码 2.建立TCP连接DataOutputStream ds = new DataOutputStream(con.getOutputStream());  //output to the connectioncon.getOutputStream()中会默认调用con.connect(),此时客户端与服务器建立的只是1个TCP连接而非HTTP。HTTP请求=HTTP头+HTTP正文。在connect()里面,会根据HttpURLConnection对象的配置值生成HTTP头,所以对con的一切配置都必须在connect()方法之前完成。 3.设置HTTP正文正文通过DataOutputStream写入,只是写入内存而不会发送到网络中去,而是在流关闭时,根据写入的内容生成HTTP正文。复制代码ds.writeBytes(twoHyphens + boundary + end);ds.writeBytes("Content-Disposition: form-data; " +    "name=\"file\";filename=\"" +    fileName + "\"" + end);ds.writeBytes(end);/* 取得文件的FileInputStream */FileInputStream fStream = new FileInputStream(uploadFile);/* 设置每次写入8192bytes */int bufferSize = 8192;byte[] buffer = new byte[bufferSize];   //8kint length = -1;/* 从文件读取数据至缓冲区 */while ((length = fStream.read(buffer)) != -1){  /* 将资料写入DataOutputStream中 */  ds.write(buffer, 0, length);}ds.writeBytes(end);ds.writeBytes(twoHyphens + boundary + twoHyphens + end);/* 关闭流,写入的东西自动生成Http正文*/fStream.close();/* 关闭DataOutputStream */ds.close();复制代码 4.建立HTTP连接(正式Post)至此,HTTP请求设置完毕,con.getInputStream()中会将请求(HTTP头+HTTP正文)发送到服务器,并返回一个输入流。所以在getInputStream()之前,HTTP正文部分一定要先设置好。InputStream is = con.getInputStream();  //input from the connection 正式建立HTTP连接 5.从返回的输入流读取响应信息复制代码int ch;StringBuffer b = new StringBuffer();while ((ch = is.read()) != -1){  b.append((char) ch);}/* 显示网页响应内容 */Toast.makeText(MainActivity.this, b.toString().trim(), Toast.LENGTH_SHORT).show();//Post成功复制代码 布局XML两个Text和一个Button复制代码<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="${packageName}.${activityClass}">    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="New Text"        android:id="@+id/myText1"        android:layout_above="@+id/myText2"        android:layout_centerHorizontal="true"        android:layout_marginBottom="80dp"/>    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="New Text"        android:id="@+id/myText2"        android:layout_centerVertical="true"        android:layout_centerHorizontal="true"/>    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Upload"        android:id="@+id/myButton"        android:layout_marginTop="80dp"        android:layout_below="@+id/myText2"        android:layout_centerHorizontal="true"/></RelativeLayout>复制代码 AndroidManifest添加网络权限、SD卡读写权限、挂载文件系统权限。复制代码<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.uploadfile.app" >    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name="com.example.uploadfile.app.MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application>    <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="15" />    <uses-permission android:name="android.permission.INTERNET" />    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/></manifest>

 

安卓上传图片