This GitLab instance reached the end of its service life. It won't be possible to create new users or projects.

Please read the deprecation notice for more information concerning the deprecation timeline

Visit migration.git.tu-berlin.de (internal network only) to import your old projects to the new GitLab platform 📥

Commit d78d2322 by Andrew Karpow

migrated to android volley

parent 5c5c69e2
#Mon Mar 30 21:00:03 CEST 2015
#Fri Apr 03 21:39:22 CEST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.3-all.zip
......@@ -32,4 +32,5 @@ android {
dependencies {
compile 'com.android.support:support-v4:22.0.0'
compile 'com.mcxiaoke.volley:library-aar:1.0.0'
}
......@@ -3,10 +3,12 @@ package de.k4ever.k4android.fragments;
import android.app.DialogFragment;
import android.app.FragmentTransaction;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.util.Patterns;
import android.view.KeyEvent;
import android.view.LayoutInflater;
......@@ -19,12 +21,22 @@ import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.JsonObjectRequest;
import de.k4ever.k4android.R;
import de.k4ever.k4android.database.KassenContentProvider;
import de.k4ever.k4android.database.KassenSQLiteHelper;
import de.k4ever.k4android.utils.KassenConfig;
import de.k4ever.k4android.utils.KassenHttpUtils;
import de.k4ever.k4android.utils.KassenHttpUtils.HttpRequestTask;
import de.k4ever.k4android.utils.KassenHttpUtils.HttpTaskResultReceiver;
import de.k4ever.k4android.utils.KassenUtils;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Map;
public class LoginFragment extends DialogFragment implements OnEditorActionListener {
private EditText mServerURL, mPassword, mUsername;
......@@ -37,7 +49,7 @@ public class LoginFragment extends DialogFragment implements OnEditorActionListe
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.layout_login, container, false);
mUsername = (EditText) v.findViewById(R.id.username);
......@@ -45,7 +57,7 @@ public class LoginFragment extends DialogFragment implements OnEditorActionListe
getActivity()).getString("pref_username", ""));
mServerURL = (EditText) v.findViewById(R.id.apiurl);
mServerURL.setText(PreferenceManager.getDefaultSharedPreferences(
getActivity()).getString("pref_apiurl", ""));
getActivity()).getString("pref_apiurl", ""));
mPassword = (EditText) v.findViewById(R.id.password);
mPassword.setOnEditorActionListener(this);
mPassword.setText(PreferenceManager.getDefaultSharedPreferences(
......@@ -72,10 +84,10 @@ public class LoginFragment extends DialogFragment implements OnEditorActionListe
return false;
}
@Override
public void onCancel (DialogInterface dialog) {
getActivity().finish();
}
@Override
public void onCancel (DialogInterface dialog) {
getActivity().finish();
}
private void login() {
if (mServerURL.getText().toString().length() == 0 ) {
......@@ -84,18 +96,18 @@ public class LoginFragment extends DialogFragment implements OnEditorActionListe
return;
}
if (!Patterns.WEB_URL.matcher(mServerURL.getText()).matches()) {
mServerURL.setError(getText(R.string.error_no_weburl));
mServerURL.requestFocus();
return;
}
if (!Patterns.WEB_URL.matcher(mServerURL.getText()).matches()) {
mServerURL.setError(getText(R.string.error_no_weburl));
mServerURL.requestFocus();
return;
}
if (mUsername.getText().toString().length() == 0 ) {
mUsername.setError(getText(R.string.error_no_input));
mUsername.requestFocus();
return;
}
if (mPassword.getText().toString().length() == 0 ) {
mPassword.setError(getText(R.string.error_no_input));
mPassword.requestFocus();
......@@ -106,8 +118,8 @@ public class LoginFragment extends DialogFragment implements OnEditorActionListe
String k4everUrl = mServerURL.getText().toString();
if (!k4everUrl.endsWith("/"))
k4everUrl += "/";
if (!k4everUrl.startsWith("http"))
k4everUrl = "http://" + k4everUrl;
if (!k4everUrl.startsWith("http"))
k4everUrl = "http://" + k4everUrl;
final String k4everApiUrl = k4everUrl + KassenConfig.KASSEN_SUBDIR_API;
......@@ -119,33 +131,49 @@ public class LoginFragment extends DialogFragment implements OnEditorActionListe
prefs.putBoolean("pref_sortorder", true);
prefs.apply();
KassenHttpUtils.recreateInstance();
new HttpRequestTask(new HttpTaskResultReceiver() {
ProgressDialog dialog;
@Override
public void onPreExecute() {
dialog = ProgressDialog.show(getActivity(), "",
getString(R.string.please_wait), true);
}
@Override
public void onPostExecute(String result) {
dialog.dismiss();
if(!KassenUtils.parseMoney(result,getActivity())) {
Toast.makeText(getActivity(), R.string.error_wrongpw, Toast.LENGTH_LONG).show();
} else {
prefs.putBoolean("pref_loginsuccess", true);
prefs.apply();
SyncFragment fragment = new SyncFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.add(fragment, "sync");
transaction.addToBackStack(null);
transaction.commit();
KassenHttpUtils.destroyInstance();
String url = KassenHttpUtils.getUrl(KassenConfig.KASSEN_SUBDIR_BALANCE, getActivity());
final ProgressDialog dialog = ProgressDialog.show(getActivity(), "",
getString(R.string.please_wait), true);
JsonObjectRequest request = new JsonObjectRequest(
Request.Method.GET,
url,
null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject result) {
dialog.dismiss();
if(!KassenUtils.parseMoney(result, getActivity())) {
Toast.makeText(getActivity(), R.string.error_wrongpw, Toast.LENGTH_LONG).show();
} else {
prefs.putBoolean("pref_loginsuccess", true);
prefs.apply();
SyncFragment fragment = new SyncFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.add(fragment, "sync");
transaction.addToBackStack(null);
transaction.commit();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
dialog.dismiss();
Log.e("Volley", "Error: " + volleyError.toString());
Toast.makeText(getActivity(), R.string.error_wrongpw, Toast.LENGTH_LONG).show();
}
}
) {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return KassenHttpUtils.getAuthHeader(getActivity());
}
};
}, getActivity()).execute(KassenConfig.KASSEN_SUBDIR_BALANCE);
KassenHttpUtils.getInstance(getActivity()).addToRequestQueue(request);
}
}
......@@ -4,19 +4,27 @@ import android.app.DialogFragment;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import de.k4ever.k4android.R;
import de.k4ever.k4android.database.KassenUpdateDatasets;
import de.k4ever.k4android.database.KassenUpdateDatasets.RequestType;
import de.k4ever.k4android.utils.KassenConfig;
import de.k4ever.k4android.utils.KassenHttpUtils.HttpRequestTask;
import de.k4ever.k4android.utils.KassenHttpUtils.HttpTaskResultReceiver;
import de.k4ever.k4android.utils.KassenHttpUtils;
import de.k4ever.k4android.utils.KassenUtils;
import org.json.JSONObject;
import java.util.Map;
public class SyncFragment extends DialogFragment{
ProgressBar mBalance, mHistory, mVirtuals, mProducts, mTransactions;
......@@ -50,23 +58,41 @@ public class SyncFragment extends DialogFragment{
}
private void update_balance() {
new HttpRequestTask(new HttpTaskResultReceiver() {
String url = KassenHttpUtils.getUrl(KassenConfig.KASSEN_SUBDIR_BALANCE, getActivity());
mBalance.setVisibility(View.VISIBLE);
JsonObjectRequest request = new JsonObjectRequest(
Request.Method.GET,
url,
null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject result) {
if (!KassenUtils.parseMoney(result, getActivity())) {
Toast.makeText(getActivity(), R.string.error_wrongpw, Toast.LENGTH_LONG).show();
} else {
mBalance.setVisibility(View.INVISIBLE);
mBalanceCheck.setVisibility(View.VISIBLE);
update_virtuals();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Log.e("Volley", "Error: " + volleyError.toString());
Toast.makeText(getActivity(), R.string.error_wrongpw, Toast.LENGTH_LONG).show();
}
}
) {
@Override
public void onPreExecute() {
mBalance.setVisibility(View.VISIBLE);
public Map<String, String> getHeaders() throws AuthFailureError {
return KassenHttpUtils.getAuthHeader(getActivity());
}
};
@Override
public void onPostExecute(String result) {
if(!KassenUtils.parseMoney(result,getActivity())) {
Toast.makeText(getActivity(), R.string.error_wrongpw, Toast.LENGTH_LONG).show();
} else {
mBalance.setVisibility(View.INVISIBLE);
mBalanceCheck.setVisibility(View.VISIBLE);
update_virtuals();
}
}
}, getActivity()).execute(KassenConfig.KASSEN_SUBDIR_BALANCE);
KassenHttpUtils.getInstance(getActivity()).addToRequestQueue(request);
}
private void update_virtuals() {
......
package de.k4ever.k4android.utils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
import org.apache.http.client.ClientProtocolException;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.widget.ImageView;
public class KassenHttpImageCache {
private Context mContext;
private KassenHttpUtils.HttpTaskResultReceiver mResultReceiver;
private File mCache;
public KassenHttpImageCache(Context ctx) {
mContext = ctx;
// Find the dir to save cached images
String sdpath = android.os.Environment.getExternalStorageState();
if (sdpath.equals(android.os.Environment.MEDIA_MOUNTED)) {
mCache = new File(android.os.Environment.getExternalStorageDirectory()
,"data/"+ctx.getPackageName());
if(!mCache.exists())
mCache.mkdirs();
try {
(new File(mCache,".nomedia")).createNewFile();
} catch (IOException e) {}
}
else
mCache = ctx.getCacheDir();
}
public KassenHttpImageCache(Context ctx, KassenHttpUtils.HttpTaskResultReceiver receiver) {
this(ctx);
mResultReceiver = receiver;
}
class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private String url;
public BitmapDownloaderTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
private Bitmap downloadImage(final String url, final String realURL) throws IOException {
try {
final Bitmap result = KassenHttpUtils.getImage(mContext, (realURL != null ? realURL : url));
if(result != null) {
final String fileName = url.substring( url.lastIndexOf('/')+1, url.length() );
final File output = new File(mCache, fileName);
final FileOutputStream out = new FileOutputStream(output);
result.compress(Bitmap.CompressFormat.PNG, 80, out);
if (out != null)
out.close();
}
return result;
} catch (ClientProtocolException e) {
e.printStackTrace();
}
return null;
}
@Override
// Actual download method, run in the task thread
protected Bitmap doInBackground(String... params) {
// params comes from the execute() call: params[0] is the url.
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
final String apiurl = prefs.getString("pref_url", "");
final String url = apiurl + KassenConfig.KASSEN_SUBDIR_MEDIA + params[0];
try {
return downloadImage(url, null);
} catch (IOException e) {
e.printStackTrace();
}
// Failback
try {
final String realURL = KassenHttpUtils.getPage(
mContext,
KassenConfig.KASSEN_SUBDIR_THUMBS +
params[1] + "/" + params[2]
);
return downloadImage(url, apiurl + KassenUtils.trimQuotes(realURL));
} catch (Exception e1) {
}
return null;
}
@Override
// Once the image is downloaded, associates it to the imageView
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
// Change bitmap only if this process is still associated with it
if (this == bitmapDownloaderTask) {
imageView.setImageBitmap(bitmap);
}
}
if(mResultReceiver != null)
mResultReceiver.onPostExecute("");
}
}
static class DownloadedDrawable extends ShapeDrawable {
private final WeakReference<BitmapDownloaderTask> bitmapDownloaderTaskReference;
public DownloadedDrawable(BitmapDownloaderTask bitmapDownloaderTask) {
bitmapDownloaderTaskReference =
new WeakReference<BitmapDownloaderTask>(bitmapDownloaderTask);
}
public BitmapDownloaderTask getBitmapDownloaderTask() {
return bitmapDownloaderTaskReference.get();
}
}
public void download(String url, ImageView imageView, String imageID, String imageSize) {
final String fileName = url.substring( url.lastIndexOf('/')+1, url.length() );
final File f = new File(mCache, fileName);
final Bitmap bitmap = BitmapFactory.decodeFile(f.getPath());
if(bitmap != null){
imageView.setImageBitmap(bitmap);
if(mResultReceiver != null)
mResultReceiver.onPostExecute("");
} else if (cancelPotentialDownload(url, imageView)) {
BitmapDownloaderTask task = new BitmapDownloaderTask(imageView);
DownloadedDrawable downloadedDrawable = new DownloadedDrawable(task);
imageView.setImageDrawable(downloadedDrawable);
task.execute(url, imageID, imageSize);
}
}
private static boolean cancelPotentialDownload(String url, ImageView imageView) {
BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
if (bitmapDownloaderTask != null) {
String bitmapUrl = bitmapDownloaderTask.url;
if ((bitmapUrl == null) || (!bitmapUrl.equals(url))) {
bitmapDownloaderTask.cancel(true);
} else {
// The same URL is already being downloaded.
return false;
}
}
return true;
}
private static BitmapDownloaderTask getBitmapDownloaderTask(ImageView imageView) {
if (imageView != null) {
Drawable drawable = imageView.getDrawable();
if (drawable instanceof DownloadedDrawable) {
DownloadedDrawable downloadedDrawable = (DownloadedDrawable)drawable;
return downloadedDrawable.getBitmapDownloaderTask();
}
}
return null;
}
}
......@@ -16,213 +16,129 @@
package de.k4ever.k4android.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.json.JSONObject;
import android.util.Base64;
import android.util.LruCache;
import com.android.volley.*;
import com.android.volley.toolbox.*;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;
import de.k4ever.k4android.R;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.InputStream;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.Map;
public class KassenHttpUtils {
public interface HttpTaskResultReceiver{
boolean get = true;
public void onPreExecute();
public void onPostExecute(String result);
}
private static KassenHttpUtils mInstance;
private static Context mCtx;
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private static String mAddress;
public static void destroyInstance() {
_instance = null;
mInstance = null;
}
private static KassenHttpClient _instance = null;
private static KassenHttpClient getHttpClientInstance(Context ctx) {
if(_instance == null) {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
setAPIUrl(prefs.getString("pref_apiurl", ""));
return _instance = new KassenHttpClient(ctx);
} else
return _instance;
}
public static void recreateInstance() {
_instance = null;
public static String getUrl(String url, Context context) {
return getInstance(context).mAddress + url;
}
private KassenHttpUtils(Context context) {
mCtx = context;
mRequestQueue = getRequestQueue();
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
setAPIUrl(prefs.getString("pref_apiurl", ""));
mImageLoader = new ImageLoader(mRequestQueue,
new ImageLoader.ImageCache() {
private final LruCache<String, Bitmap>
cache = new LruCache<String, Bitmap>(20);
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}
public static synchronized KassenHttpUtils getInstance(Context ctx) {
if (mInstance == null) {
mInstance = new KassenHttpUtils(ctx);
}
return mInstance;
}
public static class HttpRequestTask extends AsyncTask<String, Void, String> {
Exception err;
HttpTaskResultReceiver receiver;
Context context;
private List<NameValuePair> httpParams;
private JSONObject jsonParams;
private boolean post = false;
public HttpRequestTask(HttpTaskResultReceiver receiver, Context context) {
this.receiver = receiver;
this.context = context;
}
public HttpRequestTask makePostRequest(List<NameValuePair> params) {
this.httpParams = params;
this.jsonParams = null;
this.post = true;
return this;
}
public HttpRequestTask makePostRequest(JSONObject params) {
this.jsonParams = params;
this.httpParams = null;
this.post = true;
return this;
}
protected void onPreExecute () {
err = null;
receiver.onPreExecute();
}
protected String doInBackground(String... urls) {
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
SSLContext ctx;
try {
if(post)
{
if(httpParams == null)
return postPage(context, urls[0], jsonParams);
else
return postPage(context, urls[0], httpParams);
KeyStore trustStore = KeyStore.getInstance("BKS");
final InputStream in = mCtx.getResources().openRawResource(R.raw.truststore);
try {
trustStore.load(in, "freitagsrunde".toCharArray());
} finally {
in.close();
}
return getPage(context, urls[0]);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
ctx = SSLContext.getInstance("TLS");
ctx.init(null, tmf.getTrustManagers(), null);
} catch (Exception e) {
e.printStackTrace();
Log.w("HTTP",e.getMessage());
err = e;
throw new AssertionError(e);
}
return "";
}
protected void onPostExecute(String result) {
post = false;
if(err != null)
Toast.makeText(context, "Error occured: "+err.getMessage(), Toast.LENGTH_LONG).show();
receiver.onPostExecute(result);
}
}
private static String mAddress;
mRequestQueue = Volley.newRequestQueue(
mCtx.getApplicationContext(),
new HurlStack(
null,
ctx.getSocketFactory()
)
);
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req) {
getRequestQueue().add(req);
}
public ImageLoader getImageLoader() {
return mImageLoader;
}
public static void setAPIUrl(String address) {
if(!address.endsWith("/"))
address += "/";
mAddress = address;
}