我们一直在尝试向Android应用中的node.js服务器发送POST请求。因为旧的apache依赖项已被弃用(我似乎无法访问它们 - 我已经尝试过了)我们一直在使用HttpURLConnection类。我们在java中编写了一个类,它只是一个独立的类(Request.java),但是当它在android程序中被编译时,它每次都会抛出一个错误,当它试图获取错误消息时,它只返回null。
Request.java
package andrewmmattb.beacongame;
/**
* Created by matt on 05/03/2016.
*/
import java.net.HttpURLConnection;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.URL;
public class Request {
public static void main(String[] args) throws Exception {
Request http = new Request();
System.out.println("POST");
http.sendPost("{\"username\": \"matt\",\"newPoints\":5}");
}
public static void sendPost(String json) throws Exception {
String url = "http://ec2-54-187-69-193.us-west-2.compute.amazonaws.com/points";
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
//add reuqest header
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "");
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
con.setRequestProperty("Content-Type", "application/json");
String urlParameters = "";
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(json);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + urlParameters);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
//print result
System.out.println(response.toString());
}
}
GameActivity.java
package andrewmmattb.beacongame;
import android.app.Activity;
import android.app.DownloadManager;
import android.content.Intent;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.util.Base64;
import android.util.JsonWriter;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
import org.json.*;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class GameActivity extends Activity {
String username;
String serverPath = "THE PATH TO THE SERVER";
int score = 0;
int prevScore = 0;
TextView usernameTextView;
TextView scoreTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
usernameTextView = (TextView)findViewById(R.id.textViewGameUsername);
scoreTextView = (TextView)findViewById(R.id.textViewGameScore);
Intent intent = getIntent();
username = intent.getStringExtra("username");
usernameTextView.setText(username);
try {
makeSeverPost();
}
catch (IOException e) {
Toast.makeText(GameActivity.this,"There was an IO error, called after function call (line 56)",Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
void makeSeverPost() throws IOException {
// creates a map object with username and the additional points to the previous sent score
Map<String,Object> values = new HashMap<String,Object>();
values.put("username",username);
values.put("newPoints",score-prevScore);
// sets the previous score to equal the current score
prevScore = score;
// writes the map into a string in JSON format
String jsonString = new JSONObject(values).toString();
try {
Request.sendPost(jsonString);
} catch (Exception e) {
e.printStackTrace();
Log.e("problem",""+e.getMessage());
}
}
}
由于我们所做的所有其他尝试都有许多冗余的依赖性。
答案 0 :(得分:4)
在主线程的android网络中是不允许的。
您必须从AsyncTask
。
示例:
class MakeSeverPostTask extends AsyncTask<Void, String, JSONObject>
{
Map<String,Object> params;
public MakeSeverPostTask(Map<String,Object> params){
this.params = params;
}
protected JSONObject doInBackground(Void... v)
{
String jsonString = new JSONObject(this.params).toString();
return Request.sendPost(jsonString);
}
protected void onPostExecute(JSONObject result)
{
}
}
用法:
Map<String,Object> values = new HashMap<String,Object>();
values.put("username",username);
values.put("newPoints",score-prevScore);
new MakeSeverPostTask(values).execute();
答案 1 :(得分:0)
这是更详细的解决方案:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
usernameTextView = (TextView)findViewById(R.id.textViewGameUsername);
scoreTextView = (TextView)findViewById(R.id.textViewGameScore);
// creates a map object with username and the additional points to the previous sent score
Map<String,Object> values = new HashMap<String,Object>();
values.put("username",username);
values.put("newPoints",score-prevScore);
// writes the map into a string in JSON format
String jsonString = new JSONObject(values).toString();
String url = "http://ec2-54-187-69-193.us-west-2.compute.amazonaws.com/points";
// executing AsyncTask with passing string parameters.
ServerAsyncTask makeServerPost = new ServerAsyncTask();
makeServerPost.execute(url, jsonString);
}
private class ServerAsyncTask extends AsyncTask<String, Void, JSONObject> {
private final String TAG = ServerAsyncTask.class.getSimpleName();
@Override
protected JSONObject doInBackground(String... params) {
JSONObject result = null;
try {
URL obj = new URL(params[0]); // added url
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
//add reuqest header
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "");
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
con.setRequestProperty("Content-Type", "application/json");
String urlParameters = "";
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(params[1]); // Added json
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
Log.i(TAG, "\nSending 'POST' request to URL : " + params[0]);
Log.i(TAG, "Post parameters : " + urlParameters);
Log.i(TAG, "Response Code : " + responseCode);
// safer way to parse response
if(responseCode == HttpURLConnection.HTTP_OK){
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// print result
Log.i(TAG, response.toString());
result = new JSONObject(response.toString());
}
} catch (IOException | JSONException e) {
e.printStackTrace();
}
return result;
}
@Override
protected void onPostExecute(JSONObject jsonObject) {
super.onPostExecute(jsonObject);
/* You get response jsonObject here,
you can now update your UI here*/
// Example update your score.
try {
String score = (String) jsonObject.get("score");
scoreTextView.setText(score);
} catch (JSONException e) {
e.printStackTrace();
}
}
}