From: Bartek Przybylski Date: Sun, 27 May 2012 13:57:18 +0000 (+0200) Subject: instant uploading, first attempt X-Git-Tag: oc-android-1.4.3~372 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/9dd2cf294a5bd8427d344833f0098a1ab6800c98?ds=inline instant uploading, first attempt --- diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 47f65c12..718a2d09 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -32,6 +32,7 @@ + - + + + + + + + + \ No newline at end of file diff --git a/res/menu/menu.xml b/res/menu/menu.xml index 5ec8ec0a..38be9b18 100644 --- a/res/menu/menu.xml +++ b/res/menu/menu.xml @@ -6,5 +6,5 @@ - + diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index e17e2848..c38123ce 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -1,34 +1,13 @@ - - - - - - - + diff --git a/src/eu/alefzero/owncloud/files/PhotoTakenBroadcastReceiver.java b/src/eu/alefzero/owncloud/files/PhotoTakenBroadcastReceiver.java new file mode 100644 index 00000000..758413f5 --- /dev/null +++ b/src/eu/alefzero/owncloud/files/PhotoTakenBroadcastReceiver.java @@ -0,0 +1,81 @@ +/* ownCloud Android client application + * Copyright (C) 2012 Bartek Przybylski + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package eu.alefzero.owncloud.files; + +import eu.alefzero.owncloud.AccountUtils; +import eu.alefzero.owncloud.R; +import eu.alefzero.owncloud.files.services.InstantUploadService; +import android.accounts.Account; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.preference.Preference; +import android.preference.PreferenceManager; +import android.provider.MediaStore.Images.Media; +import android.util.Log; + +public class PhotoTakenBroadcastReceiver extends BroadcastReceiver { + + private static String TAG = "PhotoTakenBroadcastReceiver"; + private static final String[] CONTENT_PROJECTION = { Media.DATA, Media.DISPLAY_NAME, Media.MIME_TYPE, Media.SIZE }; + + private static String NEW_PHOTO_ACTION = "com.android.camera.NEW_PICTURE"; + + @Override + public void onReceive(Context context, Intent intent) { + if (!PreferenceManager.getDefaultSharedPreferences(context).getBoolean("instant_uploading", false)) { + Log.d(TAG, "Instant upload disabled, abording uploading"); + return; + } + if (!intent.getAction().equals(NEW_PHOTO_ACTION)) { + Log.e(TAG, "Incorrect intent sent: " + intent.getAction()); + return; + } + Account account = AccountUtils.getCurrentOwnCloudAccount(context); + if (account == null) { + Log.w(TAG, "No owncloud account found for instant upload, abording"); + return; + } + + Cursor c = context.getContentResolver().query(intent.getData(), CONTENT_PROJECTION, null, null, null); + + if (!c.moveToFirst()) { + Log.e(TAG, "Couldn't resolve given uri!"); + return; + } + + String file_path = c.getString(c.getColumnIndex(Media.DATA)); + String file_name = c.getString(c.getColumnIndex(Media.DISPLAY_NAME)); + String mime_type = c.getString(c.getColumnIndex(Media.MIME_TYPE)); + long file_size = c.getLong(c.getColumnIndex(Media.SIZE)); + + c.close(); + + Intent upload_intent = new Intent(context, InstantUploadService.class); + upload_intent.putExtra(InstantUploadService.KEY_ACCOUNT, account); + upload_intent.putExtra(InstantUploadService.KEY_FILE_PATH, file_path); + upload_intent.putExtra(InstantUploadService.KEY_DISPLAY_NAME, file_name); + upload_intent.putExtra(InstantUploadService.KEY_FILE_SIZE, file_size); + upload_intent.putExtra(InstantUploadService.KEY_MIME_TYPE, mime_type); + + context.startService(upload_intent); + } + +} diff --git a/src/eu/alefzero/owncloud/files/services/InstantUploadService.java b/src/eu/alefzero/owncloud/files/services/InstantUploadService.java new file mode 100644 index 00000000..8c8ee31f --- /dev/null +++ b/src/eu/alefzero/owncloud/files/services/InstantUploadService.java @@ -0,0 +1,161 @@ +/* ownCloud Android client application + * Copyright (C) 2012 Bartek Przybylski + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package eu.alefzero.owncloud.files.services; + +import java.io.IOException; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; + +import org.apache.commons.httpclient.HttpException; +import org.apache.jackrabbit.webdav.client.methods.MkColMethod; + +import eu.alefzero.owncloud.AccountUtils; +import eu.alefzero.owncloud.authenticator.AccountAuthenticator; +import eu.alefzero.owncloud.utils.OwnCloudVersion; +import eu.alefzero.webdav.WebdavClient; + +import android.accounts.Account; +import android.accounts.AccountManager; +import android.app.Service; +import android.content.Intent; +import android.net.Uri; +import android.os.IBinder; +import android.util.Log; + +public class InstantUploadService extends Service { + + public static String KEY_FILE_PATH = "KEY_FILEPATH"; + public static String KEY_FILE_SIZE = "KEY_FILESIZE"; + public static String KEY_MIME_TYPE = "KEY_MIMETYPE"; + public static String KEY_DISPLAY_NAME = "KEY_FILENAME"; + public static String KEY_ACCOUNT = "KEY_ACCOUNT"; + + private static String TAG = "InstantUploadService"; + private static String INSTANT_UPLOAD_DIR = "/InstantUpload"; + private UploaderRunnable mUploaderRunnable; + + @Override + public IBinder onBind(Intent arg0) { + return null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + if (intent == null || + !intent.hasExtra(KEY_ACCOUNT) || !intent.hasExtra(KEY_DISPLAY_NAME) || + !intent.hasExtra(KEY_FILE_PATH) || !intent.hasExtra(KEY_FILE_SIZE) || + !intent.hasExtra(KEY_MIME_TYPE)) { + Log.w(TAG, "Not all required information was provided, abording"); + return Service.START_NOT_STICKY; + } + + if (mUploaderRunnable == null) { + mUploaderRunnable = new UploaderRunnable(); + } + + String filename = intent.getStringExtra(KEY_DISPLAY_NAME); + String filepath = intent.getStringExtra(KEY_FILE_PATH); + String mimetype = intent.getStringExtra(KEY_MIME_TYPE); + Account account = intent.getParcelableExtra(KEY_ACCOUNT); + long filesize = intent.getLongExtra(KEY_FILE_SIZE, -1); + + mUploaderRunnable.addElementToQueue(filename, filepath, mimetype, filesize, account); + + // starting new thread for new download doesnt seems like a good idea + // maybe some thread pool or single background thread would be better + Log.d(TAG, "Starting instant upload thread"); + new Thread(mUploaderRunnable).start(); + + return Service.START_STICKY; + } + + private class UploaderRunnable implements Runnable { + + Object mLock; + List> mHashMapList; + + public UploaderRunnable() { + mHashMapList = new LinkedList>(); + mLock = new Object(); + } + + public void addElementToQueue(String filename, + String filepath, + String mimetype, + long length, + Account account) { + HashMap new_map = new HashMap(); + new_map.put(KEY_ACCOUNT, account); + new_map.put(KEY_DISPLAY_NAME, filename); + new_map.put(KEY_FILE_PATH, filepath); + new_map.put(KEY_MIME_TYPE, mimetype); + new_map.put(KEY_FILE_SIZE, length); + + synchronized (mLock) { + mHashMapList.add(new_map); + } + } + + private HashMap getFirstObject() { + synchronized (mLock) { + if (mHashMapList.size() == 0) + return null; + HashMap ret = mHashMapList.get(0); + mHashMapList.remove(0); + return ret; + } + } + + public void run() { + HashMap working_map; + AccountManager am = AccountManager.get(getApplicationContext()); + + while ((working_map = getFirstObject()) != null) { + Account account = (Account) working_map.get(KEY_ACCOUNT); + String username = account.name.substring(0, account.name.lastIndexOf('@')); + String password = am.getPassword(account); + String filename = (String) working_map.get(KEY_DISPLAY_NAME); + String filepath = (String) working_map.get(KEY_FILE_PATH); + String mimetype = (String) working_map.get(KEY_MIME_TYPE); + + String oc_base_url = am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL); + String oc_version = am.getUserData(account, AccountAuthenticator.KEY_OC_VERSION); + OwnCloudVersion ocv = new OwnCloudVersion(oc_version); + String webdav_path = AccountUtils.getWebdavPath(ocv); + WebdavClient wdc = new WebdavClient(Uri.parse(oc_base_url + webdav_path)); + wdc.allowSelfsignedCertificates(); + wdc.setCredentials(username, password); + + MkColMethod mkcol = new MkColMethod(oc_base_url+webdav_path+INSTANT_UPLOAD_DIR); + int status = 0; + try { + status = wdc.executeMethod(mkcol); + Log.e(TAG, "mkcol returned " + status); + wdc.putFile(filepath, INSTANT_UPLOAD_DIR + "/" + filename, mimetype); + } catch (HttpException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + +} diff --git a/src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java b/src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java index dc564d6f..c0a84bbc 100644 --- a/src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java +++ b/src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java @@ -134,9 +134,9 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements ACTION_SELECT_FILE); break; } - case R.id.action_accounts: { - Intent accountIntent = new Intent(this, AccountSelectActivity.class); - startActivity(accountIntent); + case R.id.action_settings: { + Intent settingsIntent = new Intent(this, Preferences.class); + startActivity(settingsIntent); } case android.R.id.home: { if(mCurrentDir != null && mCurrentDir.getParentId() != 0){ diff --git a/src/eu/alefzero/owncloud/ui/activity/Preferences.java b/src/eu/alefzero/owncloud/ui/activity/Preferences.java index 0c17d7cb..01a21ec6 100644 --- a/src/eu/alefzero/owncloud/ui/activity/Preferences.java +++ b/src/eu/alefzero/owncloud/ui/activity/Preferences.java @@ -78,21 +78,6 @@ public class Preferences extends SherlockPreferenceActivity implements populateAccountList(); ActionBar actionBar = getSherlock().getActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); - - // Update summary for device tracking preference - mTrackingUpdateInterval = (ListPreference) findPreference("devicetracking_update_intervall"); - String trackingSummary = getResources().getString( - R.string.prefs_trackmydevice_interval_summary); - trackingSummary = String.format(trackingSummary, - mTrackingUpdateInterval.getValue()); - mTrackingUpdateInterval.setSummary(trackingSummary); - mTrackingUpdateInterval.setOnPreferenceChangeListener(this); - - // Enable or disable device tracking service. Listen on events - mDeviceTracking = (CheckBoxPreference) findPreference("enable_devicetracking"); - mDeviceTracking.setOnPreferenceChangeListener(this); - - // populateSessionList(); } private void populateSessionList() { @@ -131,7 +116,7 @@ public class Preferences extends SherlockPreferenceActivity implements if (defaultAccount != null) { mAccountList.setSummary(defaultAccount.name); } - + // Transform accounts into array of string for preferences to use String[] accNames = new String[mAccounts.length]; for (int i = 0; i < mAccounts.length; i++) { @@ -180,7 +165,7 @@ public class Preferences extends SherlockPreferenceActivity implements getPreferenceScreen().getPreference(mSelectedMenuItem + 1)); break; case android.R.id.home: - intent = new Intent(getBaseContext(), LandingActivity.class); + intent = new Intent(getBaseContext(), FileDisplayActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); break;