Anqi Zhang
Anqi Zhang

Reputation: 27

send data to server under fragment tab

I'm really new in programming. I'm doing an app with tabs and each tab is a fragment, and within one of this tab, i want to send some data to the server. Here's the code, looks like all the get() something function is not working under fragment. (I've solved this problem) Now the program couldn't run.

Here's my code

public class TabActivityMain extends Fragment implements OnClickListener {

TextView tvIsConnected;
EditText etName,etCountry,etTwitter;
Button btnPost;
Person person;

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View V = inflater.inflate(R.layout.activity_tab_activity_main, container, false);


        tvIsConnected = (TextView) V.findViewById(R.id.tvIsConnected);
        etName = (EditText) V.findViewById(R.id.etName);
        etCountry = (EditText) V.findViewById(R.id.etCountry);
        etTwitter = (EditText) V.findViewById(R.id.etTwitter);
        btnPost = (Button) V.findViewById(R.id.btnPost);

        // check if you are connected or not
        if(isConnected()){
            tvIsConnected.setBackgroundColor(0xFF00CC00);
            tvIsConnected.setText("You are conncted");
        }
        else{
            tvIsConnected.setText("You are NOT conncted");
        }

        // add click listener to Button "POST"
        btnPost.setOnClickListener(this);
        return V;
    }
public static String POST(String url, Person person){
    InputStream inputStream = null;
    String result = "";
    try {

        // 1. create HttpClient
        HttpClient httpclient = new DefaultHttpClient();

        // 2. make POST request to the given URL
        HttpPost httpPost = new HttpPost(url);

        String json = "";

        // 3. build jsonObject
        JSONObject jsonObject = new JSONObject();
        jsonObject.accumulate("name", person.getName());
        jsonObject.accumulate("country", person.getCountry());
        jsonObject.accumulate("twitter", person.getTwitter());

        // 4. convert JSONObject to JSON to String
        json = jsonObject.toString();

        // ** Alternative way to convert Person object to JSON string usin Jackson Lib 
        // ObjectMapper mapper = new ObjectMapper();
        // json = mapper.writeValueAsString(person); 

        // 5. set json to StringEntity
        StringEntity se = new StringEntity(json);

        // 6. set httpPost Entity
        httpPost.setEntity(se);

        // 7. Set some headers to inform server about the type of the content   
        httpPost.setHeader("Accept", "application/json");
        httpPost.setHeader("Content-type", "application/json");

        // 8. Execute POST request to the given URL
        HttpResponse httpResponse = httpclient.execute(httpPost);

        // 9. receive response as inputStream
        inputStream = httpResponse.getEntity().getContent();

        // 10. convert inputstream to string
        if(inputStream != null)
            result = convertInputStreamToString(inputStream);
        else
            result = "Did not work!";

    } catch (Exception e) {
        Log.d("InputStream", e.getLocalizedMessage());
    }

    // 11. return result
    return result;
}

public boolean isConnected(){
    ConnectivityManager connMgr = (ConnectivityManager) getActivity().getSystemService(Activity.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isConnected()) 
            return true;
        else
            return false;    
}
@Override
public void onClick(View view) {

    switch(view.getId()){
        case R.id.btnPost:
            if(!validate())
                Toast.makeText(getActivity().getBaseContext(), "Enter some data!", Toast.LENGTH_LONG).show();
            // call AsynTask to perform network operation on separate thread
            new HttpAsyncTask().execute("http://hmkcode.appspot.com/jsonservlet");
        break;
    }

}
private class HttpAsyncTask extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {

        person = new Person();
        person.setName(etName.getText().toString());
        person.setCountry(etCountry.getText().toString());
        person.setTwitter(etTwitter.getText().toString());

        return POST(urls[0],person);
    }
    // onPostExecute displays the results of the AsyncTask.
    @Override
    protected void onPostExecute(String result) {
        Toast.makeText(getActivity().getBaseContext(), "Data Sent!", Toast.LENGTH_LONG).show();
   }
}

private boolean validate(){
    if(etName.getText().toString().trim().equals(""))
        return false;
    else if(etCountry.getText().toString().trim().equals(""))
        return false;
    else if(etTwitter.getText().toString().trim().equals(""))
        return false;
    else
        return true;    
}
private static String convertInputStreamToString(InputStream inputStream) throws IOException{
    BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream));
    String line = "";
    String result = "";
    while((line = bufferedReader.readLine()) != null)
        result += line;

    inputStream.close();
    return result;

} 

}

and the log cat info is

09-09 09:30:59.907: E/AndroidRuntime(1311): FATAL EXCEPTION: main
09-09 09:30:59.907: E/AndroidRuntime(1311): Process: com.zanqi.mainpage1, PID: 1311
09-09 09:30:59.907: E/AndroidRuntime(1311): java.lang.SecurityException: ConnectivityService: Neither user 10063 nor current process has android.permission.ACCESS_NETWORK_STATE.
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.os.Parcel.readException(Parcel.java:1465)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.os.Parcel.readException(Parcel.java:1419)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.net.IConnectivityManager$Stub$Proxy.getActiveNetworkInfo(IConnectivityManager.java:813)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.net.ConnectivityManager.getActiveNetworkInfo(ConnectivityManager.java:563)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at com.zanqi.mainpage1.TabActivityMain.isConnected(TabActivityMain.java:128)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at com.zanqi.mainpage1.TabActivityMain.onCreateView(TabActivityMain.java:58)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.support.v4.app.Fragment.performCreateView(Fragment.java:1504)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:942)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1121)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1484)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:482)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.support.v4.app.FragmentTabHost.onAttachedToWindow(FragmentTabHost.java:283)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.view.View.dispatchAttachedToWindow(View.java:12585)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2458)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2465)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2465)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2465)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1217)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5670)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at   android.view.Choreographer.doCallbacks(Choreographer.java:574)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.view.Choreographer.doFrame(Choreographer.java:544)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.os.Handler.handleCallback(Handler.java:733)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.os.Handler.dispatchMessage(Handler.java:95)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.os.Looper.loop(Looper.java:136)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at android.app.ActivityThread.main(ActivityThread.java:5017)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at java.lang.reflect.Method.invokeNative(Native Method)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at java.lang.reflect.Method.invoke(Method.java:515)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at    com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
09-09 09:30:59.907: E/AndroidRuntime(1311):     at dalvik.system.NativeStart.main(Native Method)

Upvotes: 1

Views: 1506

Answers (2)

James
James

Reputation: 3555

As you're no longer in an activity, you need to set the context for most of these functions.

for example findViewByID needs to know in what view to look.

So in your example you'd use

V.findViewByID(..)

Although normally you'd use getView().findViewByID

and in the other case you'd be looking for

getActivity().getSystemService

Here's a good explanation of the different ways to get context: https://stackoverflow.com/a/9606712/3009199

Normally a onCreateView would look like this:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.activity_tab_activity_main, container, false);
}

Then move the rest of your code in onCreateView to onActivityCreated

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    //...more code goes here and you can easily just do getView().findViewByID
}

Be aware that your return V; is called an early return. As soon as a method hits a return statement, it'll do it and the rest of the code in that method is "dead".

Also you shouldn't access the UI thread in an AsyncTask. An AsyncTask is opening a new thread and doesn't necessarily have access to the UI. So instead you should pass an object comprising of all your person details into the AsyncTask instead.

One last thing, and this is preference or style, I'm sure people will disagree. I'd say it is a good habit as a newbie to avoid if and while statements without curly brackets:

Bad:

if(whatever == 1)
    //blah blah

instead you should be implicit with your brackets:

Good:

if(whatever == 1){
    //blah blah
}

Good luck!

Upvotes: 1

tritop
tritop

Reputation: 1745

return V; 

has to be at the end of the function, as a return always will exit the function and stop the rest of the code from compiling.
As for your Logcat: Add

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

just above the application tag in your AndroidManifest.xml file.

Upvotes: 2

Related Questions