OK jag har skrivit klart jojokort-stöd (Skånetrafiken). Det fungerar nu även om du har flera kort.
Har kört det i ett par dagar och det verkar stabilt. Nån gång under natten har den en gång misslyckats med att logga in och disablat autouppdatering (det är bara att slå på igen), det är kanske när dom kör maintenance på sidan, jag får undersöka mera.
Ladda ner här: http://kalleboo.s3.amazonaws.com/Saldo.apk Om du har installerat programmet från Market innan så går det kanske inte att installera "över" och då får man snällt avinstallera, tappa bort sina inställningar och installera om :/ tyvärr är det så tills kria kommer tillbaka från döden.
![[IMG]](proxy.php?image=http%3A%2F%2Fkalleboo.s3.amazonaws.com%2FSaldo2.png&hash=2ec929bc56a4512f53416321750b4783)
Källkod om du inte litar på att jag inte snor din data (så du kan kompilera själv):
Kod:
package com.adrup.saldo.bank.skanetrafiken;
import com.adrup.http.HttpException;
import com.adrup.http.HttpHelper;
import com.adrup.saldo.SaldoHttpClient;
import com.adrup.saldo.bank.Account;
import com.adrup.saldo.bank.AccountHashKey;
import com.adrup.saldo.bank.AuthenticationException;
import com.adrup.saldo.bank.BankException;
import com.adrup.saldo.bank.BankLogin;
import com.adrup.saldo.bank.BankManager;
import com.adrup.saldo.bank.RemoteAccount;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.message.BasicNameValuePair;
import android.content.Context;
import android.text.Html;
import android.util.Log;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* A Skånetrafiken implementation of {@link BankManager}.
*
* @author Karl Baron
*
*/
public class SkanetrafikenManager implements BankManager {
private static final String TAG = "SkanetrafikenManager";
private static final String NAME = "Skanetrafiken";
private BankLogin mBankLogin;
private Context mContext;
public SkanetrafikenManager(BankLogin bankLogin, Context context) {
this.mBankLogin = bankLogin;
this.mContext = context;
}
@Override
public String getName() {
return NAME;
}
@Override
public Map<AccountHashKey, RemoteAccount> getAccounts() throws BankException {
return getAccounts(new LinkedHashMap<AccountHashKey, RemoteAccount>());
}
@Override
public Map<AccountHashKey, RemoteAccount> getAccounts(Map<AccountHashKey, RemoteAccount> accounts) throws BankException {
Log.d(TAG, "-> getAccounts()");
HttpClient httpClient = new SaldoHttpClient(mContext);
try {
Log.d(TAG, "post login form...");
List<NameValuePair> parameters = new ArrayList<NameValuePair>(3);
parameters.add(new BasicNameValuePair("__EVENTTARGET", "ctl00$LoginBlob1$DefaultLoginButton"));
parameters.add(new BasicNameValuePair("ctl00$LoginBlob1$Username", mBankLogin.getUsername()));
parameters.add(new BasicNameValuePair("ctl00$LoginBlob1$Password", mBankLogin.getPassword()));
String res = HttpHelper.post(httpClient, "http://www.skanetrafiken.se/templates/StartPage.aspx?id=2182&epslanguage=SV", parameters);
if (res.contains("Inloggningen misslyckades")) {
throw new AuthenticationException("auth fail");
}
Log.d(TAG, "getting account list...");
res = HttpHelper.get(httpClient, "https://www.skanetrafiken.se/templates/CardInformation.aspx?id=26957&epslanguage=SV");
//pick out the viewstate (we need it to get acct balance)
Pattern pattern = Pattern.compile("id=\"__VIEWSTATE\" value=\"(.*)\"");
Matcher matcher = pattern.matcher(res);
if (!matcher.find())
throw new SkanetrafikenException("failed to find viewstate");
String viewstate = matcher.group(1);
Log.d(TAG, "searching account info...");
pattern = Pattern.compile("<tr class=\"st.+?row\">.+?<a id=\"ctl00_fullRegion_mainRegion_CardInformation1_mRepeaterMyCards_ctl(\\d{2})_LinkButton3\".+?>(.+?)</a>.+?LinkButton1.+?\">(\\d+?)</a>",Pattern.DOTALL);
matcher = pattern.matcher(res);
Pattern pattern_balance = Pattern.compile("labelsaldoinfo\">(\\d*),");
Matcher matcher_balance;
int n = 0;
while (matcher.find()) {
int groupCount = matcher.groupCount();
if (groupCount < 2)
throw new SkanetrafikenException("Missing data for account "+n);
String accountType = "Reskassa";
String rowid = matcher.group(1);
String name = Html.fromHtml(matcher.group(2)).toString();
String remoteId = matcher.group(3);
int ordinal = ++n;
long balance = 9999; //will be loaded from details page
Log.d(TAG, "loading balance for card "+remoteId+" ("+name+")...");
parameters = new ArrayList<NameValuePair>(2);
parameters.add(new BasicNameValuePair("__VIEWSTATE", viewstate));
parameters.add(new BasicNameValuePair("ctl00$fullRegion$mainRegion$CardInformation1$mRepeaterMyCards$ctl"+rowid+"$Button", "Kortinfo"));
String res_balance = HttpHelper.post(httpClient, "https://www.skanetrafiken.se/templates/CardInformation.aspx?id=26957&epslanguage=SV", parameters);
matcher_balance = pattern_balance.matcher(res_balance);
if (!matcher_balance.find() || matcher_balance.groupCount() < 1)
throw new SkanetrafikenException("couldnt find balance");
balance = Long.parseLong(matcher_balance.group(1));
//We got it all! save...
accounts.put(new AccountHashKey(remoteId, mBankLogin.getId()), new Account(remoteId, mBankLogin.getId(), ordinal, name, balance));
}
Log.d(TAG, "done.");
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
throw new SkanetrafikenException(e.getMessage(), e);
} catch (HttpException e) {
Log.e(TAG, e.getMessage(), e);
throw new SkanetrafikenException(e.getMessage(), e);
}
Log.d(TAG, "<- getAccounts()");
return accounts;
}
}