0

The user must add a marker by tapping the map. My goal is to send the Name, Category, Latitude and Longitude to a SQL database.
I followed this issue: How can you pass multiple primitive parameters to AsyncTask?, but I get error in this line:

backgroundTask.execute(method,Name,Category,Latitude,Longitude);

See the code:

AddShopActivity.java

public class AddShopActivity extends MainScreen implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {

Spinner spinner;
ArrayAdapter<CharSequence> adapter;


GoogleMap mGoogleMap;
GoogleApiClient mGoogleApiClient;

String Name, Category;
Double Latitude, Longitude, Latitude_pass, Longitude_pass;

EditText shop_name = (EditText)findViewById(R.id.Shop_Name);
Spinner shop_category = (Spinner)findViewById(R.id.spinner);

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_add_shop);
    initMap();
    spinner = (Spinner) findViewById(R.id.spinner);
    adapter = ArrayAdapter.createFromResource(this, R.array.eidoskatastimatos, android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(adapter);
}

private void initMap() {
    MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.mapFragment);
    mapFragment.getMapAsync(this);
}

@Override
public void onMapReady(GoogleMap googleMap) {
    mGoogleMap = googleMap;
    mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
    mGoogleMap.getUiSettings().setZoomControlsEnabled(true);
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();
    mGoogleApiClient.connect();
}

LocationRequest mLocationsRequest;

@Override
public void onConnected(Bundle bundle) {
    mLocationsRequest = LocationRequest.create();
    mLocationsRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationsRequest.setInterval(5000);
        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }

     LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationsRequest, this);


    mGoogleMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
        @Override
        public void onMapClick(LatLng latLng) {

            MarkerOptions marker = new MarkerOptions()
                                       .position(new LatLng(latLng.latitude, latLng.longitude))
                                       .draggable(true)
                                       .title(shop_name.getText().toString())
                                       .snippet(shop_category.getSelectedItem().toString());


            CameraUpdate update = CameraUpdateFactory.newLatLngZoom(latLng, 16);
            mGoogleMap.animateCamera(update);

            mGoogleMap.clear();
            mGoogleMap.addMarker(marker);

            Latitude_pass = latLng.latitude;
            Longitude_pass = latLng.longitude;
        }
    });

}

public void shopReg(View view)
{
    Name = shop_name.getText().toString();
    Category = shop_category.getSelectedItem().toString();
    Latitude = Latitude_pass;
    Longitude = Longitude_pass;
    String method = "save";
    BackgroundTask backgroundTask = new BackgroundTask(this);
    backgroundTask.execute(method,Name,Category,Latitude,Longitude); //here is the error. It asks me to create the method 'execute' but the guy in a tutorial I am watching doen't do this//
    finish();
}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {

}

@Override
public void onLocationChanged(Location location) {
    if (location == null){
        Toast.makeText(this, "Can't get current location", Toast.LENGTH_LONG).show();
    } else {
        LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
        CameraUpdate update = CameraUpdateFactory.newLatLngZoom(ll, 16);
        mGoogleMap.animateCamera(update);
    }

}
}

BackgroundTask.java

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

String Name, Category;
Double Latitude, Longitude;

BackgroundTask(String method, String Name, String Category, Double Latitude, Double Longitude) {
    this.Name = Name;
    this.Category = Category;
    this.Latitude = Latitude;
    this.Longitude = Longitude;
} //Trying to pass 2 types of variablew, string and double, because lat and long are double//

Context ctx;

BackgroundTask(Context ctx){
    this.ctx = ctx;
}

@Override
protected void onPreExecute() {
    super.onPreExecute();
}

@Override
protected String doInBackground(String... params) {
    String reg_url = "http://10.0.2.2/shop/register.php";
    String method = params[0];
    if(method.equals("save"))
    {
        String Name = params[1];
        String Category = params[2];
        String Latitude = params[3];
        String Longitude = params[4];
        try {
            URL url = new URL(reg_url);
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setRequestMethod("POST");
            httpURLConnection.setDoOutput(true);
            OutputStream OS = httpURLConnection.getOutputStream();
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(OS, "UTF-8"));
    String data = URLEncoder.encode("Name", "UTF-8") +"="+URLEncoder.encode(Name,"UTF-8")+"&"+
            URLEncoder.encode("Category", "UTF-8") +"="+URLEncoder.encode(Category,"UTF-8")+"&"+
            URLEncoder.encode("Latitude", "UTF-8") +"="+URLEncoder.encode(Latitude,"UTF-8")+"&"+
            URLEncoder.encode("Longitude", "UTF-8") +"="+URLEncoder.encode(Longitude,"UTF-8");
            bufferedWriter.write(data);
            bufferedWriter.flush();
            bufferedWriter.close();
            OS.close();
            InputStream IS = httpURLConnection.getInputStream();
            IS.close();
            return "Το κατάστημα προστέθηκε!";
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    return null;
}

@Override
protected void onProgressUpdate(Void... values) {
    super.onProgressUpdate(values);
}

@Override
protected void onPostExecute(String result) {
    Toast.makeText(ctx,result,Toast.LENGTH_LONG).show();
}
}
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115

2 Answers2

3

Checked the linked question again. You're missing the "Params" class.

The parameters to execute are passed into doInBackground, which yours only expects a String[]. However, that's not exactly where the error is

Your other constructor is not being used to get 2 Strings and 2 Doubles

You only used the Context one

new BackgroundTask(this);

a tutorial I am watching

All I can say is try watching again, or find another

I bet it only calls execute("save"); and has something like this

// add the context to this constructor also 
new BackgroundTask(this, Name, Category, Latitude, Longitude);

Or, looking at the Asynctask, you need to use Double.parseDouble and you must pass strings

    String Name = params[1];
    String Category = params[2];
    Double Latitude = Double.parseDouble(params[3]);
    Double Longitude = Double.parseDouble(params[4]);
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • see in the link the 3rd answer (with the 63 up votes). That one I try to apply. Also check the _edited code_, I did some changes as you said. No red underlined error this time, the app is running but **it crashes when I hit the button** which calls the `shopReg`. – Konstantinos Archimandritis Sep 16 '17 at 16:57
  • I can't fix all the runtime exceptions in your code. Read the logs and learn how to fix them. Post on Stackoverflow only if you are really stuck, but actually try to understand what the error logs tell you – OneCricketeer Sep 16 '17 at 17:07
  • And I think this answer fixes your initial post. Editing your question invalidates both answers you've received here. The recommended action would be to accept one answer, then post again with the corrected code as a [mcve] with the logcat messages – OneCricketeer Sep 16 '17 at 17:11
0

This AsyncTask<String... that the parameters pass to the execute method are all gonna be String type. You are passing, String and double.

As general recommendation write your variables following the camel case convention. An use private accesor.

Your AsyncTask should be


public class BackgroundTask extends AsyncTask {

private String name, category;
private double latitude, longitude;

BackgroundTask(double latitude, double longitude) {
    this.latitude = latitude;
    this.longitude = longitude;
}
}

Now your constructor initialize your doubles and get the Strings from the params as you are doing it now.

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
cutiko
  • 9,887
  • 3
  • 45
  • 59