我对PHP、JavaScript和许多其他脚本语言很有经验,但我对Java或Android没有太多经验。

我正在寻找一种方法将POST数据发送到PHP脚本并显示结果。


当前回答

下面的方法适用于最新的Android库和使用okhttp。

    OkHttpClient client = new OkHttpClient();
    RequestBody formBody = new FormBody.Builder()
            .add("key1", "value1")
            .add("key2", "value2")  //optional
            .add("key3", "value3")  //optional
            .add("key4", "value4")  //optional
            .build();


    Request request = new Request.Builder()
    .url("http://.....")   //URL
    .post(formBody)
    .build();


    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(@NonNull Call call, @NonNull IOException e) {
            e.getStackTrace();
        }

        @Override
       public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
            if(response.isSuccessful()){
                ResponseBody responseBody = response.body();
                Log.e("TAG_", responseBody.string());
       }
    }

其他回答

在新版本的Android中,你必须把所有的web I/O请求放到一个新的线程中。AsyncTask最适合小请求。

下面是一个完整的解决方案,它运行在后台线程中,向Web API发送一个HTTPS POST多部分请求。实际测试和工作代码。注意:“\n”字符需要在顶部的“最终字符串”中进行正确的请求格式化。

我有困难要么理解,转换,或完成以上解决方案,我的多部分POST需求。

    @Override
    protected Integer doInBackground(String... files) {

        final String MULTIPART_BOUNDARY = "xxYYzzSEPARATORzzYYxx";
        final String MULTIPART_SEPARATOR = "--" + MULTIPART_BOUNDARY + "\n";
        final String MULTIPART_FORM_DATA = "Content-Disposition: form-data; name=\"%s\"\n\n";
        final String FORM_DATA_FILE1 = "file1";
        final String FORM_DATA_FILE2 = "file2";

        OutputStream outputStream;
        Integer responseCode = 0;
        try {
            URL url = new URL("https://www.example.com/api/endpoint?n1=v1&n2=v2");
            HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
            urlConnection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + MULTIPART_BOUNDARY);
            urlConnection.setConnectTimeout(6000);
            urlConnection.setRequestMethod("POST");
            urlConnection.setDoOutput(true);
            outputStream = new BufferedOutputStream(urlConnection.getOutputStream());
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
            writer.write(MULTIPART_SEPARATOR);
            writer.write(String.format(MULTIPART_FORM_DATA, FORM_DATA_FILE1));
            writer.write(files[0]);
            writer.write(MULTIPART_SEPARATOR);
            writer.write(String.format(MULTIPART_FORM_DATA, FORM_DATA_FILE2));
            writer.write(files[1]);
            writer.write(MULTIPART_SEPARATOR);
            writer.flush();
            writer.close();
            outputStream.close();
            urlConnection.connect();
            responseCode = urlConnection.getResponseCode();
            Log.d("ResponseCode:", String.valueOf(responseCode));
            urlConnection.disconnect();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return responseCode;
    }

下面的方法适用于最新的Android库和使用okhttp。

    OkHttpClient client = new OkHttpClient();
    RequestBody formBody = new FormBody.Builder()
            .add("key1", "value1")
            .add("key2", "value2")  //optional
            .add("key3", "value3")  //optional
            .add("key4", "value4")  //optional
            .build();


    Request request = new Request.Builder()
    .url("http://.....")   //URL
    .post(formBody)
    .build();


    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(@NonNull Call call, @NonNull IOException e) {
            e.getStackTrace();
        }

        @Override
       public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
            if(response.isSuccessful()){
                ResponseBody responseBody = response.body();
                Log.e("TAG_", responseBody.string());
       }
    }

注(2020年10月):以下答案中使用的AsyncTask已在Android API级别30中弃用。有关更新的示例,请参考官方文档或本博客文章

更新(2017年6月)答案,适用于Android 6.0+。感谢@Rohit Suthar, @Tamis Bolvari和@sudhiskr的评论。

    public class CallAPI extends AsyncTask<String, String, String> {
    
        public CallAPI(){
            //set context variables if required
        }
    
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }
    
         @Override
         protected String doInBackground(String... params) {
            String urlString = params[0]; // URL to call
            String data = params[1]; //data to post
            OutputStream out = null;

            try {
                URL url = new URL(urlString);
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                out = new BufferedOutputStream(urlConnection.getOutputStream());

                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
                writer.write(data);
                writer.flush();
                writer.close();
                out.close();

                urlConnection.connect();
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
    }

引用:

https://developer.android.com/reference/java/net/HttpURLConnection.html 如何使用NameValuePair使用POST添加参数到HttpURLConnection

原答案(2010年5月)

注意:此解决方案已过时。它只能在5.1版本以下的安卓设备上运行。Android 6.0及以上版本不包括本回答中使用的Apache http客户端。

来自Apache Commons的Http Client是可行的。它已经包含在android中。下面是一个简单的例子,说明如何使用它来执行HTTP Post。

public void postData() {
    // Create a new HttpClient and Post Header
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost("http://www.yoursite.com/script.php");

    try {
        // Add your data
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
        nameValuePairs.add(new BasicNameValuePair("id", "12345"));
        nameValuePairs.add(new BasicNameValuePair("stringdata", "Hi"));
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

        // Execute HTTP Post Request
        HttpResponse response = httpclient.execute(httppost);
        
    } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
    } catch (IOException e) {
        // TODO Auto-generated catch block
    }
} 

如果你只是想把数据附加到Url,你可以通过使用httppurlconnection来实现,因为HttpClient现在已经弃用了。 更好的方法是使用像-这样的库

凌空抽射 改造

我们可以将数据发送到php脚本,并通过使用AsyncTask类执行的代码来获取结果并显示它。

    private class LongOperation  extends AsyncTask<String, Void, Void> {

    // Required initialization


    private String Content;
    private String Error = null;
    private ProgressDialog Dialog = new ProgressDialog(Login.this);
    String data ="";
    int sizeData = 0;



    protected void onPreExecute() {
        // NOTE: You can call UI Element here.

        //Start Progress Dialog (Message)

        Dialog.setMessage("Please wait..");
        Dialog.show();
        Dialog.setCancelable(false);
        Dialog.setCanceledOnTouchOutside(false);

        try{
            // Set Request parameter
            data +="&" + URLEncoder.encode("username", "UTF-8") + "="+edittext.getText();



        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    // Call after onPreExecute method
    protected Void doInBackground(String... urls) {

        /************ Make Post Call To Web Server ***********/
        BufferedReader reader=null;

        // Send data
        try
        {

            // Defined URL  where to send data
            URL url = new URL(urls[0]);

            // Send POST data request

            URLConnection conn = url.openConnection();

            conn.setConnectTimeout(5000);//define connection timeout 
            conn.setReadTimeout(5000);//define read timeout
            conn.setDoOutput(true);
            OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
            wr.write( data );
            wr.flush();

            // Get the server response

            reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuilder sb = new StringBuilder();
            String line = null;



            // Read Server Response
            while((line = reader.readLine()) != null)
            {
                // Append server response in string
                sb.append(line + " ");
            }

            // Append Server Response To Content String
            Content = sb.toString();


        }
        catch(Exception ex)
        {
            Error = ex.getMessage();
        }
        finally
        {
            try
            {

                reader.close();
            }

            catch(Exception ex) {}
        }


        return null;
    }

    protected void onPostExecute(Void unused) {
        // NOTE: You can call UI Element here.

        // Close progress dialog
        Dialog.dismiss();

        if (Error != null) {

                Toast.makeText(getApplicationContext(),"Error encountered",Toast.LENGTH_LONG).show();



        }
        else {




            try {

                JSONObject jsonRootObject = new JSONObject(Content);


                JSONObject json2 =jsonRootObject.getJSONObject("jsonkey");//pass jsonkey here


                String id =json2.optString("id").toString();//parse json to string through parameters


     //the result is stored in string id. you can display it now


            } catch (JSONException e) {e.printStackTrace();}


        }

    }

}

但是使用诸如volley或retrofit之类的库是更好的选择,因为Asynctask类和HttpurlConnection相比库更慢。此外,库将获取所有内容,也更快。