Merge remote-tracking branch 'remotes/upstream/uploadShowsFiles' into uploadShowsFiles_Master

This commit is contained in:
tobiasKaminsky 2016-01-03 13:43:23 +01:00
commit 718aef0039
5 changed files with 352 additions and 68 deletions

@ -1 +1 @@
Subproject commit 1b7a5690409b4c694fbff126791289b9720e29f7
Subproject commit 9e5c44ddb58970f1bbdf6723145a47379bdbccba

View file

@ -42,7 +42,6 @@
android:divider="@color/list_divider_background"
android:dividerHeight="1dip">
</ListView>
</FrameLayout>
<LinearLayout

View file

@ -29,7 +29,7 @@
android:layout_width="@dimen/file_icon_size"
android:layout_height="@dimen/file_icon_size"
android:layout_gravity="center_vertical|center"
android:src="@drawable/ic_menu_archive"
android:src="@drawable/ic_menu_archive"
android:id="@+id/thumbnail"
android:layout_marginRight="@dimen/standard_padding"/>
@ -37,9 +37,8 @@
android:text="TextView"
android:layout_width="fill_parent"
android:id="@+id/filename"
android:layout_height="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:layout_gravity="center_vertical"
android:textSize="20dip"/>
android:textSize="16sp" />
</LinearLayout>

View file

@ -0,0 +1,96 @@
package com.owncloud.android.ui.activity;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.accounts.Account;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.storage.StorageManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import com.owncloud.android.R;
import com.owncloud.android.authentication.AccountUtils;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
import com.owncloud.android.datamodel.ThumbnailsCacheManager.AsyncDrawable;
import com.owncloud.android.lib.common.OwnCloudAccount;
import com.owncloud.android.utils.DisplayUtils;
import com.owncloud.android.utils.MimetypeIconUtil;
public class ImageSimpleAdapter extends SimpleAdapter {
private Context mContext;
private Account mAccount;
private FileDataStorageManager mStorageManager;
public LayoutInflater inflater = null;
public ImageSimpleAdapter(Context context,
List<? extends Map<String, ?>> data, int resource, String[] from,
int[] to, FileDataStorageManager storageManager, Account account) {
super(context, data, resource, from, to);
mAccount = account;
mStorageManager = storageManager;
mContext = context;
inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.uploader_list_item_layout, null);
HashMap<String, OCFile> data = (HashMap<String, OCFile>) getItem(position);
OCFile file = data.get("dirname");
TextView filename = (TextView) vi.findViewById(R.id.filename);
filename.setText((CharSequence) file.getFileName());
ImageView fileIcon = (ImageView) vi.findViewById(R.id.thumbnail);
fileIcon.setTag(file.getFileId());
// get Thumbnail if file is image
if (file.isImage() && file.getRemoteId() != null){
// Thumbnail in Cache?
Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
String.valueOf(file.getRemoteId())
);
if (thumbnail != null && !file.needsUpdateThumbnail()){
fileIcon.setImageBitmap(thumbnail);
} else {
// generate new Thumbnail
if (ThumbnailsCacheManager.cancelPotentialWork(file, fileIcon)) {
final ThumbnailsCacheManager.ThumbnailGenerationTask task =
new ThumbnailsCacheManager.ThumbnailGenerationTask(fileIcon, mStorageManager,
mAccount);
if (thumbnail == null) {
thumbnail = ThumbnailsCacheManager.mDefaultImg;
}
final AsyncDrawable asyncDrawable = new AsyncDrawable(
mContext.getResources(),
thumbnail,
task
);
fileIcon.setImageDrawable(asyncDrawable);
task.execute(file);
}
}
} else {
fileIcon.setImageResource(
MimetypeIconUtil.getFileTypeIconId(file.getMimetype(), file.getFileName())
);
}
return vi;
}
}

View file

@ -23,6 +23,7 @@
package com.owncloud.android.ui.activity;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
@ -30,15 +31,39 @@ import java.util.List;
import java.util.Stack;
import java.util.Vector;
import com.owncloud.android.MainApp;
import com.owncloud.android.R;
import com.owncloud.android.authentication.AccountAuthenticator;
import com.owncloud.android.authentication.AuthenticatorActivity;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileUploader;
import com.owncloud.android.lib.common.OwnCloudAccount;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
import com.owncloud.android.lib.common.OwnCloudCredentials;
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
import com.owncloud.android.lib.common.utils.Log_OC;
import com.owncloud.android.operations.RefreshFolderOperation;
import com.owncloud.android.operations.SynchronizeFolderOperation;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AlertDialog.Builder;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.IntentFilter;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
@ -79,6 +104,7 @@ import com.owncloud.android.lib.common.utils.Log_OC;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.operations.CreateFolderOperation;
import com.owncloud.android.syncadapter.FileSyncAdapter;
import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
import com.owncloud.android.ui.dialog.LoadingDialog;
import com.owncloud.android.utils.CopyTmpFileAsyncTask;
@ -101,6 +127,9 @@ public class Uploader extends FileActivity
private boolean mCreateDir;
private String mUploadPath;
private OCFile mFile;
private SyncBroadcastReceiver mSyncBroadcastReceiver;
private boolean mSyncInProgress = false;
private boolean mAccountSelected;
private boolean mAccountSelectionShowing;
@ -173,6 +202,13 @@ public class Uploader extends FileActivity
showDialog(DIALOG_NO_STREAM);
}
// Listen for sync messages
IntentFilter syncIntentFilter = new IntentFilter(RefreshFolderOperation.
EVENT_SINGLE_FOLDER_CONTENTS_SYNCED);
syncIntentFilter.addAction(RefreshFolderOperation.EVENT_SINGLE_FOLDER_SHARES_SYNCED);
mSyncBroadcastReceiver = new SyncBroadcastReceiver();
registerReceiver(mSyncBroadcastReceiver, syncIntentFilter);
super.setAccount(account, savedAccount);
}
@ -230,8 +266,8 @@ public class Uploader extends FileActivity
if (android.os.Build.VERSION.SDK_INT >
android.os.Build.VERSION_CODES.ECLAIR_MR1) {
// using string value since in API7 this
// constatn is not defined
// in API7 < this constatant is defined in
// constant is not defined
// in API7 < this constant is defined in
// Settings.ADD_ACCOUNT_SETTINGS
// and Settings.EXTRA_AUTHORITIES
Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);
@ -319,12 +355,14 @@ public class Uploader extends FileActivity
@Override
public void onBackPressed() {
if (mParents.size() <= 1) {
unregisterReceiver(mSyncBroadcastReceiver);
super.onBackPressed();
return;
} else {
mParents.pop();
String full_path = generatePath(mParents);
startSyncFolderOperation(getStorageManager().getFileByPath(full_path));
populateDirectoryList();
}
}
@ -339,13 +377,16 @@ public class Uploader extends FileActivity
// filter on dirtype
Vector<OCFile> files = new Vector<OCFile>();
for (OCFile f : tmpfiles)
if (f.isFolder())
files.add(f);
if (files.size() < position) {
throw new IndexOutOfBoundsException("Incorrect item selected");
}
mParents.push(files.get(position).getFileName());
populateDirectoryList();
if (files.get(position).isFolder()){
OCFile folderToEnter = files.get(position);
startSyncFolderOperation(folderToEnter);
mParents.push(folderToEnter.getFileName());
populateDirectoryList();
}
}
@Override
@ -420,19 +461,19 @@ public class Uploader extends FileActivity
if (mFile != null) {
// TODO Enable when "On Device" is recovered ?
Vector<OCFile> files = getStorageManager().getFolderContent(mFile/*, false*/);
List<HashMap<String, Object>> data = new LinkedList<HashMap<String,Object>>();
List<HashMap<String, OCFile>> data = new LinkedList<HashMap<String,OCFile>>();
for (OCFile f : files) {
HashMap<String, Object> h = new HashMap<String, Object>();
if (f.isFolder()) {
h.put("dirname", f.getFileName());
HashMap<String, OCFile> h = new HashMap<String, OCFile>();
h.put("dirname", f);
data.add(h);
}
}
SimpleAdapter sa = new SimpleAdapter(this,
ImageSimpleAdapter sa = new ImageSimpleAdapter(this,
data,
R.layout.uploader_list_item_layout,
new String[] {"dirname"},
new int[] {R.id.filename});
new int[] {R.id.filename},
getStorageManager(), getAccount());
mListView.setAdapter(sa);
Button btnChooseFolder = (Button) findViewById(R.id.uploader_choose_folder);
@ -444,6 +485,27 @@ public class Uploader extends FileActivity
mListView.setOnItemClickListener(this);
}
}
public void startSyncFolderOperation(OCFile folder) {
long currentSyncTime = System.currentTimeMillis();
mSyncInProgress = true;
// perform folder synchronization
RemoteOperation synchFolderOp = new RefreshFolderOperation( folder,
currentSyncTime,
false,
false,
false,
getStorageManager(),
getAccount(),
getApplicationContext()
);
synchFolderOp.execute(getAccount(), this, null, null);
setSupportProgressBarIndeterminateVisibility(true);
}
private String generatePath(Stack<String> dirs) {
String full_path = "";
@ -482,55 +544,54 @@ public class Uploader extends FileActivity
if (uri != null) {
if (uri.getScheme().equals("content")) {
String mimeType = getContentResolver().getType(uri);
String mimeType = getContentResolver().getType(uri);
if (mimeType.contains("image")) {
String[] CONTENT_PROJECTION = { Images.Media.DATA,
Images.Media.DISPLAY_NAME, Images.Media.MIME_TYPE,
Images.Media.SIZE };
Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null,
null, null);
c.moveToFirst();
int index = c.getColumnIndex(Images.Media.DATA);
data = c.getString(index);
filePath = mUploadPath +
c.getString(c.getColumnIndex(Images.Media.DISPLAY_NAME));
if (mimeType.contains("image")) {
String[] CONTENT_PROJECTION = { Images.Media.DATA, Images.Media.DISPLAY_NAME,
Images.Media.MIME_TYPE, Images.Media.SIZE};
Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null, null, null);
c.moveToFirst();
int index = c.getColumnIndex(Images.Media.DATA);
data = c.getString(index);
local.add(data);
remote.add(mUploadPath + c.getString(c.getColumnIndex(Images.Media.DISPLAY_NAME)));
} else if (mimeType.contains("video")) {
String[] CONTENT_PROJECTION = { Video.Media.DATA,
Video.Media.DISPLAY_NAME, Video.Media.MIME_TYPE,
Video.Media.SIZE, Video.Media.DATE_MODIFIED };
Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null,
null, null);
c.moveToFirst();
int index = c.getColumnIndex(Video.Media.DATA);
data = c.getString(index);
filePath = mUploadPath +
c.getString(c.getColumnIndex(Video.Media.DISPLAY_NAME));
} else if (mimeType.contains("audio")) {
String[] CONTENT_PROJECTION = { Audio.Media.DATA,
Audio.Media.DISPLAY_NAME, Audio.Media.MIME_TYPE,
Audio.Media.SIZE };
Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null,
null, null);
c.moveToFirst();
int index = c.getColumnIndex(Audio.Media.DATA);
data = c.getString(index);
filePath = mUploadPath +
c.getString(c.getColumnIndex(Audio.Media.DISPLAY_NAME));
}
else if (mimeType.contains("video")) {
String[] CONTENT_PROJECTION = { Video.Media.DATA, Video.Media.DISPLAY_NAME,
Video.Media.MIME_TYPE, Video.Media.SIZE,
Video.Media.DATE_MODIFIED };
Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null, null, null);
c.moveToFirst();
int index = c.getColumnIndex(Video.Media.DATA);
data = c.getString(index);
local.add(data);
remote.add(mUploadPath + c.getString(c.getColumnIndex(Video.Media.DISPLAY_NAME)));
} else {
Cursor cursor = getContentResolver().query(uri,
new String[]{MediaStore.MediaColumns.DISPLAY_NAME},
null, null, null);
cursor.moveToFirst();
int nameIndex = cursor.getColumnIndex(cursor.getColumnNames()[0]);
if (nameIndex >= 0) {
filePath = mUploadPath + cursor.getString(nameIndex);
}
}
}
else if (mimeType.contains("audio")) {
String[] CONTENT_PROJECTION = { Audio.Media.DATA, Audio.Media.DISPLAY_NAME,
Audio.Media.MIME_TYPE, Audio.Media.SIZE };
Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null, null, null);
c.moveToFirst();
int index = c.getColumnIndex(Audio.Media.DATA);
data = c.getString(index);
local.add(data);
remote.add(mUploadPath + c.getString(c.getColumnIndex(Audio.Media.DISPLAY_NAME)));
}
else {
filePath = Uri.decode(uri.toString()).replace(uri.getScheme() + "://", "");
// cut everything whats before mnt. It occured to me that sometimes apps send
// their name into the URI
if (filePath.contains("mnt")) {
String splitedFilePath[] = filePath.split("/mnt");
filePath = splitedFilePath[1];
}
final File file = new File(filePath);
local.add(file.getAbsolutePath());
remote.add(mUploadPath + file.getName());
}
} else if (uri.getScheme().equals("file")) {
filePath = Uri.decode(uri.toString()).replace(uri.getScheme() +
"://", "");
@ -683,8 +744,137 @@ public class Uploader extends FileActivity
}
return retval;
}
private OCFile getCurrentFolder(){
OCFile file = mFile;
if (file != null) {
if (file.isFolder()) {
return file;
} else if (getStorageManager() != null) {
String parentPath = file.getRemotePath().substring(0,
file.getRemotePath().lastIndexOf(file.getFileName()));
return getStorageManager().getFileByPath(parentPath);
}
}
return null;
}
private void browseToRoot() {
OCFile root = getStorageManager().getFileByPath(OCFile.ROOT_PATH);
mFile = root;
startSyncFolderOperation(root);
}
protected void requestCredentialsUpdate() {
Intent updateAccountCredentials = new Intent(this, AuthenticatorActivity.class);
updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, getAccount());
updateAccountCredentials.putExtra(
AuthenticatorActivity.EXTRA_ACTION,
AuthenticatorActivity.ACTION_UPDATE_EXPIRED_TOKEN);
updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
startActivity(updateAccountCredentials);
}
private class SyncBroadcastReceiver extends BroadcastReceiver {
/**
* {@link BroadcastReceiver} to enable syncing feedback in UI
*/
@Override
public void onReceive(Context context, Intent intent) {
try {
String event = intent.getAction();
Log_OC.d(TAG, "Received broadcast " + event);
String accountName = intent.getStringExtra(FileSyncAdapter.EXTRA_ACCOUNT_NAME);
String synchFolderRemotePath = intent.getStringExtra(FileSyncAdapter.EXTRA_FOLDER_PATH);
RemoteOperationResult synchResult = (RemoteOperationResult) intent.getSerializableExtra(
FileSyncAdapter.EXTRA_RESULT);
boolean sameAccount = (getAccount() != null && accountName.equals(getAccount().name)
&& getStorageManager() != null);
if (sameAccount) {
if (FileSyncAdapter.EVENT_FULL_SYNC_START.equals(event)) {
mSyncInProgress = true;
} else {
OCFile currentFile = (mFile == null) ? null :
getStorageManager().getFileByPath(mFile.getRemotePath());
OCFile currentDir = (getCurrentFolder() == null) ? null :
getStorageManager().getFileByPath(getCurrentFolder().getRemotePath());
if (currentDir == null) {
// current folder was removed from the server
Toast.makeText(context,
String.format(
getString(R.string.sync_current_folder_was_removed),
getCurrentFolder().getFileName()),
Toast.LENGTH_LONG)
.show();
browseToRoot();
} else {
if (currentFile == null && !mFile.isFolder()) {
// currently selected file was removed in the server, and now we know it
currentFile = currentDir;
}
if (synchFolderRemotePath != null &&
currentDir.getRemotePath().equals(synchFolderRemotePath)) {
populateDirectoryList();
}
mFile = currentFile;
}
mSyncInProgress = (!FileSyncAdapter.EVENT_FULL_SYNC_END.equals(event) &&
!RefreshFolderOperation.EVENT_SINGLE_FOLDER_SHARES_SYNCED.equals(event));
if (RefreshFolderOperation.EVENT_SINGLE_FOLDER_CONTENTS_SYNCED.
equals(event) &&
/// TODO refactor and make common
synchResult != null && !synchResult.isSuccess() &&
(synchResult.getCode() == ResultCode.UNAUTHORIZED ||
synchResult.isIdPRedirection() ||
(synchResult.isException() && synchResult.getException()
instanceof AuthenticatorException))) {
OwnCloudClient client = null;
try {
OwnCloudAccount ocAccount =
new OwnCloudAccount(getAccount(), context);
client = (OwnCloudClientManagerFactory.getDefaultSingleton().
removeClientFor(ocAccount));
// TODO get rid of these exceptions
} catch (AccountNotFoundException e) {
e.printStackTrace();
}
if (client != null) {
OwnCloudCredentials cred = client.getCredentials();
if (cred != null) {
AccountManager am = AccountManager.get(context);
if (cred.authTokenExpires()) {
am.invalidateAuthToken(
getAccount().type,
cred.getAuthToken()
);
} else {
am.clearPassword(getAccount());
}
}
}
requestCredentialsUpdate();
}
}
removeStickyBroadcast(intent);
Log_OC.d(TAG, "Setting progress visibility to " + mSyncInProgress);
setSupportProgressBarIndeterminateVisibility(mSyncInProgress /*|| mRefreshSharesInProgress*/);
}
} catch (RuntimeException e) {
// avoid app crashes after changing the serial id of RemoteOperationResult
// in owncloud library with broadcast notifications pending to process
removeStickyBroadcast(intent);
}
}
}
/**
* Process the result of CopyTmpFileAsyncTask
* @param result
@ -709,9 +899,9 @@ public class Uploader extends FileActivity
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
Log_OC.d(TAG, message);
}
}
/**
/**
* Show waiting for copy dialog
*/
public void showWaitingCopyDialog() {