edu.pdx.cecs.orcycle.Uploader.java Source code

Java tutorial

Introduction

Here is the source code for edu.pdx.cecs.orcycle.Uploader.java

Source

/**
 *  ORcycle, Copyright 2014, 2015, PSU Transportation, Technology, and People Lab.
 *
 *  @author Robin Murray <robin5@pdx.edu>    (code)
 *  @author Miguel Figliozzi <figliozzi@pdx.edu> and ORcycle team (general app
 *  design and features, report questionnaires and new ORcycle features)
 *
 *  For more information on the project, go to
 *  http://www.pdx.edu/transportation-lab/orcycle and http://www.pdx.edu/transportation-lab/app-development
 *
 *  Updated/modified for Oregon pilot study and app deployment.
 *
 *  ORcycle is free software: you can redistribute it and/or modify it under the
 *  terms of the GNU General Public License as published by the Free Software
 *  Foundation, either version 3 of the License, or any later version.
 *  ORcycle is distributed in the hope that it will be useful, but WITHOUT ANY
 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 *  A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *  You should have received a copy of the GNU General Public License along with
 *  ORcycle. If not, see <http://www.gnu.org/licenses/>.
 *
 */

package edu.pdx.cecs.orcycle;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Vector;

import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.database.Cursor;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;

public class Uploader extends AsyncTask<Long, Integer, Boolean> {

    private static final String MODULE_TAG = "Uploader";
    private static final int kSaveNoteProtocolVersion = 4;
    private static final String boundary = "cycle*******notedata*******atlanta";

    private final Context mCtx;
    private final String userId;
    private final DbAdapter mDb;

    public Uploader(Context ctx, String userId) {
        super();
        this.mCtx = ctx;
        this.userId = userId;
        this.mDb = new DbAdapter(this.mCtx);
    }

    private static final String contentFieldPrefix = "--cycle*******notedata*******atlanta\r\n";

    private String makeContentField(String name, String value) {
        return contentFieldPrefix + "Content-Disposition: form-data; name=\"" + name + "\"\r\n\r\n" + value
                + "\r\n";
    }

    private boolean uploadOneSegment(long currentNoteId) {
        boolean result = false;
        final String postUrl = mCtx.getResources().getString(R.string.post_url);

        try {
            URL url = new URL(postUrl);

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true); // Allow Inputs
            conn.setDoOutput(true); // Allow Outputs
            conn.setUseCaches(false); // Don't use a Cached Copy
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("ENCTYPE", "multipart/form-data");
            conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
            conn.setRequestProperty("Cycleatl-Protocol-Version", "4");

            SegmentData segmentData = SegmentData.fetchSegment(mCtx, currentNoteId);
            JSONObject json = segmentData.getJSON();
            String deviceId = userId;

            DataOutputStream stream = new DataOutputStream(conn.getOutputStream());
            stream.writeBytes(makeContentField("ratesegment", json.toString()));
            stream.writeBytes(makeContentField("version", String.valueOf(kSaveNoteProtocolVersion)));
            stream.writeBytes(makeContentField("device", deviceId));
            stream.writeBytes(contentFieldPrefix);
            stream.flush();
            stream.close();

            int serverResponseCode = conn.getResponseCode();
            String serverResponseMessage = conn.getResponseMessage();
            Log.v(MODULE_TAG, "HTTP Response is : " + serverResponseMessage + ": " + serverResponseCode);
            if (serverResponseCode == 201 || serverResponseCode == 202) {
                segmentData.updateSegmentStatus(SegmentData.STATUS_SENT);
                result = true;
            }
        } catch (IllegalStateException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } catch (JSONException e) {
            e.printStackTrace();
            return false;
        }
        return result;
    }

    @Override
    protected Boolean doInBackground(Long... noteid) {
        // First, send the note user asked for:
        Boolean result = true;
        if (noteid.length != 0) {
            result = uploadOneSegment(noteid[0]);
        }

        // Then, automatically try and send previously-completed notes
        // that were not sent successfully.
        return result && SendAllSegments();
    }

    private boolean SendAllSegments() {

        boolean result = true;

        Vector<Long> unsentSegmentIds = new Vector<Long>();

        mDb.openReadOnly();
        try {
            Cursor cursor = mDb.fetchUnsentSegmentIds();
            try {
                if (cursor != null && cursor.getCount() > 0) {
                    // pd.setMessage("Sent. You have previously unsent notes; submitting those now.");
                    while (!cursor.isAfterLast()) {
                        unsentSegmentIds.add(Long.valueOf(cursor.getLong(0)));
                        cursor.moveToNext();
                    }
                }
            } finally {
                cursor.close();
            }
        } finally {
            mDb.close();
        }

        for (Long segmentId : unsentSegmentIds) {
            result &= uploadOneSegment(segmentId);
        }
        return result;

    }

    @Override
    protected void onPreExecute() {
        Toast.makeText(mCtx.getApplicationContext(), "Submitting. Thanks for using ORCycle!", Toast.LENGTH_LONG)
                .show();
    }

    @Override
    protected void onPostExecute(Boolean result) {
    }
}