mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Added working (sortof) My Contributions screen
Uses CursorLoader to appropriately load and update stuff as things change. Need to update UI to show things properly. Also refactored things a fair bit.
This commit is contained in:
parent
d1b088581f
commit
2260078fa7
7 changed files with 177 additions and 84 deletions
|
|
@ -40,7 +40,7 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ContributionsActivity"
|
||||
android:name=".contributions.ContributionsActivity"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/title_activity_share"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -4,5 +4,8 @@
|
|||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
<ListView android:id="@+id/contributionsList"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_width="fill_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
package org.wikimedia.commons;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.*;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.util.Log;
|
||||
import com.actionbarsherlock.app.SherlockActivity;
|
||||
import org.wikimedia.commons.contributions.Contribution;
|
||||
|
||||
public class ContributionsActivity extends SherlockActivity {
|
||||
|
||||
private LocalBroadcastManager localBroadcastManager;
|
||||
|
||||
private String[] broadcastsToReceive = {
|
||||
UploadService.INTENT_UPLOAD_STARTED,
|
||||
UploadService.INTENT_UPLOAD_QUEUED,
|
||||
UploadService.INTENT_UPLOAD_PROGRESS,
|
||||
UploadService.INTENT_UPLOAD_COMPLETE
|
||||
};
|
||||
|
||||
private BroadcastReceiver messageReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Contribution contribution = (Contribution)intent.getParcelableExtra(UploadService.EXTRA_MEDIA);
|
||||
Log.d("Commons", "Completed " + intent.getAction() +" of " + contribution.getFilename());
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
for(int i=0; i < broadcastsToReceive.length; i++) {
|
||||
localBroadcastManager.registerReceiver(messageReceiver, new IntentFilter(broadcastsToReceive[i]));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
for(int i=0; i < broadcastsToReceive.length; i++) {
|
||||
localBroadcastManager.unregisterReceiver(messageReceiver);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
localBroadcastManager = LocalBroadcastManager.getInstance(this);
|
||||
setContentView(R.layout.activity_contributions);
|
||||
}
|
||||
}
|
||||
|
|
@ -24,12 +24,9 @@ import android.net.*;
|
|||
public class UploadService extends IntentService {
|
||||
|
||||
private static final String EXTRA_PREFIX = "org.wikimedia.commons.upload";
|
||||
public static final String INTENT_UPLOAD_COMPLETE = EXTRA_PREFIX + ".completed";
|
||||
public static final String INTENT_UPLOAD_STARTED = EXTRA_PREFIX + ".started";
|
||||
public static final String INTENT_UPLOAD_QUEUED = EXTRA_PREFIX + ".queued";
|
||||
public static final String INTENT_UPLOAD_PROGRESS = EXTRA_PREFIX + ".progress";
|
||||
public static final String EXTRA_MEDIA = ".media";
|
||||
public static final String EXTRA_TRANSFERRED_BYTES = ".progress.transferred";
|
||||
public static final String INTENT_CONTRIBUTION_STATE_CHANGED = EXTRA_PREFIX + ".progress";
|
||||
public static final String EXTRA_CONTRIBUTION_ID = EXTRA_PREFIX + ".filename";
|
||||
public static final String EXTRA_TRANSFERRED_BYTES = EXTRA_PREFIX + ".progress.transferred";
|
||||
|
||||
|
||||
public static final String EXTRA_MEDIA_URI = EXTRA_PREFIX + ".uri";
|
||||
|
|
@ -89,9 +86,8 @@ public class UploadService extends IntentService {
|
|||
Log.d("Commons", String.format("%d uploads left", toUpload));
|
||||
}
|
||||
notificationTitleChanged = true;
|
||||
Intent mediaUploadStartedEvent = new Intent(INTENT_UPLOAD_STARTED);
|
||||
// mediaUploadStartedEvent.putExtra(EXTRA_MEDIA, contribution);
|
||||
localBroadcastManager.sendBroadcast(mediaUploadStartedEvent);
|
||||
contribution.setState(Contribution.STATE_IN_PROGRESS);
|
||||
contribution.save();
|
||||
}
|
||||
if(transferred == total) {
|
||||
// Completed!
|
||||
|
|
@ -100,8 +96,9 @@ public class UploadService extends IntentService {
|
|||
} else {
|
||||
curNotification.contentView.setProgressBar(R.id.uploadNotificationProgress, 100, (int)(((double)transferred / (double)total) * 100), false);
|
||||
notificationManager.notify(NOTIFICATION_DOWNLOAD_IN_PROGRESS, curNotification);
|
||||
Intent mediaUploadProgressIntent = new Intent(INTENT_UPLOAD_PROGRESS);
|
||||
// mediaUploadProgressIntent.putExtra(EXTRA_MEDIA, contribution);
|
||||
|
||||
Intent mediaUploadProgressIntent = new Intent(INTENT_CONTRIBUTION_STATE_CHANGED);
|
||||
// mediaUploadProgressIntent.putExtra(EXTRA_MEDIA contribution);
|
||||
mediaUploadProgressIntent.putExtra(EXTRA_TRANSFERRED_BYTES, transferred);
|
||||
localBroadcastManager.sendBroadcast(mediaUploadProgressIntent);
|
||||
}
|
||||
|
|
@ -174,15 +171,13 @@ public class UploadService extends IntentService {
|
|||
}
|
||||
|
||||
Contribution contribution = mediaFromIntent(intent);
|
||||
contribution.setState(Contribution.STATE_QUEUED);
|
||||
contribution.setContentProviderClient(contributionsProviderClient);
|
||||
|
||||
try {
|
||||
contributionsProviderClient.insert(ContributionsContentProvider.BASE_URI, contribution.toContentValues());
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
contribution.save();
|
||||
|
||||
Intent mediaUploadQueuedIntent = new Intent(INTENT_UPLOAD_QUEUED);
|
||||
mediaUploadQueuedIntent.putExtra(EXTRA_MEDIA, contribution);
|
||||
Intent mediaUploadQueuedIntent = new Intent();
|
||||
mediaUploadQueuedIntent.putExtra("dummy-data", contribution); // FIXME: Move to separate handler, do not inherit from IntentService
|
||||
localBroadcastManager.sendBroadcast(mediaUploadQueuedIntent);
|
||||
return super.onStartCommand(mediaUploadQueuedIntent, flags, startId);
|
||||
}
|
||||
|
|
@ -195,7 +190,7 @@ public class UploadService extends IntentService {
|
|||
RemoteViews notificationView;
|
||||
Contribution contribution;
|
||||
InputStream file = null;
|
||||
contribution = (Contribution)intent.getSerializableExtra(EXTRA_MEDIA);
|
||||
contribution = (Contribution)intent.getSerializableExtra("dummy-data");
|
||||
|
||||
String notificationTag = contribution.getLocalUri().toString();
|
||||
|
||||
|
|
@ -256,6 +251,9 @@ public class UploadService extends IntentService {
|
|||
.setContentText(getString(R.string.upload_failed_notification_subtitle))
|
||||
.getNotification();
|
||||
notificationManager.notify(NOTIFICATION_UPLOAD_FAILED, failureNotification);
|
||||
|
||||
contribution.setState(Contribution.STATE_QUEUED);
|
||||
contribution.save();
|
||||
return;
|
||||
} finally {
|
||||
toUpload--;
|
||||
|
|
@ -278,9 +276,7 @@ public class UploadService extends IntentService {
|
|||
.getNotification();
|
||||
|
||||
notificationManager.notify(notificationTag, NOTIFICATION_DOWNLOAD_COMPLETE, doneNotification);
|
||||
|
||||
Intent mediaUploadedIntent = new Intent(INTENT_UPLOAD_COMPLETE);
|
||||
//mediaUploadedIntent.putExtra(EXTRA_MEDIA, contribution);
|
||||
localBroadcastManager.sendBroadcast(mediaUploadedIntent);
|
||||
contribution.setState(Contribution.STATE_COMPLETED);
|
||||
contribution.save();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,13 +3,22 @@ package org.wikimedia.commons.contributions;
|
|||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentValues;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.*;
|
||||
import android.os.RemoteException;
|
||||
import org.wikimedia.commons.Media;
|
||||
|
||||
public class Contribution extends Media {
|
||||
|
||||
// No need to be bitwise - they're mutually exclusive
|
||||
public static final int STATE_COMPLETED = 0;
|
||||
public static final int STATE_QUEUED = 1;
|
||||
public static final int STATE_IN_PROGRESS = 2;
|
||||
|
||||
private ContentProviderClient client;
|
||||
private Uri contentUri;
|
||||
|
||||
public String getEditSummary() {
|
||||
return editSummary;
|
||||
|
|
@ -59,7 +68,23 @@ public class Contribution extends Media {
|
|||
return buffer.toString();
|
||||
}
|
||||
|
||||
public ContentValues toContentValues() {
|
||||
public void setContentProviderClient(ContentProviderClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public void save() {
|
||||
try {
|
||||
if(contentUri == null) {
|
||||
contentUri = client.insert(ContributionsContentProvider.BASE_URI, this.toContentValues());
|
||||
} else {
|
||||
client.update(contentUri, toContentValues(), null, null);
|
||||
}
|
||||
} catch(RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private ContentValues toContentValues() {
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put(Table.COLUMN_FILENAME, getFilename());
|
||||
if(getLocalUri() != null) {
|
||||
|
|
@ -86,10 +111,7 @@ public class Contribution extends Media {
|
|||
public static final String COLUMN_STATE = "state";
|
||||
public static final String COLUMN_LENGTH = "length";
|
||||
|
||||
// No need to be bitwise - they're mutually exclusive
|
||||
public static final int STATE_COMPLETED = 0;
|
||||
public static final int STATE_QUEUED = 1;
|
||||
public static final int STATE_IN_PROGRESS = 2;
|
||||
|
||||
|
||||
|
||||
private static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " ("
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
package org.wikimedia.commons.contributions;
|
||||
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.*;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.*;
|
||||
import android.support.v4.widget.SimpleCursorAdapter;
|
||||
import android.util.Log;
|
||||
import android.widget.ListView;
|
||||
import com.actionbarsherlock.app.SherlockFragmentActivity;
|
||||
import org.wikimedia.commons.R;
|
||||
import org.wikimedia.commons.UploadService;
|
||||
|
||||
// Inherit from SherlockFragmentActivity but not use Fragments. Because Loaders are available only from FragmentActivities
|
||||
public class ContributionsActivity extends SherlockFragmentActivity implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||
|
||||
private LocalBroadcastManager localBroadcastManager;
|
||||
|
||||
private ListView contributionsList;
|
||||
private SimpleCursorAdapter contributionsAdapter;
|
||||
|
||||
private String[] broadcastsToReceive = {
|
||||
UploadService.INTENT_CONTRIBUTION_STATE_CHANGED
|
||||
};
|
||||
|
||||
private String[] CONTRIBUTIONS_PROJECTION = {
|
||||
Contribution.Table.COLUMN_ID,
|
||||
Contribution.Table.COLUMN_FILENAME,
|
||||
Contribution.Table.COLUMN_LOCAL_URI,
|
||||
Contribution.Table.COLUMN_STATE
|
||||
};
|
||||
|
||||
private String CONTRIBUTION_SELECTION = "";
|
||||
private String CONTRIBUTION_SORT = Contribution.Table.COLUMN_TIMESTAMP + " DESC";
|
||||
|
||||
private BroadcastReceiver messageReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
for(int i=0; i < broadcastsToReceive.length; i++) {
|
||||
localBroadcastManager.registerReceiver(messageReceiver, new IntentFilter(broadcastsToReceive[i]));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
for(int i=0; i < broadcastsToReceive.length; i++) {
|
||||
localBroadcastManager.unregisterReceiver(messageReceiver);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
localBroadcastManager = LocalBroadcastManager.getInstance(this);
|
||||
setContentView(R.layout.activity_contributions);
|
||||
contributionsList = (ListView)findViewById(R.id.contributionsList);
|
||||
|
||||
contributionsAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, null, new String[] { Contribution.Table.COLUMN_FILENAME, Contribution.Table.COLUMN_STATE }, new int[] { android.R.id.text1, android.R.id.text2 }, SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
|
||||
contributionsList.setAdapter(contributionsAdapter);
|
||||
|
||||
getSupportLoaderManager().initLoader(0, null, this);
|
||||
}
|
||||
|
||||
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
|
||||
return new CursorLoader(this, ContributionsContentProvider.BASE_URI, CONTRIBUTIONS_PROJECTION, CONTRIBUTION_SELECTION, null, CONTRIBUTION_SORT);
|
||||
}
|
||||
|
||||
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
|
||||
contributionsAdapter.swapCursor(cursor);
|
||||
}
|
||||
|
||||
public void onLoaderReset(Loader<Cursor> cursorLoader) {
|
||||
contributionsAdapter.swapCursor(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -7,12 +7,15 @@ import android.database.Cursor;
|
|||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteQueryBuilder;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import org.wikimedia.commons.CommonsApplication;
|
||||
import org.wikimedia.commons.data.DBOpenHelper;
|
||||
|
||||
public class ContributionsContentProvider extends ContentProvider{
|
||||
|
||||
private static final int CONTRIBUTIONS = 1;
|
||||
private static final int CONTRIBUtiONS_ID = 2;
|
||||
|
||||
public static final String AUTHORITY = "org.wikimedia.commons.contributions.contentprovider";
|
||||
private static final String BASE_PATH = "contributions";
|
||||
|
|
@ -22,6 +25,7 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -37,6 +41,7 @@ public class ContributionsContentProvider extends ContentProvider{
|
|||
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
|
||||
queryBuilder.setTables(Contribution.Table.TABLE_NAME);
|
||||
|
||||
Log.d("Commons", "Insert URI is " + uri);
|
||||
int uriType = uriMatcher.match(uri);
|
||||
|
||||
switch(uriType) {
|
||||
|
|
@ -73,7 +78,7 @@ public class ContributionsContentProvider extends ContentProvider{
|
|||
throw new IllegalArgumentException("Unknown URI: " + uri);
|
||||
}
|
||||
getContext().getContentResolver().notifyChange(uri, null);
|
||||
return Uri.parse(BASE_PATH + "/" + contentValues.get(Contribution.Table.COLUMN_FILENAME));
|
||||
return Uri.parse(BASE_URI + "/" + id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -82,7 +87,39 @@ public class ContributionsContentProvider extends ContentProvider{
|
|||
}
|
||||
|
||||
@Override
|
||||
public int update(Uri uri, ContentValues contentValues, String s, String[] strings) {
|
||||
return 0;
|
||||
public int update(Uri uri, ContentValues contentValues, String selection, String[] selectionArgs) {
|
||||
int uriType = uriMatcher.match(uri);
|
||||
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
|
||||
int rowsUpdated = 0;
|
||||
switch (uriType) {
|
||||
case CONTRIBUTIONS:
|
||||
rowsUpdated = sqlDB.update(Contribution.Table.TABLE_NAME,
|
||||
contentValues,
|
||||
selection,
|
||||
selectionArgs);
|
||||
break;
|
||||
case CONTRIBUtiONS_ID:
|
||||
String id = uri.getLastPathSegment();
|
||||
|
||||
if (TextUtils.isEmpty(selection)) {
|
||||
rowsUpdated = sqlDB.update(Contribution.Table.TABLE_NAME,
|
||||
contentValues,
|
||||
Contribution.Table.COLUMN_ID + "= " + id,
|
||||
null);
|
||||
} else {
|
||||
// Doesn't make sense, since FILENAME has to be unique. Implementing for sake of completeness
|
||||
rowsUpdated = sqlDB.update(Contribution.Table.TABLE_NAME,
|
||||
contentValues,
|
||||
Contribution.Table.COLUMN_ID + "= " + id
|
||||
+ " and "
|
||||
+ selection,
|
||||
selectionArgs);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown URI: " + uri + " with type " + uriType);
|
||||
}
|
||||
getContext().getContentResolver().notifyChange(uri, null);
|
||||
return rowsUpdated;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue