• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Android实现和PHP后端的交互数据传输,文件传输详细/附源码

武飞扬头像
recycle1
帮助1

为方便大家浏览,源码先行奉上
github源码链接 https://github.com/Recycle1/Android-connect-PHP
csdn源码链接 https://download.csdn.net/download/weixin_52263647/87751491

那熟悉PHP开发的我们都会知道PHP页面的传参方式有Get和Post,利用此原理我们即可实现Android端与PHP端的交互,Android端进行带参访问即进行Get方法传参,对于大规模的数据如文件的传输,利用Post方法,在Android端设置好相应的参数,进行大规模数据的传输。在之后的讲解中,我们将分情况进行演示。

在这篇文章中,我们需要准备的东西有:

  • Android手机,这里我调试使用的是真机,测试所用的安卓版本为Android 10,当前普遍使用的Android 12版本可能会出现不适配的情况,比如文件读取和权限方面,这个只需稍加调试即可解决。
  • 云服务器,这里我租用了阿里云的云服务器,并部署了SSL证书,(当然,如果只是android信息交互也可以不使用SSL证书)

那么接下来,我将分情况介绍如何进行Android与PHP的交互。

一 Android端

权限设置

对于互联网连接方面和文件读取方面,需要给予一定的权限,在manifest中设置

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

文件读取与写入(尤其要看一下哦!!!)

本地文件读取与写入,同时需要在activity中动态给予权限。

//初始化权限
void init_permission(){
	if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
    }
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
    }
}
android:requestLegacyExternalStorage="true"

http网络连接设置(也尤其要看一下哦!!!)

android:usesCleartextTraffic="true"

1. 单条数据传输(Get方法)

单条数据的传输,我们在Android端传入字符串,服务器端也会返回字符串,利用http建立连接。

//主要用于传输单条数据,如字符串等,同时,PHP端也返回单条数据
public static String singleData(String path) throws Exception {
        URL url = new URL(path);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setConnectTimeout(5000);
        conn.setRequestMethod("GET");
        if (conn.getResponseCode() == 200) {
            InputStream inputStream = conn.getInputStream();
            byte[] data = StreamTool.read(inputStream);
            String result = new String(data);
            return result;
        }
        return "failed";
}

下面的代码是上面过程中从流中读取数据的内容。

public static class StreamTool {
        //从流中读取数据
        public static byte[] read(InputStream inStream) throws Exception{
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while((len = inStream.read(buffer)) != -1)
            {
                outStream.write(buffer,0,len);
            }
            inStream.close();
            return outStream.toByteArray();
        }
}

2. 多条多元数据传输(Get方法)

对于多元的数据类型,我们可以采用json数组的方式进行传输,首先定义一个包含我们需要的数据类型的类,这里我设置它包含三种不同的属性,a1,a2,a3。

public class MultipleResult {

    //类中包含多种不同类型的属性
    String a1;
    int a2;
    double a3;

    public MultipleResult(String a1, int a2, double a3) {
        this.a1 = a1;
        this.a2 = a2;
        this.a3 = a3;
    }

}

在获取时,我们沿用单条数据传输的思路,只不过我们需要将获取到的json数组转换为Arraylist进行存储,这里我设置了一个参数n,因为通常情况下,我们都是在Android获取参数作为关键字到云端数据库中进行查询,然后返回查询的结果,比如我们Android端获取学生的学号,在云端数据库中查询并且返回学生的信息。

//用于获取多种复杂类型的数据
public static ArrayList<MultipleResult> multipleData(String n) throws Exception {
        ArrayList<MultipleResult> list=new ArrayList<>();
        String path="http://101.201.109.91/Connect_Android/get_multiple_data.php?n=" n;
        HttpURLConnection conn = (HttpURLConnection) new URL(path).openConnection();
        InputStream json = conn.getInputStream();
        byte[] data = StreamTool.read(json);
        String json_str = new String(data);
        JSONArray jsonArray = new JSONArray(json_str);
        for(int i = 0; i < jsonArray.length() ; i  ){
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            String a1=jsonObject.getString("a1");
            int a2=jsonObject.getInt("a2");
            double a3=jsonObject.getDouble("a3");
            list.add(new MultipleResult(a1,a2,a3));
        }
        return list;
}
学新通

3. 文件传输(Post方法)

这里我直接沿用了另一位博主的文章,链接暂时找不到了,方式是设置Post的相关参数,从本地的存储地址传到云端的存储地址。我们需要在函数中写入的参数有本地的存储路径,服务器端的存储路径,和文件名称(这里的文件名称可以是随机定义的,是在服务器端最终显示的文件名称,可以与本地存储路径名称不同)

public static void uploadFile(String path, String url_path, String name) {
        String end = "\r\n";
        String twoHyphens = "--";
        String boundary = "*****";
        try
        {
            URL url = new URL(url_path);
            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=\""  
                    name "\""   end);
            ds.writeBytes(end);
            /* 取得文件的FileInputStream */
            FileInputStream fStream = new FileInputStream(path);
            /* 设置每次写入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);
            }
            /* 显示网页响应内容 */
            System.out.println(b.toString().trim());
            //Toast.makeText(MainActivity.this, b.toString().trim(), Toast.LENGTH_SHORT).show();//Post成功
        } catch (Exception e)
        {
            /* 显示异常信息 */
            System.out.println("fail" e);
            //Toast.makeText(MainActivity.this, "Fail:"   e, Toast.LENGTH_SHORT).show();//Post失败
        }
}
学新通

在Activity中的进行调用使用

在xml文件中,我们设置了三个按钮,和一个文本,分别进行单条数据传输,多元数据传输,以及文件传输的显示。

在activity中,我们将整个的方法整合为一个WebTool工具类,利用这个工具类调用上述的方法,同时需要注意的是,网络连接不能再主线程中进行,因此需要开辟一个新的线程进行调用,同时,对于前端控件的调用不能在分支线程中进行,因此最后的结果显示部分,我们用到了handler实现分支线程与主线程之间的通信,最终实现结果在TextView中显示。

1. 单条数据传输调用

//在新线程中获取数据,通过handler判断是否获取到数据
//n为向PHP传输的数据
String n="本地测试数据";
result=WebTool.singleData("https://www.recycle11.top/Connect_Android/get_single_data.php?n=" n);

2. 多条多元数据调用

//n为测试数据
result_list=WebTool.multipleData("本地测试数据");

3. 文件传输

WebTool.uploadFile(test_file_path(),"https://www.recycle11.top/Connect_Android/upload.php","test.txt");

本地文件处理

本地文件处理借鉴了另一篇博文,由于没有测试过Android 12版本,因此文件权限方面一定要处理好,否则无法获取,写入文件。
博文链接:本地文件的创建

在本地我们将文件夹创建,文件创建放入一个工具类FileUtil中,进行处理,我们将写入一个文件存入手机内存中,并获得它的路径。

String test_file_path(){
        File fileDir=new File(Environment.getExternalStorageDirectory().getAbsolutePath() "/Connect_web_test");
        String filename="test.txt";

        //创建文件夹及文件
        FileUtil.createFileDir(fileDir);
        FileUtil.createFile(fileDir.getAbsolutePath(),filename);

        //写入文件信息
        FileOutputStream fos = null;
        try {

            fos = new FileOutputStream(fileDir.getAbsolutePath() "/" filename);
            String content="本地测试数据";
            fos.write(content.getBytes());

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try{
                //保证即使出现异常,fos也可以正常关闭
                fos.close();
            } catch (IOException e){
                e.printStackTrace();
            }
        }

        return fileDir.getAbsolutePath() "/" filename;
}
学新通

二 PHP服务器端

在服务器端我们创建了如下的一些文件,设置了三个php文件接收并回传信息,Android_File文件夹存储Android端传入的文件。
学新通
单条数据传输

<?php
    if(is_array($_GET)&&count($_GET)>0){
        if(isset($_GET['n'])){
            $n=$_GET['n'];
        }
    }
    echo "网络数据内容"
?>

多条多元数据传输

<?php
    if(is_array($_GET)&&count($_GET)>0){
        if(isset($_GET['n'])){
            $n=$_GET['n'];
        }
    }
    //根据传过来的数据$n可作为关键字,查询数据库的信息,这里就不演示数据库交互过程了
    $content=array();
    $content[0]=array("a1"=>"网络测试数据1","a2"=>1,"a3"=>1.5);
    $content[1]=array("a1"=>"网络测试数据2","a2"=>2,"a3"=>2.5);
	echo json_encode($content);
?>

文件传输

<?php
	$target_path  = "./Android_File/";//接收文件目录
	$target_path = $target_path . basename( $_FILES['file']['name']);
	if(move_uploaded_file($_FILES['file']['tmp_name'], $target_path)) {
   		echo "The file ".  basename( $_FILES['file']['name']). " has been uploaded";
	}
	else{
   		echo "There was an error uploading the file, please try again!" . $_FILES['file']['error'];
	}
?>

最后我们在手机上进行测试,出现如下效果就说明数据传输成功了。

单条数据传输

学新通

多条多元数据传输

学新通

文件传输

学新通

PS:博主在测试完成后,将服务器端的代码删除了,因此利用本demo是无法访问博主服务器的,也无法直接运行,需要大家连接自己的服务器哦。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhggigke
系列文章
更多 icon
同类精品
更多 icon
继续加载