-2

I want to call a POST request, to send some geo information from my android device to my server.

My server use PHP and I want use a php script to save all incoming post requests in my database. My php script works fine when I tried it with curl, but when I want to send some information from my android device I get some network errors.

Here is my error log

12-11 12:08:02.871 10241-10241/local.example.markus.geoapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: local.example.markus.geoapp, PID: 10241
 android.os.NetworkOnMainThreadException
 at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1448)
 at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:102)
 at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:90)
 at java.net.InetAddress.getAllByName(InetAddress.java:787)
 at com.android.okhttp.Dns$1.lookup(Dns.java:39)
 at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:175)
 at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:141)
 at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:83)
 at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:174)
 at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)
 at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)
 at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281)
 at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224)
 at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461)
 at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
 at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:258)
 at com.android.tools.profiler.support.network.httpurl.TrackedHttpURLConnection.getOutputStream(TrackedHttpURLConnection.java:288)
 at com.android.tools.profiler.support.network.httpurl.HttpURLConnection$.getOutputStream(HttpURLConnection$.java:212)
 at local.example.markus.geoapp.MapsListener.sendPost(MapsListener.java:121)
 at local.example.markus.geoapp.MapsListener.onLocationChanged(MapsListener.java:77)
 at android.location.LocationManager$ListenerTransport._handleMessage(LocationManager.java:291)
 at android.location.LocationManager$ListenerTransport.-wrap0(Unknown Source:0)
 at android.location.LocationManager$ListenerTransport$1.handleMessage(LocationManager.java:236)
 at android.os.Handler.dispatchMessage(Handler.java:105)
 at android.os.Looper.loop(Looper.java:164)
 at android.app.ActivityThread.main(ActivityThread.java:6541)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

Here is my java code

package local.example.markus.geoapp;

import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.util.Log;

import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.Timestamp;

/**
 * Created by markus on 04.12.17.
 */

public class MapsListener implements LocationListener {
// Member Variablen
private GoogleMap googleMap;

// Konstruktor
public MapsListener() {

}

// Getter und Setter
public GoogleMap getGoogleMap() {
    return googleMap;
}

public void setGoogleMap(GoogleMap googleMap) {
    this.googleMap = googleMap;
}


// Interface Methods
@Override
public void onLocationChanged(Location location) {
    // Print new Latitide and Logtitude into log
    Log.d("INFO", "New Location! Latitude: '" + location.getLatitude() + "', '" + location.getLongitude() + "'");

    // Define new Latitude and Logtitude object
    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());

    // Add a new Marker to the Map
    this.googleMap.addMarker(new MarkerOptions().position(latLng).title("Lat:" + location.getLatitude() + ", Lng: " + location.getLongitude()));

    // Build ca,era position
    CameraPosition cameraPosition = new CameraPosition.Builder()
            .target(new LatLng(location.getLatitude(), location.getLongitude()))      // Sets the center of the map to location user
            .zoom(17)                                                                 // Sets the zoom
            .bearing(0)                                                               // Sets the orientation of the camera to north
            .tilt(40)                                                                 // Sets the tilt of the camera to 30 degrees
            .build();                                                                 // Creates a CameraPosition from the builder

    // Animate camera to zoom to the new position with defined settings
    this.googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

    Log.d("Device ID", this.getDeviceId());
    this.sendPost(location);
}

@Override
public void onStatusChanged(String s, int i, Bundle bundle) {

}

@Override
public void onProviderEnabled(String s) {

}

@Override
public void onProviderDisabled(String s) {

}

private String getDeviceId() {
    if (Build.VERSION.SDK_INT <= 25) {
        return Build.SERIAL;
    } else {
        return Build.getSerial();
    }
}

private void sendPost(Location location) {
    URL url = null;
    HttpURLConnection httpURLConnection = null;
    OutputStream outputStream = null;

    try{
        url = new URL("http://example.local");
        httpURLConnection = (HttpURLConnection) url.openConnection();

        Timestamp timestamp = new Timestamp(System.currentTimeMillis());

        /*httpURLConnection.setRequestMethod("POST");
        httpURLConnection.setRequestProperty("d", this.getDeviceId());
        httpURLConnection.setRequestProperty("lat", Double.toString(location.getLatitude()));
        httpURLConnection.setRequestProperty("lon", Double.toString(location.getLongitude()));
        httpURLConnection.setRequestProperty("t", timestamp.toString());
        httpURLConnection.setDoOutput(true);*/

        outputStream = new BufferedOutputStream(httpURLConnection.getOutputStream());

        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));

        writer.write(Double.toString(location.getLongitude()));

        writer.flush();

        writer.close();

        outputStream.close();


        httpURLConnection.disconnect();

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

How I can send some information about POST requests to my php script on http://example.local/gps.php?

The post Sending POST data in Android does not work.

Volker Raschek
  • 545
  • 1
  • 6
  • 21
  • 1
    https://stackoverflow.com/questions/30180957/send-post-request-with-params-using-retrofit Use retrofit library to easier your job or run the API in main thread using Async http – Ramesh sambu Dec 11 '17 at 11:29
  • Do you know how to read? It clearly says `NetworkOnMainThreadException` and if you check the android reference, there it is: `The exception that is thrown when an application attempts to perform a networking operation on its main thread.` – vilpe89 Dec 11 '17 at 11:34

2 Answers2

0

This exception is thrown when an application attempts to perform a networking operation on its main thread. Run your code in AsyncTask.

public class HttpPost extends AsyncTask<String, String, String> {


    protected String doInBackground(String... args) {
        URL url = null;
        HttpURLConnection httpURLConnection = null;
        OutputStream outputStream = null;

        try{
           url = new URL("http://example.local");
           httpURLConnection = (HttpURLConnection) url.openConnection();

           Timestamp timestamp = new Timestamp(System.currentTimeMillis());

           /*httpURLConnection.setRequestMethod("POST");
           httpURLConnection.setRequestProperty("d", this.getDeviceId());
           httpURLConnection.setRequestProperty("lat", Double.toString(location.getLatitude()));
           httpURLConnection.setRequestProperty("lon", Double.toString(location.getLongitude()));
           httpURLConnection.setRequestProperty("t", timestamp.toString());
           httpURLConnection.setDoOutput(true);*/

           outputStream = new BufferedOutputStream(httpURLConnection.getOutputStream());

           BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));

          writer.write(Double.toString(location.getLongitude()));
          writer.flush();
          writer.close();
          outputStream.close();
          httpURLConnection.disconnect();

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

    protected void onPostExecute(String result) {
        //What you want to do with the result
        //Call a callback function for instance
        //You can also delete this method if you dont expect a result
    }
}
Andreas W
  • 275
  • 1
  • 7
0

The post Sending POST data in Android does not work.

The above should work absolutely fine else ans would have been not in accepted and upvoted state.

The error what you're getting obvious since missed how the network call is made in that ans

You missed below one.

public class CallAPI extends AsyncTask {

In android or other platforms most of the platforms also network call ui thread is not allowed. In Android AsyncTask is one way making network call off the ui thread.

Sush
  • 3,864
  • 2
  • 17
  • 35