Search code examples
androidpostandroid-servicealarmmanagerhttpurlconnection

Why does HttpUrlConnection Post call gives java.io.FileNotFoundException when calling it from a service invoked by alarm manager?


Details:

  1. In my main Activity I create an alarm with the following code:

    Intent myIntent1 = new Intent(MainActivity.this, AlarmReceiver.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent1,PendingIntent.FLAG_CANCEL_CURRENT);
    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), constants.INTERVAL , pendingIntent);
    
  2. Then in AlarmReceiver I invoke a Service with the following code:

      @Override
      public void onReceive(final Context context, Intent intent) {
    
      Intent in =  new Intent(context, LocationPoll.class);
      context.startService(in);
      }
    
  3. Below is the LocationPoll.java which extends service and implements location listener which onLocationChanged does the following.I use GoogleApiClient to receive updates.I just pass json data and expect json in response.

    @Override
    public void onLocationChanged(Location location) {
    String url = constants.BASE_URL+constants.TRACK_URL;
    JSONObject jsonBody = new JSONObject();
    try {
        jsonBody.put("latitude", location.getLatitude());
        jsonBody.put("longitude",location.getLongitude());
        jsonBody.put("driver_id", constants.DRIVERID);
    
    }
    catch(Exception e ){
    
    }
    JSONRequest jr = new JSONRequest(jsonBody,url,this);
    jr.execute();
    }
    
  4. JSONRequest Asynct Task does the following to make a post call using HttpUrlConnection:

    URL urlConnection = new URL(url);
        System.setProperty("http.keepAlive", "false");
         connection = (HttpURLConnection) urlConnection
                .openConnection();
        connection.setDoOutput(true);
        connection.setChunkedStreamingMode(0);
        connection.setDoInput(true);
        connection.setRequestProperty("Accept", "*/*");
        connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        connection.setRequestProperty("Accept-Encoding","gzip, deflate");
        connection.setRequestProperty("Accept-Language", "en-US,en;q=0.8,hi;q=0.6");
        connection.setRequestProperty("Connection", "close");
        connection.setRequestMethod("POST");
    
    
        OutputStream os = connection.getOutputStream();
        os.write(data.toString().getBytes("UTF-8"));
        os.close();
        connection.connect();
        _map=  connection.getHeaderFields();
        responsecode = connection.getResponseCode();
    

The above works fine when the app is in foreground or background state. But when the app is in killed state location update fails with error : java.io.FileNotFoundException. Please assist.

Logcat:

        10-14 18:50:03.806  17841-18041/? W/System.err﹕                java.io.FileNotFoundException: http://example.com
        10-14 18:50:03.807  17841-18041/? W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:197)
        10-14 18:50:03.807  17841-18041/? W/System.err﹕ at java.net.URLConnection$DefaultContentHandler.getContent(URLConnection.java:1017)
        10-14 18:50:03.807  17841-18041/? W/System.err﹕ at java.net.URLConnection.getContent(URLConnection.java:199)
        10-14 18:50:03.807  17841-18041/? W/System.err﹕ at com.bikeninja.driver_app.asynctasks.JSONRequest.doInBackground(JSONRequest.java:70)
        10-14 18:50:03.807  17841-18041/? W/System.err﹕ at com.bikeninja.driver_app.asynctasks.JSONRequest.doInBackground(JSONRequest.java:23)
        10-14 18:50:03.807  17841-18041/? W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:288)
        10-14 18:50:03.807  17841-18041/? W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        10-14 18:50:03.807  17841-18041/? W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
        10-14 18:50:03.807  17841-18041/? W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
        10-14 18:50:03.807  17841-18041/? W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
        10-14 18:50:03.809  17841-18041/? W/System.err﹕ at java.lang.Thread.run(Thread.java:818)

Solution

  • Just for anyone's information. In my case when the app was in killed state, the JSON data which I was passing had one of its field null. Reason being i used to read from a constants file within the app which was not available when app is killed. Hence used to get 404 from server.The solution was to read it from SharedPreferences.