使用HttpClient发布JSONObject时出错

时间:2014-07-22 23:41:48

标签: java android httpclient jsonobject

我得到的错误是“StrictMode $ AndroidBlockGuardPolicy.onNetwork”使用

我在这里尝试做的是使用jsonobject将所有这些数据发布到服务器。我真的不知道该怎么做,因为我正在使用一个活动和这个类来管理所有的http请求。

这是我的代码:

import android.util.Log;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;
import java.io.IOException;  

public class HttpRequestManager {

String TAG = "Request Manager";

public String RegisterUser (String deviceId, String userNames, String userSurnames, String password,
                            String retypedPassword, String userIds,
                            String userCellphone, String userEmail) {



    //Log.i(TAG, deviceId);

    JSONObject registerFormObject = new JSONObject();

    HttpClient httpClient = new DefaultHttpClient();
    HttpPost httpPost = new HttpPost("http://192.168.1.110:8000/api/v1/registration");

    try {

        try {

            registerFormObject.put("device_id", deviceId);
            registerFormObject.put("device_type", "a");
            registerFormObject.put("names", userNames);
            registerFormObject.put("surnames", userSurnames);
            registerFormObject.put("cell", userCellphone);
            registerFormObject.put("email", userEmail);
            registerFormObject.put("password1", password);
            registerFormObject.put("password2", retypedPassword);
            registerFormObject.put("identification", userIds);

        }catch (Exception e){

        }

        httpPost.setEntity(new StringEntity(registerFormObject.toString()));
        //httpPost.setHeader("Accept", "application/json");
        httpPost.setHeader("Content-type", "application/json");

        HttpResponse response = httpClient.execute(httpPost);

        Log.i(TAG, response.toString());

    } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
        Log.i(TAG, e.toString());
    } catch (IOException e) {
        // TODO Auto-generated catch block
        Log.i(TAG, e.toString());
    }


    return userSurnames;
} 


}

有关如何解决此错误的任何想法?

uses-permission android:name =“android.permission.INTERNET”btw。

2 个答案:

答案 0 :(得分:1)

@Machinarius所说的是正确的。您无法在主线程上执行网络活动。但是,为了回答你的问题,我有适合你的解决方案。

你可以创建一个新的类......你可以随意调用它(为了这个例子的目的,我们假设它将是 RegUser )并且在那个类里面......把这个代码放进去。当然,更改参数寄存器功能将为您带来。

public void Register(
                          // Parameters it takes IN
                            String deviceId, 
                            String userNames, 
                            String userSurnames, 
                            String password,
                            String retypedPassword, 
                            String userIds,
                            String userCellphone, 
                            String userEmail
                          )
        {
        //Start of the Code in Function

        //Create a JSON variable of type JSON
        JSONObject JSON = new JSONObject();


        //Get UnixTimeStamp (Used to get UniquePushMessageID)
        long unixTime = System.currentTimeMillis() / 1000L;

        //Wrap all contacts and variabels to a single JSON object


    try {
                JSON.put("deviceId", deviceId);
                JSON.put("userNames", userNames);
                JSON.put("userSurnames", userSurnames);
                JSON.put("password", password);
...please add more yourself.
                JSON.put("contact", JSONcontacts); // Put JSON into JSON to create Array of Contacts
                JSON.put("channel", channel);
                JSON.put("unique", channel + String.valueOf(unixTime) ); //Create Unique MessageID (RSU-MAC+TimeInSec)
                JSON.put("icon", icon);

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

            }

            Log.v("MAD", "About to send" + JSON.toString());

            //Send this JSON object to a server
            SendToServer(JSON.toString());
}

现在,在同一个类中,请创建一个名为 SendToServer 的方法。如您所见,它使用异步任务:)

@SuppressWarnings({ "unchecked", "rawtypes" })
    public void SendToServer(final String JSON) {
        new AsyncTask() {

            @SuppressWarnings("unused")
            protected void onPostExecute(String msg) {
                //Not Needed
            }

            protected Object doInBackground(Object... params) {
                //Create Array of Post Variabels
                ArrayList<NameValuePair> postVars = new ArrayList<NameValuePair>();

                //Add a 1st Post Value called JSON with String value of JSON inside
                //This is first and last post value sent because server side will decode the JSON and get other vars from it.
                postVars.add(new BasicNameValuePair("JSON", String.valueOf(JSON)));

                //Declare and Initialize Http Clients and Http Posts
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost(YOUR_URL);

                //Format it to be sent
                try {
                    httppost.setEntity(new UrlEncodedFormEntity(postVars));

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

                /* Send request and Get the Response Back */
                try {
                    HttpResponse response = httpclient.execute(httppost);
                    String responseBody = EntityUtils.toString(response.getEntity());
                    //Log.v("MAD", "RESPONSE: " + responseBody + " | Length: " + String.valueOf(responseBody.length()));

                } catch (ClientProtocolException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }


                return null;
            }
        }.execute(null, null, null);

    }// END of Send to Server

就是这样。现在,在您的MainActivity中,您只需要声明RegUser:

RegUser registerUser = new RegUser();

在您输入数据的所有TextField之后......只需一个简单的调用:

registerUser.Register(username, password.. etc);

我希望这能解决你的问题,对我有用。

答案 1 :(得分:0)

Android应用程序中,您应该避免在用户界面thread上执行长时间运行的操作。这包括文件和网络访问。

StrictMode允许在您的应用程序中设置策略,以避免做错误的事情。截至Android 3.0 (Honeycomb) StrictMode 配置为在NetworkOnMainThreadException异常时崩溃,如果在用户界面线程中访问了网络。

虽然您应该在后台线程中进行网络访问,但本教程将避免这种情况,以允许用户独立于后台处理学习网络访问。

如果您定位Android 3.0或更高,则可以在活动的onCreate()方法开头通过以下代码关闭此检查。

在此处查看更多内容:http://www.vogella.com/tutorials/AndroidNetworking/article.html

AsyncTask此处http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html

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

        @Override
        protected String doInBackground(Void... params) {
                // TODO Auto-generated method stub

                HttpRequestManager mHttpRequestManager new HttpRequestManager();
                String returnValue = mHttpRequestManager.RegisterUser()

                return returnValue;
        }

        @Override
        protected void onPostExecute(String result) {
                // TODO Auto-generated method stub
                super.onPostExecute(result);

                //your result here

        }
}