Java tutorial
/* * Copyright (C) 2010 Koni * * This file is only usefull as part of WebSMS. * * This program 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 (at your option) any later * version. * * This program 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 * this program; If not, see <http://www.gnu.org/licenses/>. */ package com.rothconsulting.android.websms.connector.orange; import java.net.HttpURLConnection; import java.util.ArrayList; import org.apache.http.HttpResponse; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.message.BasicNameValuePair; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.util.Log; import android.widget.Toast; import com.google.analytics.tracking.android.GoogleAnalytics; import com.google.analytics.tracking.android.Tracker; import de.ub0r.android.websms.connector.common.Connector; import de.ub0r.android.websms.connector.common.ConnectorCommand; import de.ub0r.android.websms.connector.common.ConnectorSpec; import de.ub0r.android.websms.connector.common.ConnectorSpec.SubConnectorSpec; import de.ub0r.android.websms.connector.common.Utils; import de.ub0r.android.websms.connector.common.Utils.HttpOptions; import de.ub0r.android.websms.connector.common.WebSMSException; /** * AsyncTask to manage IO to Orange.ch API. * * @author koni */ public class ConnectorOrange extends Connector { /** Tag for output. */ private static final String TAG = "Orange"; /** Dummy String */ private static final String DUMMY = "???"; /** Entrance URL */ private static final String URL_LOGIN_STARTUP = "https://my.orange.ch/idmp/UI/Login?realm=my.orange.ch"; /** Login URL */ private static final String URL_LOGIN_ACTION = "https://my.orange.ch/idmp/UI/Login"; /** SMS Composer -> get SMS credit */ // private static final String URL_DASHBOARD = "https://my.orange.ch/de/dashboard"; private static final String URL_SMS_COMPOSER_BALANCE = "https://my.orange.ch/de/messaging/sms-composer/ph"; /** Dashboard -> get prepay credit */ private static final String URL_PREPAY_CREDIT = "https://my.orange.ch/de/dashboard/content/prepay/usage"; /** SMS URL */ private static final String URL_SENDSMS = "https://my.orange.ch/de/messaging/sms-composer.content"; /** Prepay Credit */ private String PREPAY_CREDIT = ""; /** SMS Credit */ private String SENT_SMS = DUMMY; /** SMS form(token) */ private String SMS_FORM_TOKEN = ""; /** HTTP User agent. */ private static final String USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0"; /** SMS Encoding */ private static final String ENCODING = "UTF-8"; /** Check whether this connector is bootstrapping. */ private static boolean inBootstrap = false; /** The secret login token from parsing the http response */ private String LOGIN_TOKEN = DUMMY; /** My Ad-ID */ private static final String AD_UNITID = "a14ed1536d6c700"; /** My Analytics-ID */ private static final String ANALYTICS_ID = "UA-38114228-3"; private Tracker mGaTracker; private GoogleAnalytics mGaInstance; /** * {@inheritDoc} */ @Override public final ConnectorSpec initSpec(final Context context) { final String name = context.getString(R.string.connector_orange_name); ConnectorSpec c = new ConnectorSpec(name); c.setAuthor(context.getString(R.string.connector_orange_author)); c.setBalance(null); c.setLimitLength(140); c.setAdUnitId(AD_UNITID); c.setCapabilities(ConnectorSpec.CAPABILITIES_BOOTSTRAP | ConnectorSpec.CAPABILITIES_UPDATE | ConnectorSpec.CAPABILITIES_SEND | ConnectorSpec.CAPABILITIES_PREFS); c.addSubConnector("orange", c.getName(), SubConnectorSpec.FEATURE_MULTIRECIPIENTS); return c; } /** * {@inheritDoc} */ @Override public final ConnectorSpec updateSpec(final Context context, final ConnectorSpec connectorSpec) { this.log("************************************************"); this.log("*** Start updateSpec"); this.log("************************************************"); final SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(context); if (p.getBoolean(Preferences.PREFS_ENABLED, false)) { if (p.getString(Preferences.PREFS_USER, "").length() > 0 && p.getString(Preferences.PREFS_PASSWORD, "") // . .length() > 0) { connectorSpec.setReady(); } else { connectorSpec.setStatus(ConnectorSpec.STATUS_ENABLED); } } else { connectorSpec.setStatus(ConnectorSpec.STATUS_INACTIVE); } this.log("************************************************"); this.log("*** End updateSpec"); this.log("************************************************"); return connectorSpec; } /** * {@inheritDoc} */ @Override protected final void doBootstrap(final Context context, final Intent intent) throws WebSMSException { this.log("************************************************"); this.log("*** Start doBootstrap"); this.log("************************************************"); final SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(context); if (inBootstrap && !this.SENT_SMS.equals(DUMMY) && !this.LOGIN_TOKEN.equals(DUMMY)) { this.log("already in bootstrap: skip bootstrap"); return; } this.log("Enter in new bootstrap"); this.log("LOGIN_TOKEN=" + this.LOGIN_TOKEN); if (this.LOGIN_TOKEN.equals(DUMMY)) { // Get LOGIN_TOKEN (SunQueryParamsString) this.sendData(ConnectorOrange.URL_LOGIN_STARTUP, context, null); } this.log("**** got the Token=" + this.LOGIN_TOKEN); if (this.LOGIN_TOKEN.equals(DUMMY)) { this.LOGIN_TOKEN = "cmVhbG09bXkub3JhbmdlLmNo"; } inBootstrap = true; String username = p.getString(Preferences.PREFS_USER, ""); String password = p.getString(Preferences.PREFS_PASSWORD, ""); ArrayList<BasicNameValuePair> postParameter = new ArrayList<BasicNameValuePair>(); postParameter.add(new BasicNameValuePair("IDButton", "Submit")); postParameter.add(new BasicNameValuePair("IDToken1", username)); postParameter.add(new BasicNameValuePair("IDToken2", password)); postParameter.add(new BasicNameValuePair("Login.Submit", "Anmeldung")); postParameter.add(new BasicNameValuePair("SunQueryParamsString", this.LOGIN_TOKEN)); postParameter.add(new BasicNameValuePair("encoded", "false")); postParameter.add(new BasicNameValuePair("goto", "null")); postParameter.add(new BasicNameValuePair("gotoOnFail", "")); postParameter.add(new BasicNameValuePair("gx_charset", ConnectorOrange.ENCODING)); postParameter.add(new BasicNameValuePair("iPSPCookie", "false")); // Do the Login this.log("**** Do the Login"); this.sendData(URL_LOGIN_ACTION, context, postParameter); this.setBalance(context); this.log("**** at end of bootstrap LOGIN_TOKEN = " + this.LOGIN_TOKEN); this.log("************************************************"); this.log("*** Ende doBootstrap"); this.log("************************************************"); } /** * {@inheritDoc} */ @Override protected final void doUpdate(final Context context, final Intent intent) throws WebSMSException { this.log("************************************************"); this.log("*** Start doUpdate"); this.log("************************************************"); this.doBootstrap(context, intent); // Get singleton. this.mGaInstance = GoogleAnalytics.getInstance(context); // To set the default tracker, use: // First get a tracker using a new property ID. Tracker newTracker = this.mGaInstance.getTracker(ANALYTICS_ID); // Then make newTracker the default tracker globally. this.mGaInstance.setDefaultTracker(newTracker); // Get default tracker. this.mGaTracker = this.mGaInstance.getDefaultTracker(); // Get SMS credit form dashboard ArrayList<BasicNameValuePair> postParameter = new ArrayList<BasicNameValuePair>(); this.sendData(URL_SMS_COMPOSER_BALANCE, context, postParameter); this.setBalance(context); // Google analytics if (this.mGaTracker != null) { this.log("Tracking ID=" + this.mGaTracker.getTrackingId()); this.mGaTracker.sendEvent(TAG, "doUpdate", "Balance: " + this.getSpec(context).getBalance(), 0L); } this.log("************************************************"); this.log("*** Ende doUpdate"); this.log("************************************************"); } /** * {@inheritDoc} */ @Override protected final void doSend(final Context context, final Intent intent) throws WebSMSException { this.log("************************************************"); this.log("*** Start doSend SMS"); this.log("************************************************"); this.doBootstrap(context, intent); this.sendData(URL_SENDSMS, context, null); ConnectorCommand command = new ConnectorCommand(intent); // SMS Text String text = command.getText(); this.log("text.length()=" + text.length()); this.log("text=" + text); int sent = 0; if (!this.SENT_SMS.equals(DUMMY)) { try { sent = Integer.valueOf(this.SENT_SMS); } catch (NumberFormatException e) { this.log("*** Cannot convert SMS_CREDIT to integer: " + this.SENT_SMS); } } // Building POST parameter ArrayList<BasicNameValuePair> postParameter = new ArrayList<BasicNameValuePair>(); postParameter.add(new BasicNameValuePair("form[_token]", this.SMS_FORM_TOKEN)); postParameter.add(new BasicNameValuePair("form[message]", text)); postParameter.add(new BasicNameValuePair("form[sentTillNow]", "" + sent)); postParameter.add(new BasicNameValuePair("form[submitted]", "1")); postParameter.add(new BasicNameValuePair("submit", "0")); // SMS Recipients String[] to = command.getRecipients(); this.log("to[0] =" + to[0]); if (to == null || to.length > 10) { String error = context.getString(R.string.connector_orange_more_than_10); this.log("----- ERROR: " + error); Toast.makeText(context, R.string.connector_orange_more_than_10, Toast.LENGTH_LONG).show(); } this.log("to.length=" + to.length); // Send SMS for (int i = 0; i < to.length; i++) { if (to[i] != null && to[i].length() > 1) { int index1 = to[i].indexOf("<"); int index2 = to[i].indexOf(">"); String toNumber = to[i].substring(index1 + 1, index2); postParameter.add(new BasicNameValuePair("form[to][fullNumber]", toNumber)); // Google analytics if (this.mGaTracker != null) { this.log("Tracking ID=" + this.mGaTracker.getTrackingId()); this.mGaTracker.sendEvent(TAG, "Send SMS", "Count receiver: " + i + 1, 0L); } this.log("***** POST Parameter=" + postParameter.toString()); this.sendData(URL_SENDSMS, context, postParameter); } } this.doUpdate(context, intent); this.setBalance(context); this.log("************************************************"); this.log("*** Ende doSend SMS"); this.log("************************************************"); } /** * Sending the SMS * * @param fullTargetURL * @param context * @param postParameter * @throws WebSMSException */ private void sendData(final String fullTargetURL, final Context context, final ArrayList<BasicNameValuePair> postParameter) throws WebSMSException { this.log("************************************************"); this.log("*** Start sendData"); this.log("************************************************"); try { this.log("URL: " + fullTargetURL); // send data this.log("prepare: getHttpClient(...)"); HttpOptions httpOptions = new HttpOptions(); httpOptions.url = fullTargetURL; httpOptions.userAgent = USER_AGENT; // httpOptions.encoding = ENCODING; httpOptions.trustAll = true; this.log("UrlEncodedFormEntity()"); if (postParameter != null) { httpOptions.postData = new UrlEncodedFormEntity(postParameter, ENCODING); } this.log("send data: getHttpClient(...)"); HttpResponse response = Utils.getHttpClient(httpOptions); int respStatus = response.getStatusLine().getStatusCode(); this.log("response status=" + respStatus); this.log("response=\n" + response); if (respStatus != HttpURLConnection.HTTP_OK) { throw new WebSMSException(context, R.string.error_http, "" + respStatus); } String htmlText = Utils.stream2str(response.getEntity().getContent()).trim(); if (htmlText == null || htmlText.length() == 0) { throw new WebSMSException(context, R.string.error_service); } this.log("----- Start HTTP RESPONSE--"); this.log(htmlText); this.log("----- End HTTP RESPONSE--"); // ================ // Start parse HTML // ================ // Get Login token if (fullTargetURL.equals(ConnectorOrange.URL_LOGIN_STARTUP)) { this.LOGIN_TOKEN = HtmlUtil.getHtmlString(htmlText, "SunQueryParamsString", 29, 69, " />", -1); } else // Get prepayed credit if (fullTargetURL.equals(ConnectorOrange.URL_LOGIN_ACTION) || fullTargetURL.equals(ConnectorOrange.URL_PREPAY_CREDIT)) { String prepayCredit = HtmlUtil.getHtmlString(htmlText, ">CHF", 5, 10, null, 0); if (prepayCredit != null && !prepayCredit.equals("")) { this.PREPAY_CREDIT = prepayCredit.replace("<", ""); } } else // Get SMS credit if (fullTargetURL.equals(ConnectorOrange.URL_SMS_COMPOSER_BALANCE)) { String smsCredit = HtmlUtil.getHtmlString(htmlText, "sent_sms_counter\">", 18, 20, null, 0); if (smsCredit.indexOf("<") > 0) { smsCredit = smsCredit.substring(0, 1); } if (smsCredit != null && !smsCredit.equals("")) { this.SENT_SMS = smsCredit; } } else // Get form[_token] if (fullTargetURL.equals(ConnectorOrange.URL_SENDSMS)) { String formToken = HtmlUtil.getHtmlString(htmlText, "form[_token]", 21, 66, " />", -1); if (formToken != null && !formToken.equals("")) { this.SMS_FORM_TOKEN = formToken; } } // ================ // End parse HTML // ================ htmlText = null; } catch (Exception e) { Log.e(TAG, "Unknown Error", e); throw new WebSMSException(e.getMessage()); } this.log("************************************************"); this.log("*** Ende sendData"); this.log("************************************************"); } void setBalance(final Context context) { String sms = ""; String credit = ""; if (!this.SENT_SMS.equals(DUMMY)) { try { sms = "" + (20 - Integer.valueOf(this.SENT_SMS)); if (Integer.valueOf(sms) <= 0) { Toast.makeText(context, R.string.connector_orange_balance_negativ, Toast.LENGTH_LONG).show(); } } catch (NumberFormatException e) { this.log("*** Cannot convert SMS_CREDIT to integer: " + this.SENT_SMS); sms = ""; } } if (!this.PREPAY_CREDIT.equals("")) { credit = " CHF=" + this.PREPAY_CREDIT; } else { this.getPrepayCredit(context); credit = this.PREPAY_CREDIT; } this.getSpec(context).setBalance(sms + credit); } private void getPrepayCredit(final Context context) { this.sendData(ConnectorOrange.URL_PREPAY_CREDIT, context, null); } /** * central logger * * @param message */ private void log(final String message) { // Log.d(TAG, message); } }