Refactor to send out Broadcasts events when uploading

This commit is contained in:
YuviPanda 2013-01-30 05:25:24 +05:30
parent dd758a7964
commit 7919aa07a0
5 changed files with 177 additions and 62 deletions

View file

@ -39,7 +39,16 @@
<!-- Remove Audio Support for now <data android:mimeType="audio/*" /> --> <!-- Remove Audio Support for now <data android:mimeType="audio/*" /> -->
</intent-filter> </intent-filter>
</activity> </activity>
<activity
android:name=".ContributionsActivity"
android:icon="@drawable/ic_launcher"
android:label="@string/title_activity_share"
>
<intent-filter>
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
<service android:name="UploadService" > <service android:name="UploadService" >
</service> </service>
<service <service

View file

@ -0,0 +1,52 @@
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.media.Media;
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) {
Media media = (Media)intent.getParcelableExtra(UploadService.EXTRA_MEDIA);
Log.d("Commons", "Completed " + intent.getAction() +" of " + media.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);
}
}

View file

@ -18,6 +18,7 @@ import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.Window; import com.actionbarsherlock.view.Window;
import android.widget.*; import android.widget.*;
import android.view.*; import android.view.*;
import org.wikimedia.commons.media.Media;
public class ShareActivity extends AuthenticatedActivity { public class ShareActivity extends AuthenticatedActivity {
@ -56,11 +57,11 @@ public class ShareActivity extends AuthenticatedActivity {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
Intent uploadIntent = new Intent(getApplicationContext(), UploadService.class); Intent uploadIntent = new Intent(getApplicationContext(), UploadService.class);
uploadIntent.putExtra(UploadService.EXTRA_MEDIA_URI, mediaUri); uploadIntent.putExtra(Media.EXTRA_MEDIA_URI, mediaUri);
uploadIntent.putExtra(UploadService.EXTRA_TARGET_FILENAME, titleEdit.getText().toString()); uploadIntent.putExtra(Media.EXTRA_TARGET_FILENAME, titleEdit.getText().toString());
uploadIntent.putExtra(UploadService.EXTRA_DESCRIPTION, descEdit.getText().toString()); uploadIntent.putExtra(Media.EXTRA_DESCRIPTION, descEdit.getText().toString());
uploadIntent.putExtra(UploadService.EXTRA_MIMETYPE, mimeType); uploadIntent.putExtra(Media.EXTRA_MIMETYPE, mimeType);
uploadIntent.putExtra(UploadService.EXTRA_EDIT_SUMMARY, "Mobile upload from Wikimedia Commons Android app"); uploadIntent.putExtra(Media.EXTRA_EDIT_SUMMARY, "Mobile upload from Wikimedia Commons Android app");
startService(uploadIntent); startService(uploadIntent);
Toast startingToast = Toast.makeText(that, R.string.uploading_started, Toast.LENGTH_LONG); Toast startingToast = Toast.makeText(that, R.string.uploading_started, Toast.LENGTH_LONG);
startingToast.show(); startingToast.show();

View file

@ -3,6 +3,7 @@ package org.wikimedia.commons;
import java.io.*; import java.io.*;
import java.util.Date; import java.util.Date;
import android.support.v4.content.LocalBroadcastManager;
import org.mediawiki.api.*; import org.mediawiki.api.*;
import org.wikimedia.commons.media.Media; import org.wikimedia.commons.media.Media;
@ -23,14 +24,16 @@ import android.net.*;
public class UploadService extends IntentService { public class UploadService extends IntentService {
private static final String EXTRA_PREFIX = "org.wikimedia.commons.uploader"; private static final String EXTRA_PREFIX = "org.wikimedia.commons.upload";
public static final String EXTRA_MEDIA_URI = EXTRA_PREFIX + ".media_uri"; public static final String INTENT_UPLOAD_COMPLETE = EXTRA_PREFIX + ".completed";
public static final String EXTRA_TARGET_FILENAME = EXTRA_PREFIX + ".filename"; public static final String INTENT_UPLOAD_STARTED = EXTRA_PREFIX + ".started";
public static final String EXTRA_DESCRIPTION = EXTRA_PREFIX + ".description"; public static final String INTENT_UPLOAD_QUEUED = EXTRA_PREFIX + ".queued";
public static final String EXTRA_EDIT_SUMMARY = EXTRA_PREFIX + ".summary"; public static final String INTENT_UPLOAD_PROGRESS = EXTRA_PREFIX + ".progress";
public static final String EXTRA_MIMETYPE = EXTRA_PREFIX + ".mimetype"; public static final String EXTRA_MEDIA = ".media";
public static final String EXTRA_TRANSFERRED_BYTES = ".progress.transferred";
private NotificationManager notificationManager; private NotificationManager notificationManager;
private LocalBroadcastManager localBroadcastManager;
private CommonsApplication app; private CommonsApplication app;
private Notification curProgressNotification; private Notification curProgressNotification;
@ -56,15 +59,17 @@ public class UploadService extends IntentService {
Notification curNotification; Notification curNotification;
String notificationTag; String notificationTag;
boolean notificationTitleChanged; boolean notificationTitleChanged;
Media media;
String notificationProgressTitle; String notificationProgressTitle;
String notificationFinishingTitle; String notificationFinishingTitle;
public NotificationUpdateProgressListener(Notification curNotification, String notificationTag, String notificationProgressTitle, String notificationFinishingTitle) { public NotificationUpdateProgressListener(Notification curNotification, String notificationTag, String notificationProgressTitle, String notificationFinishingTitle, Media media) {
this.curNotification = curNotification; this.curNotification = curNotification;
this.notificationTag = notificationTag; this.notificationTag = notificationTag;
this.notificationProgressTitle = notificationProgressTitle; this.notificationProgressTitle = notificationProgressTitle;
this.notificationFinishingTitle = notificationFinishingTitle; this.notificationFinishingTitle = notificationFinishingTitle;
this.media = media;
} }
@Override @Override
public void onProgress(long transferred, long total) { public void onProgress(long transferred, long total) {
@ -75,6 +80,9 @@ public class UploadService extends IntentService {
curView.setTextViewText(R.id.uploadNotificationsCount, String.format(getString(R.string.uploads_pending_notification_indicator), toUpload)); curView.setTextViewText(R.id.uploadNotificationsCount, String.format(getString(R.string.uploads_pending_notification_indicator), toUpload));
Log.d("Commons", String.format("%d uploads left", toUpload)); Log.d("Commons", String.format("%d uploads left", toUpload));
notificationTitleChanged = true; notificationTitleChanged = true;
Intent mediaUploadStartedEvent = new Intent(INTENT_UPLOAD_STARTED);
mediaUploadStartedEvent.putExtra(EXTRA_MEDIA, media);
localBroadcastManager.sendBroadcast(mediaUploadStartedEvent);
} }
if(transferred == total) { if(transferred == total) {
// Completed! // Completed!
@ -83,6 +91,10 @@ public class UploadService extends IntentService {
} else { } else {
curNotification.contentView.setProgressBar(R.id.uploadNotificationProgress, 100, (int)(((double)transferred / (double)total) * 100), false); curNotification.contentView.setProgressBar(R.id.uploadNotificationProgress, 100, (int)(((double)transferred / (double)total) * 100), false);
notificationManager.notify(NOTIFICATION_DOWNLOAD_IN_PROGRESS, curNotification); notificationManager.notify(NOTIFICATION_DOWNLOAD_IN_PROGRESS, curNotification);
Intent mediaUploadProgressIntent = new Intent(INTENT_UPLOAD_PROGRESS);
mediaUploadProgressIntent.putExtra(EXTRA_MEDIA, media);
mediaUploadProgressIntent.putExtra(EXTRA_TRANSFERRED_BYTES, transferred);
localBroadcastManager.sendBroadcast(mediaUploadProgressIntent);
} }
} }
@ -97,6 +109,7 @@ public class UploadService extends IntentService {
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
localBroadcastManager = LocalBroadcastManager.getInstance(this);
app = (CommonsApplication)this.getApplicationContext(); app = (CommonsApplication)this.getApplicationContext();
} }
@ -109,6 +122,37 @@ public class UploadService extends IntentService {
return cursor.getString(column_index); return cursor.getString(column_index);
} }
private Media mediaFromIntent(Intent intent) {
Bundle extras = intent.getExtras();
Uri mediaUri = (Uri)extras.getParcelable(Media.EXTRA_MEDIA_URI);
String filename = intent.getStringExtra(Media.EXTRA_TARGET_FILENAME);
String description = intent.getStringExtra(Media.EXTRA_DESCRIPTION);
String editSummary = intent.getStringExtra(Media.EXTRA_EDIT_SUMMARY);
String mimeType = intent.getStringExtra(Media.EXTRA_MIMETYPE);
Date dateCreated = null;
Long length = null;
try {
length = this.getContentResolver().openAssetFileDescriptor(mediaUri, "r").getLength();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
Log.d("Commons", "MimeType is " + mimeType);
if (mimeType.startsWith("image/")) {
Cursor cursor = this.getContentResolver().query(mediaUri,
new String[]{MediaStore.Images.ImageColumns.DATE_TAKEN}, null, null, null);
if (cursor.getCount() != 0) {
cursor.moveToFirst();
dateCreated = new Date(cursor.getLong(0));
}
} /* else if (mimeType.startsWith("audio/")) {
Removed Audio implementationf or now
} */
Media media = new Media(mediaUri, filename, description, editSummary, app.getCurrentAccount().name, dateCreated, length);
return media;
}
@Override @Override
public int onStartCommand(Intent intent, int flags, int startId) { public int onStartCommand(Intent intent, int flags, int startId) {
toUpload++; toUpload++;
@ -117,48 +161,37 @@ public class UploadService extends IntentService {
Log.d("Commons", String.format("%d uploads left", toUpload)); Log.d("Commons", String.format("%d uploads left", toUpload));
notificationManager.notify(NOTIFICATION_DOWNLOAD_IN_PROGRESS, curProgressNotification); notificationManager.notify(NOTIFICATION_DOWNLOAD_IN_PROGRESS, curProgressNotification);
} }
return super.onStartCommand(intent, flags, startId);
Media media = mediaFromIntent(intent);
Intent mediaUploadQueuedIntent = new Intent(INTENT_UPLOAD_QUEUED);
mediaUploadQueuedIntent.putExtra(EXTRA_MEDIA, media);
localBroadcastManager.sendBroadcast(mediaUploadQueuedIntent);
return super.onStartCommand(mediaUploadQueuedIntent, flags, startId);
} }
@Override @Override
protected void onHandleIntent(Intent intent) { protected void onHandleIntent(Intent intent) {
MWApi api = app.getApi(); MWApi api = app.getApi();
InputStream file = null;
long length = 0;
ApiResult result; ApiResult result;
RemoteViews notificationView; RemoteViews notificationView;
Media media;
Bundle extras = intent.getExtras(); InputStream file = null;
Uri mediaUri = (Uri)extras.getParcelable(EXTRA_MEDIA_URI); long length = 0;
String filename = intent.getStringExtra(EXTRA_TARGET_FILENAME); media = (Media)intent.getParcelableExtra(EXTRA_MEDIA);
String description = intent.getStringExtra(EXTRA_DESCRIPTION);
String editSummary = intent.getStringExtra(EXTRA_EDIT_SUMMARY); String notificationTag = media.getMediaUri().toString();
String mimeType = intent.getStringExtra(EXTRA_MIMETYPE);
String notificationTag = mediaUri.toString();
Date dateCreated = null; try {
file = this.getContentResolver().openInputStream(media.getMediaUri());
try { } catch (FileNotFoundException e) {
Log.d("Commons", "MimeType is " + mimeType); throw new RuntimeException(e);
if(mimeType.startsWith("image/")) { }
file = this.getContentResolver().openInputStream(mediaUri);
length = this.getContentResolver().openAssetFileDescriptor(mediaUri, "r").getLength();
Cursor cursor = this.getContentResolver().query(mediaUri,
new String[] { MediaStore.Images.ImageColumns.DATE_TAKEN }, null, null, null);
if(cursor.getCount() != 0) {
cursor.moveToFirst();
dateCreated = new Date(cursor.getLong(0));
}
} /* else if (mimeType.startsWith("audio/")) {
Removed Audio implementationf or now
} */
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
notificationView = new RemoteViews(getPackageName(), R.layout.layout_upload_progress); notificationView = new RemoteViews(getPackageName(), R.layout.layout_upload_progress);
notificationView.setTextViewText(R.id.uploadNotificationTitle, String.format(getString(R.string.upload_progress_notification_title_start), filename)); notificationView.setTextViewText(R.id.uploadNotificationTitle, String.format(getString(R.string.upload_progress_notification_title_start), media.getFileName()));
notificationView.setProgressBar(R.id.uploadNotificationProgress, 100, 0, false); notificationView.setProgressBar(R.id.uploadNotificationProgress, 100, 0, false);
Log.d("Commons", "Before execution!"); Log.d("Commons", "Before execution!");
@ -168,16 +201,13 @@ public class UploadService extends IntentService {
.setContent(notificationView) .setContent(notificationView)
.setOngoing(true) .setOngoing(true)
.setContentIntent(PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), 0)) .setContentIntent(PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), 0))
.setTicker(String.format(getString(R.string.upload_progress_notification_title_in_progress), filename)) .setTicker(String.format(getString(R.string.upload_progress_notification_title_in_progress), media.getFileName()))
.getNotification(); .getNotification();
this.startForeground(NOTIFICATION_DOWNLOAD_IN_PROGRESS, curProgressNotification); this.startForeground(NOTIFICATION_DOWNLOAD_IN_PROGRESS, curProgressNotification);
Log.d("Commons", "Just before"); Log.d("Commons", "Just before");
NotificationUpdateProgressListener notificationUpdater = new NotificationUpdateProgressListener(curProgressNotification, notificationTag,
String.format(getString(R.string.upload_progress_notification_title_in_progress), filename),
String.format(getString(R.string.upload_progress_notification_title_finishing), filename)
);
try { try {
if(!api.validateLogin()) { if(!api.validateLogin()) {
// Need to revalidate! // Need to revalidate!
@ -192,8 +222,12 @@ public class UploadService extends IntentService {
return; return;
} }
} }
Media media = new Media(mediaUri, filename, description, editSummary, app.getCurrentAccount().name, dateCreated); NotificationUpdateProgressListener notificationUpdater = new NotificationUpdateProgressListener(curProgressNotification, notificationTag,
result = api.upload(filename, file, length, media.getPageContents(), editSummary, notificationUpdater); String.format(getString(R.string.upload_progress_notification_title_in_progress), media.getFileName()),
String.format(getString(R.string.upload_progress_notification_title_finishing), media.getFileName()),
media
);
result = api.upload(media.getFileName(), file, length, media.getPageContents(), media.getEditSummary(), notificationUpdater);
} catch (IOException e) { } catch (IOException e) {
Log.d("Commons", "I have a network fuckup"); Log.d("Commons", "I have a network fuckup");
stopForeground(true); stopForeground(true);
@ -201,8 +235,8 @@ public class UploadService extends IntentService {
.setSmallIcon(R.drawable.ic_launcher) .setSmallIcon(R.drawable.ic_launcher)
.setAutoCancel(true) .setAutoCancel(true)
.setContentIntent(PendingIntent.getService(getApplicationContext(), 0, intent, 0)) .setContentIntent(PendingIntent.getService(getApplicationContext(), 0, intent, 0))
.setTicker(String.format(getString(R.string.upload_failed_notification_title), filename)) .setTicker(String.format(getString(R.string.upload_failed_notification_title), media.getFileName()))
.setContentTitle(String.format(getString(R.string.upload_failed_notification_title), filename)) .setContentTitle(String.format(getString(R.string.upload_failed_notification_title), media.getFileName()))
.setContentText(getString(R.string.upload_failed_notification_subtitle)) .setContentText(getString(R.string.upload_failed_notification_subtitle))
.getNotification(); .getNotification();
notificationManager.notify(NOTIFICATION_UPLOAD_FAILED, failureNotification); notificationManager.notify(NOTIFICATION_UPLOAD_FAILED, failureNotification);
@ -221,12 +255,16 @@ public class UploadService extends IntentService {
Notification doneNotification = new NotificationCompat.Builder(this) Notification doneNotification = new NotificationCompat.Builder(this)
.setAutoCancel(true) .setAutoCancel(true)
.setSmallIcon(R.drawable.ic_launcher) .setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(String.format(getString(R.string.upload_completed_notification_title), filename)) .setContentTitle(String.format(getString(R.string.upload_completed_notification_title), media.getFileName()))
.setContentText(getString(R.string.upload_completed_notification_text)) .setContentText(getString(R.string.upload_completed_notification_text))
.setTicker(String.format(getString(R.string.upload_completed_notification_title), filename)) .setTicker(String.format(getString(R.string.upload_completed_notification_title), media.getFileName()))
.setContentIntent(PendingIntent.getActivity(this, 0, openUploadedPageIntent, 0)) .setContentIntent(PendingIntent.getActivity(this, 0, openUploadedPageIntent, 0))
.getNotification(); .getNotification();
notificationManager.notify(notificationTag, NOTIFICATION_DOWNLOAD_COMPLETE, doneNotification); notificationManager.notify(notificationTag, NOTIFICATION_DOWNLOAD_COMPLETE, doneNotification);
Intent mediaUploadedIntent = new Intent(INTENT_UPLOAD_COMPLETE);
mediaUploadedIntent.putExtra(EXTRA_MEDIA, media);
localBroadcastManager.sendBroadcast(mediaUploadedIntent);
} }
} }

View file

@ -9,6 +9,14 @@ import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
public class Media implements Parcelable { public class Media implements Parcelable {
private static final String EXTRA_PREFIX = "org.wikimedia.commons.media";
public static final String EXTRA_MEDIA_URI = EXTRA_PREFIX + ".uri";
public static final String EXTRA_TARGET_FILENAME = EXTRA_PREFIX + ".filename";
public static final String EXTRA_DESCRIPTION = EXTRA_PREFIX + ".description";
public static final String EXTRA_EDIT_SUMMARY = EXTRA_PREFIX + ".summary";
public static final String EXTRA_MIMETYPE = EXTRA_PREFIX + ".mimetype";
private Uri mediaUri; private Uri mediaUri;
private String fileName; private String fileName;
private String editSummary; private String editSummary;
@ -16,17 +24,22 @@ public class Media implements Parcelable {
private String description; private String description;
private String userName; private String userName;
private Date dateCreated; private Date dateCreated;
private long length;
private Date dateUploaded; private Date dateUploaded;
public Media(Uri mediaUri, String fileName, String description, String editSummary, String userName, Date dateCreated) { public Media(Uri mediaUri, String fileName, String description, String editSummary, String userName, Date dateCreated, long length) {
this.mediaUri = mediaUri; this.mediaUri = mediaUri;
this.fileName = fileName; this.fileName = fileName;
this.description = description; this.description = description;
this.editSummary = editSummary; this.editSummary = editSummary;
this.userName = userName; this.userName = userName;
this.dateCreated = dateCreated; this.dateCreated = dateCreated;
this.length = length;
}
public long getLength() {
return length;
} }
public Uri getMediaUri() { public Uri getMediaUri() {
return mediaUri; return mediaUri;
} }
@ -74,6 +87,7 @@ public class Media implements Parcelable {
parcel.writeString(description); parcel.writeString(description);
parcel.writeString(editSummary); parcel.writeString(editSummary);
parcel.writeString(userName); parcel.writeString(userName);
parcel.writeLong(length);
parcel.writeSerializable(dateCreated); parcel.writeSerializable(dateCreated);
} }
@ -83,8 +97,9 @@ public class Media implements Parcelable {
String description = parcel.readString(); String description = parcel.readString();
String editSummary = parcel.readString(); String editSummary = parcel.readString();
String userName = parcel.readString(); String userName = parcel.readString();
Long length = parcel.readLong();
Date dateCreated = (Date)parcel.readSerializable(); Date dateCreated = (Date)parcel.readSerializable();
return new Media(mediaUri, fileName, description, editSummary, userName, dateCreated); return new Media(mediaUri, fileName, description, editSummary, userName, dateCreated, length);
} }
public static final Parcelable.Creator<Media> CREATOR = new Parcelable.Creator<Media>() { public static final Parcelable.Creator<Media> CREATOR = new Parcelable.Creator<Media>() {