Android端通过Okhttp与PHP服务器进行交互并实现文件上传下载(一)

来源:互联网 发布:淘宝卖家让我售后 编辑:程序博客网 时间:2024/06/05 10:43

简介

  • 由于Android给我们提供的Http请求方式之一 :HttpURLConnection,使用起来非常麻烦,所以一般我们实际开发并不会用HttpURLConnection和HttpClient,而是会使用别人封装好的第三方网络请求框架,诸如:Volley,android-async-http,loopj,OkHttp等,因为网络操作涉及到 异步以及多线程,自己动手写的话,很麻烦,所以实际开发还是直接用第三方。
  • 这里我们选择的是近来最火的开源HTTP框架——OKHttp,来实现Android客户端的工作。
  • GitHub地址:https://github.com/square/okhttp
  • 上传功能包含了一个简单的文件选择器
  • 下载功能目前做得极不完善,几乎等于没做,后续还会改进

准备工作

  1. 新建一个安卓工程
  2. 从官方网站上下载okhttp和okio的jar包
    okhttp的下载地址:http://square.github.io/okhttp/
    okio的下载地址:
    https://repo1.maven.org/maven2/com/squareup/okio/okio/1.11.0/okio-1.11.0.jar
    okio的jar包的下载地址其实就在okhttp的官网上,不一定用我给的链接去下载。
    PS.也可以通过Maven或者Gradle来导入,但因为速度太慢,所以我直接下了jar包

3.将这两个jar包导入到工程中,放在libs目录下

右键点击jar包,选择Add As Library就行了,两个包都要添加。

这里写图片描述

下面是具体代码

MainActivity.java

package com.example.ywy.mycloud1;    import java.io.FileOutputStream;    import java.io.IOException;    import android.Manifest;    import android.app.Activity;    import android.content.Intent;    import android.content.pm.PackageManager;    import android.graphics.Bitmap;    import android.net.Uri;    import android.os.Build;    import android.os.Environment;    import android.support.v4.app.ActivityCompat;    import android.support.v4.content.ContextCompat;    import android.support.v7.app.AppCompatActivity;    import android.os.Bundle;    import android.view.View;    import android.widget.Button;    import android.widget.ProgressBar;    import android.widget.TextView;    import android.widget.Toast;    import java.io.File;    import java.io.IOException;    import java.io.InputStream;    import java.util.concurrent.TimeUnit;    import okhttp3.Call;    import okhttp3.Callback;    import okhttp3.Interceptor;    import okhttp3.MediaType;    import okhttp3.MultipartBody;    import okhttp3.OkHttpClient;    import okhttp3.Request;    import okhttp3.RequestBody;    import okhttp3.Response;    import okhttp3.ResponseBody;    import okio.Buffer;    import okio.BufferedSink;    import okio.BufferedSource;    import okio.ForwardingSink;    import okio.ForwardingSource;    import okio.Okio;    import okio.Sink;    import okio.Source;    public class MainActivity extends AppCompatActivity {        private OkHttpClient okHttpClient;        private TextView textView;        private File tempFile;        private File targetFile;        private String path;        private Button button1;        private Button button2;        private Button button3;        private Button button4;        //private long time;        private static final int REQUEST_EXTERNAL_STORAGE = 1;        private static final int FILE_SELECT_CODE = 1;        private static String[] PERMISSIONS_STORAGE = {                Manifest.permission.READ_EXTERNAL_STORAGE,                Manifest.permission.WRITE_EXTERNAL_STORAGE        };        @Override        protected void onCreate(Bundle savedInstanceState) {            super.onCreate(savedInstanceState);            setContentView(R.layout.activity_main);            setTitle("上传文件并显示进度");            //verifyStoragePermissions(MainActivity.this);            textView = (TextView) findViewById(R.id.tv1);            button1 = (Button) findViewById(R.id.btn_choose);            button2 = (Button) findViewById(R.id.btn_upload);            button3 = (Button) findViewById(R.id.btn_download);            button4 = (Button) findViewById(R.id.btn_display);            path = "";            okHttpClient = new OkHttpClient.Builder()                    .readTimeout(60, TimeUnit.SECONDS)                    .connectTimeout(10, TimeUnit.SECONDS)                    .writeTimeout(120, TimeUnit.SECONDS)                    .build();            button1.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    showFileChooser();                }            });            button2.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    startUploadClick();                }            });            button3.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    startDownloadClick();                }            });            button4.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    Intent intent = new Intent(MainActivity.this,DisplayActivity.class);                    startActivity(intent);                }            });        }                //打开文件选择器        private void showFileChooser() {            Intent intent = new Intent(Intent.ACTION_GET_CONTENT);            intent.setType("*/*");            intent.addCategory(Intent.CATEGORY_OPENABLE);            try {                startActivityForResult( Intent.createChooser(intent, "Select a File to Upload"), FILE_SELECT_CODE);            } catch (android.content.ActivityNotFoundException ex) {                Toast.makeText(this, "Please install a File Manager.",  Toast.LENGTH_SHORT).show();            }        }        @Override        protected void onActivityResult(int requestCode, int resultCode, Intent data)  {            switch (requestCode) {                case FILE_SELECT_CODE:                    if (resultCode == RESULT_OK) {                        // Get the Uri of the selected file                        Uri uri = data.getData();                        path = FileUtils.getPath(this, uri);                    }                    break;            }            super.onActivityResult(requestCode, resultCode, data);        }        public String getFileName(String pathandname){            int start=pathandname.lastIndexOf("/");            //int end=pathandname.lastIndexOf("");            if(start!=-1 ){                return pathandname.substring(start+1);            }else{                return null;            }        }        //点击按钮开始上传文件        public void startUploadClick() {            //tempFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "test1.txt");            //showFileChooser();            String fileName = "";            tempFile = new File(path);            //tempFile = new File("/data/data/upload/man.jpg");            if (tempFile.getName() == null){                Toast.makeText(MainActivity.this, "找不到该文件!", Toast.LENGTH_SHORT).show();            }            else {                fileName = getFileName(path);            }            RequestBody requestBody = new MultipartBody.Builder()                    .setType(MultipartBody.FORM)                    .addFormDataPart("file", fileName, RequestBody.create(MediaType.parse("image/jpg"), tempFile))                    .build();            //ProgressRequestBody progressRequestBody = new ProgressRequestBody(requestBody, progressListener);            Request request = new Request.Builder()                    .url("http://xxx.xxx.xxx.xx/receive_file.php")                    .post(requestBody)                    .build();            //上面url中的内容请改成自己php文件的所在地址            okHttpClient.newCall(request).enqueue(callback_upload);        }        //点击按钮开始下载文件        public void startDownloadClick() {            targetFile = new File("/data/data/com.example.ywy.mycloud1/cache/"  + "test1.jpg");            Request request = new Request.Builder()                    .url("http://xxx.xxx.xxx.xx/downloads/woman.jpg")                    .build();            okHttpClient.newCall(request).enqueue(callback_download);            //上面url中的内容请改成自己想要下载的文件的所在地址        }        //上传请求后的回调方法        private Callback callback_upload = new Callback() {            @Override            public void onFailure(Call call, IOException e) {                setResult(e.getMessage(), false);            }            @Override            public void onResponse(Call call, Response response) throws IOException {                setResult(response.body().string(), true);            }        };        private  Callback callback_download = new Callback() {            @Override            public void onFailure(Call call, IOException e) {                setResult(e.getMessage(),false);            }            @Override            public void onResponse(Call call, Response response) throws IOException {                if(response != null) {                    //下载完成,保存数据到文件                    //verifyStoragePermissions(MainActivity.this);                    InputStream is = response.body().byteStream();                    FileOutputStream fos = new FileOutputStream(targetFile);                    byte[] buf = new byte[1024];                    int hasRead = 0;                    while((hasRead = is.read(buf)) > 0) {                        fos.write(buf, 0, hasRead);                    }                    fos.close();                    is.close();                    setResult("下载成功", true);                }            }        };        //显示请求返回的结果        private void setResult(final String msg, final boolean success) {            runOnUiThread(new Runnable() {                @Override                public void run() {                    if (success) {                        Toast.makeText(MainActivity.this, "请求成功", Toast.LENGTH_SHORT).show();                    } else {                        Toast.makeText(MainActivity.this, "请求失败", Toast.LENGTH_SHORT).show();                    }                    textView.setText(msg);                }            });        }}

FileUtils.java 用来辅助以获取所选文件的目录

package com.example.ywy.mycloud1;import android.content.Context;import android.database.Cursor;import android.net.Uri;/** * Created by YWY on 2016/11/9. */public class FileUtils {    public static String getPath(Context context, Uri uri) {        if ("content".equalsIgnoreCase(uri.getScheme())) {            String[] projection = { "_data" };            Cursor cursor = null;            try {                cursor = context.getContentResolver().query(uri, projection,null, null, null);                int column_index = cursor.getColumnIndexOrThrow("_data");                if (cursor.moveToFirst()) {                    return cursor.getString(column_index);                }            } catch (Exception e) {                // Eat it            }        }        else if ("file".equalsIgnoreCase(uri.getScheme())) {            return uri.getPath();        }        return null;    }}

DisplayActivity.java 展示下载内容的一个Activity,没什么用

package com.example.ywy.mycloud1;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.ImageView;public class DisplayActivity extends AppCompatActivity {    private  ImageView imageView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_display);        imageView = (ImageView)findViewById(R.id.iv);        Bitmap bitmap = BitmapFactory.decodeFile("/data/data/com.example.ywy.mycloud1/cache/test1.jpg");        imageView.setImageBitmap(bitmap);    }}

还有两个布局文件就不贴了,很简单,自己写一下就行,无非是一些Button和TextView。

另外,不要忘了在AndroidManifest文件中添加读写存储以及联网的权限

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS" />
<uses-permission android:name="androd.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

总结

至此,我们完成了安卓客户端的基本操作,服务器端的PHP代码将在下一篇文章给出,具体功能则是响应客户端的上传请求,接受文件并保存在相关目录下。

顺便附上客户端源代码:
https://github.com/SwallowYWY/MyCloud1

0 0
原创粉丝点击