Android客户端+PHP服务器文件传输

原创 2018年04月15日 15:39:44

做了快两年的Android开发,第一次写帖子,以前一直是用Android+JavaWeb实现客户端服务器,最近接触PHP,发现PHP相对JavaWeb更简单方便,虽然听说php性能没有Java做后端好,不过对于小demo来说已经完全足够了。

PHP和apache的安装和配置就不讲了,网上很多教程。

Android客户端我使用的是OKHttp框架,根据官网和网上的demo,自己包装了一下

package util;

import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;


public class OKHttpUtil {


    /**
     * get方法访问,获取返回String
     * @param url url地址
     * @return
     * @throws IOException
     */
    public static String getString(String url) throws IOException {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .build();
        Response response = null;
        response = client.newCall(request).execute();//得到Response 对象
        if (response.isSuccessful()) {
            return response.body().string();
        }
        return null;
    }

    /**
     *post请求传递map键值对参数,获取返回的字符串
     * @param url url地址
     * @param params map集合,里面放需要上传的参数
     * @return
     * @throws IOException
     */
    public static String postMap(String url, Map<String,String>params) throws IOException {
        OkHttpClient client = new OkHttpClient();//创建OkHttpClient对象。
        FormBody.Builder formBody = new FormBody.Builder();//创建表单请求体
        for(String key:params.keySet()){
            formBody.add(key, params.get(key));//传递键值对参数
        }
        Request request = new Request.Builder()//创建Request 对象。
                .url(url)
                .post(formBody.build())//传递请求体
                .build();
        Response response = null;
        response = client.newCall(request).execute();//得到Response 对象
        if (response.isSuccessful()) {
            return response.body().string();
        }
        return null;
    }

    /**
     * post请求传递json数据,获取返回的字符串
     * @param url url地址
     * @param jsonString 上传的json字符串
     * @return
     * @throws IOException
     */
    public static String postJson(String url,String jsonString) throws IOException {
        OkHttpClient client = new OkHttpClient();//创建OkHttpClient对象。
        MediaType JSON = MediaType.parse("application/json; charset=utf-8");//数据类型为json格式,
        RequestBody body = RequestBody.create(JSON, jsonString);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        Response response = null;
        response = client.newCall(request).execute();//得到Response 对象
        if (response.isSuccessful()) {
            return response.body().string();
        }
        return null;
    }

    /**
     * post请求传递文件和参数,获取返回的字符串
     * @param url url地址
     * @param file 要上传的文件
     * @param params Map集合,里面放需要上传的参数
     * @return
     * @throws IOException
     */
    public static String postFile(String url,File file,Map<String,String>params) throws IOException {
        if(file==null)return null;

        OkHttpClient client = new OkHttpClient();

        MultipartBody.Builder  builder=new MultipartBody.Builder();
        builder.setType(MultipartBody.FORM);
        if(params!=null){
            for(String key:params.keySet()){
                builder.addFormDataPart(key,params.get(key));//传递键值对参数
            }
        }
        builder.addFormDataPart("lhf",file.getName(),RequestBody.create(MediaType.parse("File/*"), file));//第一个参数是文件传输的name属性,与服务器对应即可
        RequestBody multipartBody=builder.build();
        Log.d("lhf","文件名:"+file.getName());
         Request request = new Request.Builder()
                .url(url)
                .post(multipartBody)
                .build();

        Response response = null;
        response = client.newCall(request).execute();//得到Response 对象
        if (response.isSuccessful()) {
            String result=response.body().string();
            return result;
        }
        return null;
    }

    /**
     *根据url直接下载文件
     * @param url url地址
     * @param path 存储路径
     * @param fileName 文件名
     * @return
     * @throws IOException
     */
    public static File downloadFile(String url,String path,String fileName) throws IOException {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .build();
        Response response = null;
        response = client.newCall(request).execute();//得到Response 对象
        if (response.isSuccessful()) {
            InputStream is = response.body().byteStream();//从服务器得到输入流对象
            long sum = 0;
            File dir = new File(path);
            if (!dir.exists()){
                dir.mkdirs();
            }
            File file = new File(dir, fileName);//根据目录和文件名得到file对象
            FileOutputStream fos = new FileOutputStream(file);
            byte[] buf = new byte[1024];
            int len = 0;
            while ((len = is.read(buf)) != -1){
                fos.write(buf, 0, len);
            }
            fos.flush();
            Log.d("lhf","下载成功");
            return file;
        }

        return null;
    }
    
    /**
     * 提交 Map集合参数,通过response的输入流获取文件
     * @param url url地址
     * @param params map集合参数
     * @param path 文件存储路径
     * @param fileName 文件名
     * @return
     * @throws IOException
     */
    public static File downloadFile(String url, Map<String,String>params,String path,String fileName) throws IOException {
        OkHttpClient client = new OkHttpClient();//创建OkHttpClient对象。
        FormBody.Builder formBody = new FormBody.Builder();//创建表单请求体
        for(String key:params.keySet()){
            formBody.add(key, params.get(key));//传递键值对参数
        }
        Request request = new Request.Builder()//创建Request 对象。
                .url(url)
                .post(formBody.build())//传递请求体
                .build();
        Response response = null;
        response = client.newCall(request).execute();//得到Response 对象
        if (response.isSuccessful()) {
            InputStream is = response.body().byteStream();//从服务器得到输入流对象
            long sum = 0;
            File dir = new File(path);
            if (!dir.exists()){
                dir.mkdirs();
            }
            File file = new File(dir, fileName);//根据目录和文件名得到file对象
            FileOutputStream fos = new FileOutputStream(file);
            byte[] buf = new byte[1024];
            int len = 0;
            while ((len = is.read(buf)) != -1){
                fos.write(buf, 0, len);
            }
            fos.flush();
            Log.d("lhf","下载成功");
            return file;
        }
        return null;
    }

}

在执行文件上传和下载的Activity里调用方法,要注意在AndroidManifest.xml里添加网络和访问存储的权限。

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

如果要兼容Android6.0及以上的机型,注意要在Acticity里添加动态权限申请,可以自行查资料,这里不再赘述,以后有时间单独写一篇动态权限的帖子。

Android网络操作要在子线程里完成,我这里直接用的匿名线程。

上传文件

final String path="";//这里填本地文件路径(包括文件名和文件后缀 ),如:"/storage/emulated/0/myfile/test.txt"

final File mFile=new File(path);//根据路径拿到文件对象

//这里可以加一个文件判空,防止程序崩溃,编辑写缩进太麻烦,我就不加了

new Thread(){
      @Override
      public void run() {
          super.run();
          try {
              Map<String ,String>params=new HashMap<>();
            //params.put("name","lhf");//可以根据需要添加多个参数,如上传文件的用户 
              OKHttpUtil.postFile("http://192.168.0.114/TestAndroid/index.php/test/upload",mFile,params);//第一个参数是我本地服务器的url地址,根据自己的项目进行修改
          } catch (IOException e) {
              Log.d("lhf","上传失败失败");
              e.printStackTrace();
          }
     }
}.start();
 

根据url直接下载文件,简单但不安全,不建议使用

new Thread(){
    @Override
    public void run() {
        super.run();
        try {
            OKHttpUtil.downloadFile("http://192.168.0.114/TestAndroid/upload/我的文档.txt","/storage/emulated/0/myfile","我的文件.txt");//第一个参数是我服务器的文件下载url,根据自己的项目进行修改
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}.start();
上传参数到服务器下载文件
new Thread(){
    @Override
    public void run() {
        super.run();
        try {
            Map<String ,String>params=new HashMap<>();
            //params.put("name","lhf");//可以根据需要添加多个参数,如用户名 
OKHttpUtil.downloadFile("
http://192.168.0.114/TestAndroid/index.php/test/download",params,"/storage/emulated/0/myfile","我的文件.txt");//第一个参数是我服务器的文件下载url,根据自己的项目进行修改
} catch (IOException e) { e.printStackTrace(); } }}.start();

接下来是PHP服务器端,我使用的是PHP的CI框架 ,如果使用其他方式请自行百度查找PHP文件上传下载方式,非常简单

upload方法,将接收的文件存到项目相对路径的upload文件夹中

public function upload()
    {
    // 上传文件到服务器目录
    $config['upload_path'] = './upload';
    // 允许上传哪些类型文件
    $config['allowed_types'] = 'txt|gif|jpg|png';
    $config['max_size']="200000";
    // 上传后的文件名,用uniqid()保证文件名唯一
    $config['file_name'] = uniqid();
//     $name = $_POST["name"];//接收其它参数
    // 加载上传库
    $this->load->library('upload', $config);
    // 上传文件,这里的lhf是file的name属性,与客户端对应
  //windows的文件默认为gbk编码,这里需要转码
$filename=iconv("UTF-8","gbk", $_FILES["lhf"]["name"]);
move_uploaded_file($_FILES["lhf"]["tmp_name"],"./upload/" . $filename);

    }

通过url直接从服务器下载文件不需要特地写下载方法,只需要在服务器相对路径中有该文件即可直接下载,但是这种方法不安全,不建议使用,下面介绍根据上传参数下载文件的方法

download方法将本地文件通过输出流发送到客服端

//文件下载方法
    public function download() {
    $this->load->helper('url');

    $this->load->helper('download');

//      $name = $_POST["name"];//可以接收其它参数

    //windows的文件默认为gbk编码,这里需要转码
    $filename=iconv("gbk","utf-8","D:/你好.txt");
    $myfile=fopen($filename, "r");
    force_download($filename,NULL);
    fclose($myfile);

    }



JavaAndroid客户端和C#服务端Web Api接口开发

C#服务端HttpGet接口开发 C#服务端HttpPost接口开发 JavaAndroid客户端请求C#服务端HttpGet接口开发 JavaAndroid客户端Android请求C#服务端HttpPost接口开发
  • 2017年01月08日 20:05

自我感觉完美的“Android客户端+PHP服务器端”应用开发框架案例

  • 2017年05月08日 23:08
  • 2.73MB
  • 下载

Android客户端与PHP服务端交互(一)---框架概述

背景 作为一个普通上班族,总是想做一些自认为有意义的事情,于是乎准备成立一个工作室,尽管目前正在筹备阶段,但是之前有些朋友提出一些需求的时候,我发现自己的能力还是有限,直到最近和一些技术牛朋友聊起这事...
  • mybelief321
  • mybelief321
  • 2015-05-01 23:01:26
  • 3608

Android客户端读取PHP服务器的信息

  • 2013年07月15日 11:45
  • 102KB
  • 下载

android(客户端)和PC(服务器端)通信RSA 加密解密

android客户端代码: package com.suning.reminder.util; import java.io.BufferedReader; import java.io.ByteAr...
  • xiaoyezi_1
  • xiaoyezi_1
  • 2013-12-06 11:39:31
  • 2739

android使用PHP上传图片到服务器

PHP端代码
  • csd54496
  • csd54496
  • 2015-07-06 15:45:35
  • 925

android视频传输

  • 2012年04月20日 14:01
  • 172KB
  • 下载

Android客户端和php+mysql+apache搭建的服务器之间的简单交互

android客户端和php+mysql+apache搭建的服务器之间的简单交互,实现登入功能。 实现原理就是android客户端发送请求,传给服务器登入的用户名密码,服务器收到这些,连接到数据库查询...
  • tomato00001
  • tomato00001
  • 2016-08-01 00:12:29
  • 2626

Android客户端与Web服务器端Http通信

首先需要在Web服务器端配置struts2的jar包以及json包所依赖的jar包并导入到web项目中。 下面是Web服务器端的配置代码: 在web.xml文件中配置struts2并交给actio...
  • u010883330
  • u010883330
  • 2016-09-24 23:16:46
  • 450

android向php服务器传送数据

  • 2015年04月23日 16:42
  • 1.23MB
  • 下载
收藏助手
不良信息举报
您举报文章:Android客户端+PHP服务器文件传输
举报原因:
原因补充:

(最多只允许输入30个字)