Android Open Source - StreetlightSeattleReporter Submit Service






From Project

Back to project page StreetlightSeattleReporter.

License

The source code is released under:

MIT License

If you think the Android project StreetlightSeattleReporter listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package org.codeforseattle.streetlightseattlereporter;
//from   w  w w  .j  av a 2 s  . c o m
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import com.google.gdata.client.spreadsheet.SpreadsheetService;
import com.google.gdata.data.spreadsheet.ListEntry;
import com.google.gdata.data.spreadsheet.ListFeed;
import com.google.gdata.data.spreadsheet.SpreadsheetEntry;
import com.google.gdata.data.spreadsheet.SpreadsheetFeed;
import com.google.gdata.data.spreadsheet.WorksheetEntry;
import com.google.gdata.data.spreadsheet.WorksheetFeed;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;
import com.google.gdata.util.common.base.StringUtil;

import android.app.IntentService;
import android.content.Intent;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
// import android.util.Log;

/**
 * An IntentService subclass for handling asynchronous task requests in a service on a separate handler thread.
 */
public class SubmitService extends IntentService 
{
  /**
   * Starts the service to perform the Post request with the given parameters. If
   * the service is already performing a task this action will be queued.
   * @throws InterruptedException 
   * 
   * @see IntentService
   */
  public static void performHttpPostRequest(Context context, HashMap<String, String> hashMap)
  {
    Intent intent = new Intent(context, SubmitService.class);
    intent.putExtra("hashMap", hashMap);
    context.startService(intent);
  }

  public SubmitService() {
    super("SubmitService");
  }

  /**
   * The fields entered on the form arrive here in the hashMap, where they are turned into the name-value pairs in the body of the Post request.
   */
  @Override
  protected void onHandleIntent(Intent intent) 
  {
    if (intent == null)
      return;
    
    // Retries happen at increasingly long, powers-of-2-second intervals, up to an hour.
    for (int interval = 2; interval <= 12; interval++)
    {
      if (isOnline()) {
        break;
      }
      try {
        int numMilliSec = (int) (1000 * Math.pow(2, interval));
        String message = "Connection unavailable. Sleeping for "  + numMilliSec/1000 + " sec.";
        Intent toastIntent = new Intent();
        toastIntent.setAction(MainActivity.TOAST_STR);
        toastIntent.putExtra("toast", message);
        sendBroadcast(toastIntent);
        Thread.sleep(numMilliSec);
      }
      catch (InterruptedException xcpt) {
        // Log.e("SubmitService.onHandleIntent", xcpt.getMessage());
      }
    }
    
      /* Request body:
         * LastName=John+Doe&Phone=206-555-5555&PhoneExtension=&Email=johndoe%40yahoo.com&PoleNumber=0000000&StreetNumber=just+a
         * +test.+please+ignore+this.&ProblemType=Unknown&ProblemDescription=Please+ignore+this+request.+Sorry+to+bother
         * +you.&SubmitForm=Submit+Trouble+Report
       */
      // Create a new HttpClient and Post Header
      HttpClient httpClient = new DefaultHttpClient();
      HttpPost httpPost = new HttpPost("http://www.seattle.gov/light/streetlight/sl_handler.asp");
//      HttpPost httpPost = new HttpPost("http://www.example.com");
      Intent broadcastIntent = new Intent();
      broadcastIntent.setAction(MainActivity.SUBMIT_RESPONSE_STR);
    
    @SuppressWarnings("unchecked")
    HashMap<String, String> hashMap = (HashMap<String, String>) intent.getSerializableExtra("hashMap");
    // The values the user entered in the activity were put in a hashmap that was included with the intent. 
    // Here we work with those values as these parameters.
    List<NameValuePair> parameters = new ArrayList<NameValuePair>();
    for (HashMap.Entry<String, String> entry : hashMap.entrySet()) {
        parameters.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
    }
      try {
        // Add the name, phone number, etc. fields to the request body.
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters);
      httpPost.setEntity(entity);
          
        httpPost.addHeader("Host", "www.seattle.gov");
        httpPost.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
        httpPost.addHeader("Origin", "http://www.seattle.gov");
        httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36");
        httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
        httpPost.addHeader("Referer", "http://www.seattle.gov/light/streetlight/form.asp");
        httpPost.addHeader("Accept-Language", "en-US,en;q=0.8");
        httpPost.addHeader("Connection", "keep-alive");

          // Execute HTTP Post Request
          HttpResponse response = httpClient.execute(httpPost);
          int statusCode = response.getStatusLine().getStatusCode();
          broadcastIntent.putExtra("statusCode", statusCode);
          String body = "", httpResponseStr = "", message = "<html><body>";
          
          HttpEntity httpEntity = response.getEntity();
          BufferedReader rd = new BufferedReader(new InputStreamReader(httpEntity.getContent()));
          while ((body = rd.readLine()) != null) 
      {
            httpResponseStr += body;
      }
          if (statusCode != 200)
          {
            broadcastIntent.putExtra("message", httpResponseStr);
            sendBroadcast(broadcastIntent);
            return;
          }
          boolean receivedExpectedResponse = true;
          String str = getString(R.string.response_1);
          
          // Check for the expected strings in the response.
          if (httpResponseStr.contains(str))
            message += "<h1>" + str + "</h1>";
          else
            receivedExpectedResponse = false;
          str = getString(R.string.response_2);
          if (httpResponseStr.contains(str))
            message += "<p>" + str + "</p>";
          else
            receivedExpectedResponse = false;
          str = getString(R.string.response_3);
          if (httpResponseStr.contains(str))
            message += "<p>" + str + getString(R.string.response_3a) + "</p>";
          else
            receivedExpectedResponse = false;
          str = getString(R.string.response_4);
          if (httpResponseStr.contains(str))
            message += "<p>" + str + "</p>";
          else
            receivedExpectedResponse = false;
          
          if (receivedExpectedResponse) {
            broadcastIntent.putExtra("message", message);
          }
          else {
            // If the expected response is not returned, return the response so that the user might figure it out.
            broadcastIntent.putExtra("message", httpResponseStr);
          }
          broadcastIntent.putExtra("receivedExpectedResponse", receivedExpectedResponse);
          sendBroadcast(broadcastIntent);

      } catch (IOException e) {
        e.printStackTrace();
      }
      
      try {
      createRecordInSpreadsheet(parameters); // Add a row to the google doc spreadsheet.
    } catch (AuthenticationException e) {
      e.printStackTrace();
    } catch (MalformedURLException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } catch (ServiceException e) {
      e.printStackTrace();
    }
    }

  /**
   * Recording a copy of the information somebody used the Streetlight Seattle Reporter app to send to Seattle City Light. 
   * Google Docs approach inspired by: https://developers.google.com/google-apps/spreadsheets/#adding_a_list_row
   * Spreadsheet viewable at: https://docs.google.com/spreadsheet/ccc?key=0AvDYc0olGEwRdE56dTlKMVVZdGYxQkc5eGJEQzJLNkE&usp=drive_web#gid=0
   * 
   * @param parameters names and values from the activity; names are column headers in the spreadsheet. 
   * @throws AuthenticationException
   * @throws MalformedURLException
   * @throws IOException
   * @throws ServiceException
   */
  private void createRecordInSpreadsheet(List<NameValuePair> parameters)
      throws AuthenticationException, MalformedURLException, IOException, ServiceException
  {
    String timeStamp = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(Calendar.getInstance().getTime());
    parameters.add(new BasicNameValuePair("Date", timeStamp));
    //parameters.remove(object)
    
    SpreadsheetService service = new SpreadsheetService("CodeForSeattle-StreetlightSeattleReporter-v1");

    // Authorize the service object for a specific user (see other sections)
    final String user = "streetlightseattlereporter@gmail.com";
    final String pword = StringUtil.repeat(getString(R.string.app_initials), 3) + "333";
    service.setUserCredentials(user, pword);

    // Define the URL to request.  This should never change.
    URL SPREADSHEET_FEED_URL = new URL("https://spreadsheets.google.com/feeds/spreadsheets/private/full");

    // Make a request to the API and get all spreadsheets.
    SpreadsheetFeed feed = service.getFeed(SPREADSHEET_FEED_URL, SpreadsheetFeed.class);
    List<SpreadsheetEntry> spreadsheets = feed.getEntries();

    if (spreadsheets.size() == 0) {
      // There were no spreadsheets, act accordingly.
      return;
    }
    SpreadsheetEntry spreadsheet = null;
    for (SpreadsheetEntry s : spreadsheets)
    {
      String title = s.getTitle().getPlainText();
      if (title.equals("StreetlightSeattleReporter"))
      {
        spreadsheet = s;
        break;
      }
      if (spreadsheet == null) // Backup plan.
        spreadsheet = spreadsheets.get(0);
    }

    // Get the first worksheet of the first spreadsheet.
    WorksheetFeed worksheetFeed = service.getFeed(spreadsheet.getWorksheetFeedUrl(), WorksheetFeed.class);
    List<WorksheetEntry> worksheets = worksheetFeed.getEntries();
    WorksheetEntry worksheet = worksheets.get(0);

    // Fetch the list feed of the worksheet.
    URL listFeedUrl = worksheet.getListFeedUrl();
    ListFeed listFeed = service.getFeed(listFeedUrl, ListFeed.class);

    // Create a local representation of the new row.
    ListEntry row = new ListEntry();
    
    // Set the values of the new row.
    for (NameValuePair param : parameters) {
      String key = param.getName();
      // Refrain from storing these 3 fields in the Google Docs spreadsheet.
      if (key.equals("LastName") || key.equals("Phone") || key.equals("Email"))
        continue;
      row.getCustomElements().setValueLocal(key, param.getValue());
    }
    // Send the new row to the API for insertion.
    row = service.insert(listFeedUrl, row);
  }
  
  /**
   * http://stackoverflow.com/questions/1560788/how-to-check-internet-access-on-android-inetaddress-never-timeouts
   * 
   * @return
   */
  private boolean isOnline()
  {
      ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
      NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
      if (activeNetwork != null && activeNetwork.isConnectedOrConnecting()) {
          return true;
      }
      return false;
  }

}




Java Source Code List

org.codeforseattle.streetlightseattlereporter.BasicAlertDialogFragment.java
org.codeforseattle.streetlightseattlereporter.MainActivity.java
org.codeforseattle.streetlightseattlereporter.MyLocationListener.java
org.codeforseattle.streetlightseattlereporter.SubmitService.java