【问题标题】:Creating a android app that sends POST request to PHP [closed]创建一个向 PHP 发送 POST 请求的 android 应用程序 [关闭]
【发布时间】:2017-04-15 15:15:03
【问题描述】:

我已经尝试了几个选项来将一个发布请求从一个 android 应用程序发送到一个运行 PHP 文件的服务器 我需要发送一个 POST 请求,其中包含以下参数:id = 0 & balance = 666

我的应用程序上有以下代码,当应用程序发送请求时应用程序崩溃

有人可以帮忙吗?

安卓代码:

package com.example.hk300.jsonpost;

import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.InterstitialAd;

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import static android.R.id.message;

public class MainActivity extends AppCompatActivity {
    // Remove the below line after defining your own ad unit ID.
    private static final String TOAST_TEXT = "Test ads are being shown. "
            + "To show live ads, replace the ad unit ID in res/values/strings.xml with your own ad unit ID.";

    private static final int START_LEVEL = 1;
    private int mLevel;
    private Button mNextLevelButton;
    private InterstitialAd mInterstitialAd;
    private TextView mLevelTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Create the next level button, which tries to show an interstitial when clicked.
        mNextLevelButton = ((Button) findViewById(R.id.next_level_button));
        mNextLevelButton.setEnabled(false);
        mNextLevelButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showInterstitial();
            }
        });

        // Create the text view to show the level number.
        mLevelTextView = (TextView) findViewById(R.id.level);
        mLevel = START_LEVEL;

        // Create the InterstitialAd and set the adUnitId (defined in values/strings.xml).
        mInterstitialAd = newInterstitialAd();
        loadInterstitial();

        // Toasts the test ad message on the screen. Remove this after defining your own ad unit ID.
        Toast.makeText(this, TOAST_TEXT, Toast.LENGTH_LONG).show();



    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private InterstitialAd newInterstitialAd() {
        InterstitialAd interstitialAd = new InterstitialAd(this);
        interstitialAd.setAdUnitId(getString(R.string.interstitial_ad_unit_id));
        interstitialAd.setAdListener(new AdListener() {
            @Override
            public void onAdLoaded() {
                mNextLevelButton.setEnabled(true);
            }

            @Override
            public void onAdFailedToLoad(int errorCode) {
                mNextLevelButton.setEnabled(true);
            }

            @Override
            public void onAdClosed() {
                // Proceed to the next level.
                goToNextLevel();
            }
        });
        return interstitialAd;
    }

    private void showInterstitial() {
        // Show the ad if it's ready. Otherwise toast and reload the ad.
        if (mInterstitialAd != null && mInterstitialAd.isLoaded()) {
            mInterstitialAd.show();
        } else {
            Toast.makeText(this, "Ad did not load", Toast.LENGTH_SHORT).show();
            goToNextLevel();
        }
    }

    private void loadInterstitial() {
        // Disable the next level button and load the ad.
        mNextLevelButton.setEnabled(false);
        AdRequest adRequest = new AdRequest.Builder()
                .setRequestAgent("android_studio:ad_template").build();
        mInterstitialAd.loadAd(adRequest);
    }

    private void goToNextLevel() {
        // Show the next level and reload the ad to prepare for the level after.
        mLevelTextView.setText("Level " + (++mLevel));
        mInterstitialAd = newInterstitialAd();
        loadInterstitial();
        new BackgroundTask().execute();

    }

    public class BackgroundTask extends AsyncTask<Void,Void,String> {

        @Override
        protected void onPreExecute(){
//Do UI operation here and onPostExecute
             //TextView textview = (TextView)findViewById(R.id.credits);
             //textview.setText(message);
        }
        @Override
        protected String doInBackground(Void... params) {
            OutputStream os = null;
            InputStream is = null;
            HttpURLConnection conn = null;
            String contentAsString = null;
            try {
                URL url = new URL("https://disjunct-swabs.000webhostapp.com/testapp.php");
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("id", "0");
                jsonObject.put("balance", "666");
                String message = jsonObject.toString();
                //You cannot perform these UI operation on non-UI thread

                conn = (HttpURLConnection) url.openConnection();
                conn.setReadTimeout(10000 /*milliseconds*/);
                conn.setConnectTimeout(15000 /* milliseconds */);
                conn.setRequestMethod("POST");
                conn.setDoInput(true);
                conn.setDoOutput(true);
                conn.setFixedLengthStreamingMode(message.getBytes().length);

                conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
                conn.setRequestProperty("X-Requested-With", "XMLHttpRequest");

                DataOutputStream wr = new DataOutputStream(conn.getOutputStream());

                wr.writeBytes(message);
                Log.e("JSON Input", message);
                wr.flush();
                wr.close();
                conn.connect();
                is = conn.getInputStream();
                contentAsString = is.toString();
            } catch (IOException e) {
                Log.d("shit", "Shit");
            } catch (JSONException e) {
                Log.d("shit", "Shit");
            } finally {

                conn.disconnect();
            }
            //return response to onPostExecute()
            return contentAsString;
        }

        @Override
        protected void onPostExecute(String res){
            //Do anything with response

        }
    }


}

【问题讨论】:

  • 有什么问题?
  • 你能发布错误的细节,比如 logcat 消息吗?
  • logcat 仅显示:新连接 04-16 17:49:32.709 1609-1609/system_process W/IInputConnectionWrapper:reportFullscreenMode on inexistent InputConnection
  • 04-16 17:49:36.447 2405-2894/com.google.android.gms I/FA-SVC:应用测量正在启动,版本:10298 04-16 17:49:36.481 2405-3007/com.google.android.gms I/FA-SVC:此实例被标记为上传者
  • 您应该将您的错误信息放入您的问题中;不要进入 cmets!

标签: java php android json http-post


【解决方案1】:

您确定您没有在主 UI 线程中运行它吗?创建新线程或使用 AsyncTask 执行网络操作。

public class BackgroundTask extends AsyncTask<String, Void, String> {

    protected void onPreExecute(){}

    protected String doInBackground(String... arg0) {

      try {

        URL url = new URL("https://disjunct-swabs.000webhostapp.com/testapp.php"); 

        JSONObject postDataParams = new JSONObject();
        postDataParams.put("id", "0");
        postDataParams.put("balance", "666");
        Log.e("params",postDataParams.toString());

        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(15000 /* milliseconds */);
        conn.setConnectTimeout(15000 /* milliseconds */);
        conn.setRequestMethod("POST");
        conn.setDoInput(true);
        conn.setDoOutput(true);

         OutputStream os = conn.getOutputStream();
            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(os, "UTF-8"));
            writer.write(getPostDataString(postDataParams));

            writer.flush();
            writer.close();
            os.close();

            int responseCode=conn.getResponseCode();

            if (responseCode == HttpsURLConnection.HTTP_OK) {

                BufferedReader in=new BufferedReader(new
                       InputStreamReader(
                              conn.getInputStream()));

                StringBuffer sb = new StringBuffer("");
                String line="";

                while((line = in.readLine()) != null) {

                    sb.append(line);
                    break;
                }

                in.close();
                return sb.toString();

            }
            else {
                return new String("false : "+responseCode);
            }
        }
        catch(Exception e){
            return new String("Exception: " + e.getMessage());
        }

    }

    @Override
    protected void onPostExecute(String result) {
       Toast.makeText(getApplicationContext(), result,
                Toast.LENGTH_LONG).show();
    }
}

public String getPostDataString(JSONObject params) throws Exception {

    StringBuilder result = new StringBuilder();
    boolean first = true;

    Iterator<String> itr = params.keys();

    while(itr.hasNext()){

        String key= itr.next();
        Object value = params.get(key);

        if (first)
            first = false;
        else
            result.append("&");

        result.append(URLEncoder.encode(key, "UTF-8"));
        result.append("=");
        result.append(URLEncoder.encode(value.toString(), "UTF-8"));

    }
    return result.toString();
}

} 在上述线程中,您不能在任何视图上声明、初始化或执行操作(setText),因为它们必须仅在 UI 线程上发生。把它放在 onPreExecute 或 onPostExecute 方法中 现在你可以通过

运行代码
new BackgroundTask().execute();

也在清单中添加权限

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

如果您使用的是 Android M 或更高版本,您还必须在运行时请求许可。这应该是你的 goToNextLevel() 方法

private void goToNextLevel() {
    // Show the next level and reload the ad to prepare for the level after.
    mLevelTextView.setText("Level " + (++mLevel));
    mInterstitialAd = newInterstitialAd();
    loadInterstitial();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
     if (checkSelfPermission(Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) {
        requestPermissions(new String[]{
                Manifest.permission.INTERNET
        }, 10);

     }
    }
    new BackgroundTask().execute();

}

【讨论】:

  • 我试图创建一个新的胎面并在应用程序 oncreate 上调用它,它可以阻止应用程序崩溃,但仍然不会将数据发送到 PHP。如果它有助于我尝试存档的内容是向用户显示一个 admob 添加然后发送到数据库(使用 PHP 文件来处理查询)一些信息(上面的那个)所以基本上我使用的是标准模板对于来自 android studio 的 admob 并实现上面的代码来发送 php 帖子。然后我将代码称为“trycon”;在模板附带的“private void goToNextLevel()”中。
  • 我已经用你的异步任务替换了我的代码但仍然无法正常工作,我什至删除了文本视图部分,也许它现在没有正确形成的发布请求,有什么办法我看到正在发送的帖子请求?我也尝试在一个新的 java 类中运行代码,并在主要活动 java
  • 检查编辑的答案
  • 仍然不起作用我一定是做错了什么,我刚刚发布了上面的完整代码,请查看是否有任何问题。我还更改了“String contentAsString = readIt(is,len);”到“ contentAsString = is.toString();”它给了我一个错误,无法识别 len。 (代码在mainactivity java上)
  • 我已经给出了完整的代码,检查新的编辑答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-11
  • 1970-01-01
  • 1970-01-01
  • 2019-12-18
  • 1970-01-01
  • 2017-12-25
相关资源
最近更新 更多