mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Tap to retry failed uploads implemented
UploadService can now be bound to as a local service. Yay!
This commit is contained in:
parent
91aa440eac
commit
297f3277de
6 changed files with 104 additions and 34 deletions
|
|
@ -57,6 +57,8 @@ public class CommonsApplication extends Application {
|
|||
public static final String API_URL = "https://test.wikipedia.org/w/api.php";
|
||||
public static final String IMAGE_URL_BASE = "https://upload.wikimedia.org/wikipedia/test";
|
||||
|
||||
public static final String DEFAULT_EDIT_SUMMARY = "Uploaded using Android Commons app";
|
||||
|
||||
|
||||
public static MWApi createMWApi() {
|
||||
DefaultHttpClient client = new DefaultHttpClient();
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ import java.util.Date;
|
|||
|
||||
public class Media implements Serializable {
|
||||
|
||||
protected Media() {
|
||||
}
|
||||
|
||||
public Uri getLocalUri() {
|
||||
return localUri;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,10 +41,8 @@ public class UploadService extends Service {
|
|||
|
||||
private int toUpload;
|
||||
|
||||
private volatile Looper mServiceLooper;
|
||||
private volatile ServiceHandler mServiceHandler;
|
||||
private String mName;
|
||||
private boolean mRedelivery;
|
||||
private volatile Looper uploadThreadLooper;
|
||||
private volatile ServiceHandler uploadThreadHandler;
|
||||
|
||||
private final class ServiceHandler extends Handler {
|
||||
public ServiceHandler(Looper looper) {
|
||||
|
|
@ -119,14 +117,22 @@ public class UploadService extends Service {
|
|||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mServiceLooper.quit();
|
||||
uploadThreadLooper.quit();
|
||||
contributionsProviderClient.release();
|
||||
Log.d("Commons", "ZOMG I AM BEING KILLED HALP!");
|
||||
}
|
||||
|
||||
public class UploadServiceLocalBinder extends Binder {
|
||||
public UploadService getService() {
|
||||
return UploadService.this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final IBinder localBinder = new UploadServiceLocalBinder();
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
return localBinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -135,8 +141,8 @@ public class UploadService extends Service {
|
|||
HandlerThread thread = new HandlerThread("UploadService");
|
||||
thread.start();
|
||||
|
||||
mServiceLooper = thread.getLooper();
|
||||
mServiceHandler = new ServiceHandler(mServiceLooper);
|
||||
uploadThreadLooper = thread.getLooper();
|
||||
uploadThreadHandler = new ServiceHandler(uploadThreadLooper);
|
||||
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
app = (CommonsApplication) this.getApplicationContext();
|
||||
contributionsProviderClient = this.getContentResolver().acquireContentProviderClient(ContributionsContentProvider.AUTHORITY);
|
||||
|
|
@ -179,9 +185,20 @@ public class UploadService extends Service {
|
|||
}
|
||||
|
||||
private void postMessage(int type, Object obj) {
|
||||
Message msg = mServiceHandler.obtainMessage(type);
|
||||
Message msg = uploadThreadHandler.obtainMessage(type);
|
||||
msg.obj = obj;
|
||||
mServiceHandler.sendMessage(msg);
|
||||
uploadThreadHandler.sendMessage(msg);
|
||||
}
|
||||
|
||||
|
||||
public void queueContribution(Contribution contribution) {
|
||||
contribution.setState(Contribution.STATE_QUEUED);
|
||||
contribution.setTransferred(0);
|
||||
contribution.setContentProviderClient(contributionsProviderClient);
|
||||
|
||||
contribution.save();
|
||||
|
||||
postMessage(ACTION_UPLOAD_FILE, contribution);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -193,13 +210,10 @@ public class UploadService extends Service {
|
|||
notificationManager.notify(NOTIFICATION_UPLOAD_IN_PROGRESS, curProgressNotification);
|
||||
}
|
||||
|
||||
Log.d("Commons", "Received startcommand");
|
||||
Contribution contribution = mediaFromIntent(intent);
|
||||
contribution.setState(Contribution.STATE_QUEUED);
|
||||
contribution.setContentProviderClient(contributionsProviderClient);
|
||||
queueContribution(contribution);
|
||||
|
||||
contribution.save();
|
||||
|
||||
postMessage(ACTION_UPLOAD_FILE, contribution);
|
||||
return START_REDELIVER_INTENT;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import java.util.*;
|
|||
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.*;
|
||||
import android.os.RemoteException;
|
||||
|
|
@ -34,7 +35,7 @@ public class Contribution extends Media {
|
|||
private long transferred;
|
||||
|
||||
public String getEditSummary() {
|
||||
return editSummary;
|
||||
return editSummary != null ? editSummary : CommonsApplication.DEFAULT_EDIT_SUMMARY;
|
||||
}
|
||||
|
||||
public Uri getContentUri() {
|
||||
|
|
@ -142,6 +143,26 @@ public class Contribution extends Media {
|
|||
this.imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
private Contribution() {
|
||||
// Empty constructor for being constructed by our static methods
|
||||
}
|
||||
|
||||
public static Contribution fromCursor(Cursor cursor) {
|
||||
// Hardcoding column positions!
|
||||
Contribution c = new Contribution();
|
||||
c.contentUri = ContributionsContentProvider.uriForId(cursor.getInt(0));
|
||||
c.filename = cursor.getString(1);
|
||||
c.localUri = TextUtils.isEmpty(cursor.getString(2)) ? null : Uri.parse(cursor.getString(2));
|
||||
c.imageUrl = cursor.getString(3);
|
||||
c.timestamp = cursor.getLong(4) == 0 ? null : new Date(cursor.getLong(4));
|
||||
c.state = cursor.getInt(5);
|
||||
c.dataLength = cursor.getLong(6);
|
||||
c.dateUploaded = cursor.getLong(7) == 0 ? null : new Date(cursor.getLong(7));
|
||||
c.transferred = cursor.getLong(8);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class Table {
|
||||
public static final String TABLE_NAME = "contributions";
|
||||
|
|
@ -156,6 +177,19 @@ public class Contribution extends Media {
|
|||
public static final String COLUMN_UPLOADED = "uploaded";
|
||||
public static final String COLUMN_TRANSFERRED = "transferred"; // Currently transferred number of bytes
|
||||
|
||||
// NOTE! KEEP IN SAME ORDER AS THEY ARE DEFINED UP THERE. HELPS HARD CODE COLUMN INDICES.
|
||||
public static final String[] ALL_FIELDS = {
|
||||
COLUMN_ID,
|
||||
COLUMN_FILENAME,
|
||||
COLUMN_LOCAL_URI,
|
||||
COLUMN_IMAGE_URL,
|
||||
COLUMN_TIMESTAMP,
|
||||
COLUMN_STATE,
|
||||
COLUMN_LENGTH,
|
||||
COLUMN_UPLOADED,
|
||||
COLUMN_TRANSFERRED
|
||||
};
|
||||
|
||||
|
||||
private static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " ("
|
||||
+ "_id INTEGER PRIMARY KEY,"
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.wikimedia.commons.contributions;
|
|||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.os.Environment;
|
||||
import android.os.IBinder;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
|
|
@ -17,10 +18,7 @@ import android.text.TextUtils;
|
|||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.GridView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.*;
|
||||
import com.actionbarsherlock.app.SherlockFragmentActivity;
|
||||
import com.actionbarsherlock.view.ActionMode;
|
||||
import com.actionbarsherlock.view.Menu;
|
||||
|
|
@ -53,6 +51,18 @@ public class ContributionsActivity extends AuthenticatedActivity implements Load
|
|||
super(WikiAccountAuthenticator.COMMONS_ACCOUNT_TYPE);
|
||||
}
|
||||
|
||||
private UploadService uploadService;
|
||||
private ServiceConnection uploadServiceConnection = new ServiceConnection() {
|
||||
public void onServiceConnected(ComponentName componentName, IBinder binder) {
|
||||
uploadService = ((UploadService.UploadServiceLocalBinder)binder).getService();
|
||||
}
|
||||
|
||||
public void onServiceDisconnected(ComponentName componentName) {
|
||||
// this should never happen
|
||||
throw new RuntimeException("UploadService died but the rest of the process did not!");
|
||||
}
|
||||
};
|
||||
|
||||
private class ContributionAdapter extends CursorAdapter {
|
||||
|
||||
private final int COLUMN_FILENAME;
|
||||
|
|
@ -127,17 +137,6 @@ public class ContributionsActivity extends AuthenticatedActivity implements Load
|
|||
|
||||
private DisplayImageOptions contributionDisplayOptions;
|
||||
|
||||
private String[] CONTRIBUTIONS_PROJECTION = {
|
||||
Contribution.Table.COLUMN_ID,
|
||||
Contribution.Table.COLUMN_FILENAME,
|
||||
Contribution.Table.COLUMN_LOCAL_URI,
|
||||
Contribution.Table.COLUMN_STATE,
|
||||
Contribution.Table.COLUMN_UPLOADED,
|
||||
Contribution.Table.COLUMN_LENGTH,
|
||||
Contribution.Table.COLUMN_TRANSFERRED,
|
||||
Contribution.Table.COLUMN_IMAGE_URL
|
||||
};
|
||||
|
||||
private String CONTRIBUTION_SELECTION = "";
|
||||
/*
|
||||
This sorts in the following order:
|
||||
|
|
@ -171,11 +170,25 @@ public class ContributionsActivity extends AuthenticatedActivity implements Load
|
|||
.cacheOnDisc()
|
||||
.resetViewBeforeLoading().build();
|
||||
|
||||
Cursor allContributions = getContentResolver().query(ContributionsContentProvider.BASE_URI, CONTRIBUTIONS_PROJECTION, CONTRIBUTION_SELECTION, null, CONTRIBUTION_SORT);
|
||||
bindService(new Intent(this, UploadService.class), uploadServiceConnection, Context.BIND_AUTO_CREATE);
|
||||
|
||||
Cursor allContributions = getContentResolver().query(ContributionsContentProvider.BASE_URI, Contribution.Table.ALL_FIELDS, CONTRIBUTION_SELECTION, null, CONTRIBUTION_SORT);
|
||||
contributionsAdapter = new ContributionAdapter(this, allContributions, 0);
|
||||
contributionsList.setAdapter(contributionsAdapter);
|
||||
|
||||
getSupportLoaderManager().initLoader(0, null, this);
|
||||
|
||||
contributionsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
public void onItemClick(AdapterView<?> adapterView, View view, int position, long item) {
|
||||
Cursor cursor = (Cursor)adapterView.getItemAtPosition(position);
|
||||
Contribution c = Contribution.fromCursor(cursor);
|
||||
if(c.getState() == Contribution.STATE_FAILED) {
|
||||
uploadService.queueContribution(c);
|
||||
Log.d("Commons", "Restarting for" + c.toContentValues().toString());
|
||||
}
|
||||
Log.d("Commons", "You clicked on:" + c.toContentValues().toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -283,7 +296,7 @@ public class ContributionsActivity extends AuthenticatedActivity implements Load
|
|||
}
|
||||
|
||||
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
|
||||
return new CursorLoader(this, ContributionsContentProvider.BASE_URI, CONTRIBUTIONS_PROJECTION, CONTRIBUTION_SELECTION, null, CONTRIBUTION_SORT);
|
||||
return new CursorLoader(this, ContributionsContentProvider.BASE_URI, Contribution.Table.ALL_FIELDS, CONTRIBUTION_SELECTION, null, CONTRIBUTION_SORT);
|
||||
}
|
||||
|
||||
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
|
||||
|
|
|
|||
|
|
@ -25,10 +25,14 @@ public class ContributionsContentProvider extends ContentProvider{
|
|||
private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
|
||||
static {
|
||||
uriMatcher.addURI(AUTHORITY, BASE_PATH, CONTRIBUTIONS);
|
||||
uriMatcher.addURI(AUTHORITY, BASE_PATH + "/*", CONTRIBUTIONS_ID);
|
||||
uriMatcher.addURI(AUTHORITY, BASE_PATH + "/#", CONTRIBUTIONS_ID);
|
||||
}
|
||||
|
||||
|
||||
public static Uri uriForId(int id) {
|
||||
return Uri.parse(BASE_URI.toString() + "/" + id);
|
||||
}
|
||||
|
||||
private DBOpenHelper dbOpenHelper;
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue