mirror of
https://github.com/nextcloud/android.git
synced 2024-11-23 13:45:35 +03:00
Enable auto upload for all
Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
parent
2b313b92f8
commit
378c46f0ec
7 changed files with 77 additions and 562 deletions
|
@ -226,32 +226,7 @@
|
|||
<activity android:name=".ui.activity.UploadListActivity" />
|
||||
<activity android:name=".ui.activity.WhatsNewActivity"
|
||||
android:theme="@style/Theme.ownCloud.noActionBar.Login" />
|
||||
|
||||
<receiver android:name=".files.services.ConnectivityActionReceiver"
|
||||
android:enabled="true" android:label="ConnectivityActionReceiver">
|
||||
<intent-filter>
|
||||
<!--action android:name="android.net.conn.CONNECTIVITY_CHANGE"/-->
|
||||
<action android:name="android.net.wifi.STATE_CHANGE"/>
|
||||
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
|
||||
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".files.InstantUploadBroadcastReceiver">
|
||||
<intent-filter>
|
||||
|
||||
<!-- unofficially supported by many Android phones but not by HTC devices: -->
|
||||
<action android:name="com.android.camera.NEW_PICTURE" />
|
||||
<!-- officially supported since Android 4.0 (SDK 14, works even for HTC devices): -->
|
||||
<action android:name="android.hardware.action.NEW_PICTURE" />
|
||||
|
||||
<data android:mimeType="image/*" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.hardware.action.NEW_VIDEO" />
|
||||
|
||||
<data android:mimeType="video/*" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".files.BootupBroadcastReceiver" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
/**
|
||||
* ownCloud Android client application
|
||||
* ownCloud Android client application
|
||||
*
|
||||
* @author LukeOwncloud
|
||||
* @author David A. Velasco
|
||||
* @author masensio
|
||||
* Copyright (C) 2016 ownCloud Inc.
|
||||
* @author LukeOwncloud
|
||||
* @author David A. Velasco
|
||||
* @author masensio
|
||||
* Copyright (C) 2016 ownCloud Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2,
|
||||
* as published by the Free Software Foundation.
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.owncloud.android.datamodel;
|
||||
|
||||
|
@ -26,8 +26,6 @@ import android.content.ContentValues;
|
|||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.RequiresApi;
|
||||
|
||||
import com.evernote.android.job.JobManager;
|
||||
import com.evernote.android.job.JobRequest;
|
||||
|
@ -163,9 +161,9 @@ public class UploadsStorageManager extends Observable {
|
|||
cv.put(ProviderTableMeta.UPLOADS_UPLOAD_END_TIMESTAMP, ocUpload.getUploadEndTimestamp());
|
||||
|
||||
int result = getDB().update(ProviderTableMeta.CONTENT_URI_UPLOADS,
|
||||
cv,
|
||||
ProviderTableMeta._ID + "=?",
|
||||
new String[]{String.valueOf(ocUpload.getUploadId())}
|
||||
cv,
|
||||
ProviderTableMeta._ID + "=?",
|
||||
new String[]{String.valueOf(ocUpload.getUploadId())}
|
||||
);
|
||||
|
||||
Log_OC.d(TAG, "updateUpload returns with: " + result + " for file: " + ocUpload.getLocalPath());
|
||||
|
@ -188,15 +186,15 @@ public class UploadsStorageManager extends Observable {
|
|||
|
||||
String path = c.getString(c.getColumnIndex(ProviderTableMeta.UPLOADS_LOCAL_PATH));
|
||||
Log_OC.v(
|
||||
TAG,
|
||||
"Updating " + path + " with status:" + status + " and result:"
|
||||
+ (result == null ? "null" : result.toString()) + " (old:"
|
||||
+ upload.toFormattedString() + ")");
|
||||
TAG,
|
||||
"Updating " + path + " with status:" + status + " and result:"
|
||||
+ (result == null ? "null" : result.toString()) + " (old:"
|
||||
+ upload.toFormattedString() + ")");
|
||||
|
||||
upload.setUploadStatus(status);
|
||||
upload.setLastResult(result);
|
||||
upload.setRemotePath(remotePath);
|
||||
if(localPath != null) {
|
||||
if (localPath != null) {
|
||||
upload.setLocalPath(localPath);
|
||||
}
|
||||
if (status == UploadStatus.UPLOAD_SUCCEEDED) {
|
||||
|
@ -236,7 +234,7 @@ public class UploadsStorageManager extends Observable {
|
|||
|
||||
if (c.getCount() != 1) {
|
||||
Log_OC.e(TAG, c.getCount() + " items for id=" + id
|
||||
+ " available in UploadDb. Expected 1. Failed to update upload db.");
|
||||
+ " available in UploadDb. Expected 1. Failed to update upload db.");
|
||||
} else {
|
||||
returnValue = updateUploadInternal(c, status, result, remotePath, localPath);
|
||||
}
|
||||
|
@ -266,7 +264,7 @@ public class UploadsStorageManager extends Observable {
|
|||
public int removeUpload(OCUpload upload) {
|
||||
int result = getDB().delete(
|
||||
ProviderTableMeta.CONTENT_URI_UPLOADS,
|
||||
ProviderTableMeta._ID + "=?" ,
|
||||
ProviderTableMeta._ID + "=?",
|
||||
new String[]{Long.toString(upload.getUploadId())}
|
||||
);
|
||||
Log_OC.d(TAG, "delete returns " + result + " for upload " + upload);
|
||||
|
@ -287,7 +285,7 @@ public class UploadsStorageManager extends Observable {
|
|||
public int removeUpload(String accountName, String remotePath) {
|
||||
int result = getDB().delete(
|
||||
ProviderTableMeta.CONTENT_URI_UPLOADS,
|
||||
ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "=? AND " + ProviderTableMeta.UPLOADS_REMOTE_PATH + "=?" ,
|
||||
ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "=? AND " + ProviderTableMeta.UPLOADS_REMOTE_PATH + "=?",
|
||||
new String[]{accountName, remotePath}
|
||||
);
|
||||
Log_OC.d(TAG, "delete returns " + result + " for file " + remotePath + " in " + accountName);
|
||||
|
@ -379,6 +377,7 @@ public class UploadsStorageManager extends Observable {
|
|||
*/
|
||||
public OCUpload[] getCurrentAndPendingUploads() {
|
||||
|
||||
|
||||
OCUpload[] uploads = getUploads(
|
||||
ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_IN_PROGRESS.value + " OR " +
|
||||
ProviderTableMeta.UPLOADS_LAST_RESULT + "==" + UploadResult.DELAYED_FOR_WIFI.getValue() + " OR " +
|
||||
|
@ -386,17 +385,13 @@ public class UploadsStorageManager extends Observable {
|
|||
null
|
||||
);
|
||||
|
||||
// add pending Jobs
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
return uploads;
|
||||
} else {
|
||||
List<OCUpload> result = getPendingJobs();
|
||||
Collections.addAll(result, uploads);
|
||||
return result.toArray(uploads);
|
||||
}
|
||||
//return uploads;
|
||||
|
||||
List<OCUpload> result = getPendingJobs();
|
||||
Collections.addAll(result, uploads);
|
||||
return result.toArray(uploads);
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
private List<OCUpload> getPendingJobs() {
|
||||
Set<JobRequest> jobRequests = JobManager.create(mContext).getAllJobRequestsForTag(AutoUploadJob.TAG);
|
||||
|
||||
|
@ -404,11 +399,11 @@ public class UploadsStorageManager extends Observable {
|
|||
|
||||
for (JobRequest ji : jobRequests) {
|
||||
PersistableBundleCompat extras = ji.getExtras();
|
||||
OCUpload upload = new OCUpload(extras.getString("filePath", ""),
|
||||
extras.getString("remotePath", ""),
|
||||
extras.getString("account", ""));
|
||||
OCUpload upload = new OCUpload(extras.getString("filePath", ""),
|
||||
extras.getString("remotePath", ""),
|
||||
extras.getString("account", ""));
|
||||
|
||||
list.add(upload);
|
||||
list.add(upload);
|
||||
}
|
||||
|
||||
return list;
|
||||
|
@ -416,15 +411,14 @@ public class UploadsStorageManager extends Observable {
|
|||
|
||||
public void cancelPendingAutoUploadJobsForAccount(Account account) {
|
||||
JobManager jobManager = JobManager.create(mContext);
|
||||
for (JobRequest ji: jobManager.getAllJobRequestsForTag(AutoUploadJob.TAG)) {
|
||||
for (JobRequest ji : jobManager.getAllJobRequestsForTag(AutoUploadJob.TAG)) {
|
||||
if (ji.getExtras().getString(AutoUploadJob.ACCOUNT, "").equalsIgnoreCase(account.name)) {
|
||||
jobManager.cancel(ji.getJobId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public void cancelPendingJob(String accountName, String remotePath){
|
||||
public void cancelPendingJob(String accountName, String remotePath) {
|
||||
JobManager jobManager = JobManager.create(mContext);
|
||||
Set<JobRequest> jobRequests = jobManager.getAllJobRequests();
|
||||
|
||||
|
@ -457,14 +451,14 @@ public class UploadsStorageManager extends Observable {
|
|||
|
||||
/**
|
||||
* Get all failed uploads, except for those that were not performed due to lack of Wifi connection
|
||||
* @return Array of failed uploads, except for those that were not performed due to lack of Wifi connection.
|
||||
* @return Array of failed uploads, except for those that were not performed due to lack of Wifi connection.
|
||||
*/
|
||||
public OCUpload[] getFailedButNotDelayedUploads() {
|
||||
|
||||
return getUploads(ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_FAILED.value + AND +
|
||||
ProviderTableMeta.UPLOADS_LAST_RESULT + "<>" + UploadResult.DELAYED_FOR_WIFI.getValue() + AND +
|
||||
ProviderTableMeta.UPLOADS_LAST_RESULT + "<>" + UploadResult.DELAYED_FOR_CHARGING.getValue(),
|
||||
null
|
||||
ProviderTableMeta.UPLOADS_LAST_RESULT + "<>" + UploadResult.DELAYED_FOR_WIFI.getValue() + AND +
|
||||
ProviderTableMeta.UPLOADS_LAST_RESULT + "<>" + UploadResult.DELAYED_FOR_CHARGING.getValue(),
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -474,11 +468,11 @@ public class UploadsStorageManager extends Observable {
|
|||
|
||||
public long clearFailedButNotDelayedUploads() {
|
||||
long result = getDB().delete(
|
||||
ProviderTableMeta.CONTENT_URI_UPLOADS,
|
||||
ProviderTableMeta.CONTENT_URI_UPLOADS,
|
||||
ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_FAILED.value + AND +
|
||||
ProviderTableMeta.UPLOADS_LAST_RESULT + "<>" + UploadResult.DELAYED_FOR_WIFI.getValue() + AND +
|
||||
ProviderTableMeta.UPLOADS_LAST_RESULT + "<>" + UploadResult.DELAYED_FOR_CHARGING.getValue(),
|
||||
null
|
||||
ProviderTableMeta.UPLOADS_LAST_RESULT + "<>" + UploadResult.DELAYED_FOR_WIFI.getValue() + AND +
|
||||
ProviderTableMeta.UPLOADS_LAST_RESULT + "<>" + UploadResult.DELAYED_FOR_CHARGING.getValue(),
|
||||
null
|
||||
);
|
||||
Log_OC.d(TAG, "delete all failed uploads but those delayed for Wifi");
|
||||
if (result > 0) {
|
||||
|
@ -491,7 +485,7 @@ public class UploadsStorageManager extends Observable {
|
|||
|
||||
long result = getDB().delete(
|
||||
ProviderTableMeta.CONTENT_URI_UPLOADS,
|
||||
ProviderTableMeta.UPLOADS_STATUS + "=="+ UploadStatus.UPLOAD_SUCCEEDED.value, null
|
||||
ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_SUCCEEDED.value, null
|
||||
);
|
||||
Log_OC.d(TAG, "delete all successful uploads");
|
||||
if (result > 0) {
|
||||
|
@ -508,8 +502,8 @@ public class UploadsStorageManager extends Observable {
|
|||
long result = getDB().delete(
|
||||
ProviderTableMeta.CONTENT_URI_UPLOADS,
|
||||
ProviderTableMeta.UPLOADS_STATUS + "=? OR " + ProviderTableMeta.UPLOADS_STATUS + "=? AND " +
|
||||
ProviderTableMeta.UPLOADS_LAST_RESULT + "<>" + UploadResult.DELAYED_FOR_WIFI.getValue() + AND +
|
||||
ProviderTableMeta.UPLOADS_LAST_RESULT + "<>" + UploadResult.DELAYED_FOR_CHARGING.getValue(),
|
||||
ProviderTableMeta.UPLOADS_LAST_RESULT + "<>" + UploadResult.DELAYED_FOR_WIFI.getValue() + AND +
|
||||
ProviderTableMeta.UPLOADS_LAST_RESULT + "<>" + UploadResult.DELAYED_FOR_CHARGING.getValue(),
|
||||
whereArgs
|
||||
);
|
||||
Log_OC.d(TAG, "delete all finished uploads");
|
||||
|
@ -528,28 +522,28 @@ public class UploadsStorageManager extends Observable {
|
|||
|
||||
if (uploadResult.isCancelled()) {
|
||||
removeUpload(
|
||||
upload.getAccount().name,
|
||||
upload.getRemotePath()
|
||||
upload.getAccount().name,
|
||||
upload.getRemotePath()
|
||||
);
|
||||
} else {
|
||||
String localPath = (FileUploader.LOCAL_BEHAVIOUR_MOVE == upload.getLocalBehaviour())
|
||||
? upload.getStoragePath() : null;
|
||||
? upload.getStoragePath() : null;
|
||||
|
||||
if (uploadResult.isSuccess()) {
|
||||
updateUploadStatus(
|
||||
upload.getOCUploadId(),
|
||||
UploadStatus.UPLOAD_SUCCEEDED,
|
||||
UploadResult.UPLOADED,
|
||||
upload.getRemotePath(),
|
||||
localPath
|
||||
upload.getOCUploadId(),
|
||||
UploadStatus.UPLOAD_SUCCEEDED,
|
||||
UploadResult.UPLOADED,
|
||||
upload.getRemotePath(),
|
||||
localPath
|
||||
);
|
||||
} else {
|
||||
updateUploadStatus(
|
||||
upload.getOCUploadId(),
|
||||
UploadStatus.UPLOAD_FAILED,
|
||||
UploadResult.fromOperationResult(uploadResult),
|
||||
upload.getRemotePath(),
|
||||
localPath
|
||||
upload.getOCUploadId(),
|
||||
UploadStatus.UPLOAD_FAILED,
|
||||
UploadResult.fromOperationResult(uploadResult),
|
||||
upload.getRemotePath(),
|
||||
localPath
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -560,14 +554,14 @@ public class UploadsStorageManager extends Observable {
|
|||
*/
|
||||
public void updateDatabaseUploadStart(UploadFileOperation upload) {
|
||||
String localPath = (FileUploader.LOCAL_BEHAVIOUR_MOVE == upload.getLocalBehaviour())
|
||||
? upload.getStoragePath() : null;
|
||||
? upload.getStoragePath() : null;
|
||||
|
||||
updateUploadStatus(
|
||||
upload.getOCUploadId(),
|
||||
UploadStatus.UPLOAD_IN_PROGRESS,
|
||||
UploadResult.UNKNOWN,
|
||||
upload.getRemotePath(),
|
||||
localPath
|
||||
upload.getOCUploadId(),
|
||||
UploadStatus.UPLOAD_IN_PROGRESS,
|
||||
UploadResult.UNKNOWN,
|
||||
upload.getRemotePath(),
|
||||
localPath
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -576,7 +570,7 @@ public class UploadsStorageManager extends Observable {
|
|||
* Changes the status of any in progress upload from UploadStatus.UPLOAD_IN_PROGRESS
|
||||
* to UploadStatus.UPLOAD_FAILED
|
||||
*
|
||||
* @return Number of uploads which status was changed.
|
||||
* @return Number of uploads which status was changed.
|
||||
*/
|
||||
public int failInProgressUploads(UploadResult fail) {
|
||||
Log_OC.v(TAG, "Updating state of any killed upload");
|
||||
|
@ -584,16 +578,16 @@ public class UploadsStorageManager extends Observable {
|
|||
ContentValues cv = new ContentValues();
|
||||
cv.put(ProviderTableMeta.UPLOADS_STATUS, UploadStatus.UPLOAD_FAILED.getValue());
|
||||
cv.put(
|
||||
ProviderTableMeta.UPLOADS_LAST_RESULT,
|
||||
fail != null ? fail.getValue() : UploadResult.UNKNOWN.getValue()
|
||||
ProviderTableMeta.UPLOADS_LAST_RESULT,
|
||||
fail != null ? fail.getValue() : UploadResult.UNKNOWN.getValue()
|
||||
);
|
||||
cv.put(ProviderTableMeta.UPLOADS_UPLOAD_END_TIMESTAMP, Calendar.getInstance().getTimeInMillis());
|
||||
|
||||
int result = getDB().update(
|
||||
ProviderTableMeta.CONTENT_URI_UPLOADS,
|
||||
cv,
|
||||
ProviderTableMeta.UPLOADS_STATUS + "=?",
|
||||
new String[]{String.valueOf(UploadStatus.UPLOAD_IN_PROGRESS.getValue())}
|
||||
ProviderTableMeta.CONTENT_URI_UPLOADS,
|
||||
cv,
|
||||
ProviderTableMeta.UPLOADS_STATUS + "=?",
|
||||
new String[]{String.valueOf(UploadStatus.UPLOAD_IN_PROGRESS.getValue())}
|
||||
);
|
||||
|
||||
if (result == 0) {
|
||||
|
|
|
@ -1,223 +0,0 @@
|
|||
/**
|
||||
* ownCloud Android client application
|
||||
*
|
||||
* @author Bartek Przybylski
|
||||
* @author David A. Velasco
|
||||
* Copyright (C) 2012 Bartek Przybylski
|
||||
* Copyright (C) 2016 ownCloud Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.owncloud.android.files;
|
||||
|
||||
import android.Manifest;
|
||||
import android.accounts.Account;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.os.Build;
|
||||
import android.provider.MediaStore.Images;
|
||||
import android.provider.MediaStore.Video;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.authentication.AccountUtils;
|
||||
import com.owncloud.android.db.PreferenceManager;
|
||||
import com.owncloud.android.files.services.FileUploader;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.operations.UploadFileOperation;
|
||||
import com.owncloud.android.utils.FileStorageUtils;
|
||||
|
||||
|
||||
public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
|
||||
|
||||
private static final String TAG = InstantUploadBroadcastReceiver.class.getName();
|
||||
// Image action
|
||||
// Unofficial action, works for most devices but not HTC. See: https://github.com/owncloud/android/issues/6
|
||||
private static final String NEW_PHOTO_ACTION_UNOFFICIAL = "com.android.camera.NEW_PICTURE";
|
||||
// Officially supported action since SDK 14:
|
||||
// http://developer.android.com/reference/android/hardware/Camera.html#ACTION_NEW_PICTURE
|
||||
private static final String NEW_PHOTO_ACTION = "android.hardware.action.NEW_PICTURE";
|
||||
// Video action
|
||||
// Officially supported action since SDK 14:
|
||||
// http://developer.android.com/reference/android/hardware/Camera.html#ACTION_NEW_VIDEO
|
||||
private static final String NEW_VIDEO_ACTION = "android.hardware.action.NEW_VIDEO";
|
||||
|
||||
/**
|
||||
* Because we support NEW_PHOTO_ACTION and NEW_PHOTO_ACTION_UNOFFICIAL it can happen that
|
||||
* handleNewPictureAction is called twice for the same photo. Use this simple static variable to
|
||||
* remember last uploaded photo to filter duplicates. Must not be null!
|
||||
*/
|
||||
static String lastUploadedPhotoPath = "";
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||
Log_OC.d(TAG, "Received: " + intent.getAction());
|
||||
if (intent.getAction().equals(NEW_PHOTO_ACTION_UNOFFICIAL)) {
|
||||
handleNewPictureAction(context, intent);
|
||||
Log_OC.d(TAG, "UNOFFICIAL processed: com.android.camera.NEW_PICTURE");
|
||||
} else if (intent.getAction().equals(NEW_PHOTO_ACTION)) {
|
||||
handleNewPictureAction(context, intent);
|
||||
Log_OC.d(TAG, "OFFICIAL processed: android.hardware.action.NEW_PICTURE");
|
||||
} else if (intent.getAction().equals(NEW_VIDEO_ACTION)) {
|
||||
handleNewVideoAction(context, intent);
|
||||
Log_OC.d(TAG, "OFFICIAL processed: android.hardware.action.NEW_VIDEO");
|
||||
} else {
|
||||
Log_OC.e(TAG, "Incorrect intent received: " + intent.getAction());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleNewPictureAction(Context context, Intent intent) {
|
||||
Cursor c = null;
|
||||
String file_path = null;
|
||||
String file_name = null;
|
||||
String mime_type = null;
|
||||
long date_taken = 0;
|
||||
|
||||
Log_OC.i(TAG, "New photo received");
|
||||
|
||||
if (!PreferenceManager.instantPictureUploadEnabled(context)) {
|
||||
Log_OC.d(TAG, "Instant picture upload disabled, ignoring new picture");
|
||||
return;
|
||||
}
|
||||
|
||||
Account account = AccountUtils.getCurrentOwnCloudAccount(context);
|
||||
if (account == null) {
|
||||
Log_OC.w(TAG, "No account found for instant upload, aborting");
|
||||
return;
|
||||
}
|
||||
|
||||
String[] CONTENT_PROJECTION = {
|
||||
Images.Media.DATA, Images.Media.DISPLAY_NAME, Images.Media.MIME_TYPE, Images.Media.SIZE};
|
||||
|
||||
// if < Jelly Bean permission must be accepted during installation
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
|
||||
int permissionCheck = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE);
|
||||
|
||||
if (android.content.pm.PackageManager.PERMISSION_GRANTED != permissionCheck) {
|
||||
Log_OC.w(TAG, "Read external storage permission isn't granted, aborting");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
c = context.getContentResolver().query(intent.getData(), CONTENT_PROJECTION, null, null, null);
|
||||
if (!c.moveToFirst()) {
|
||||
Log_OC.e(TAG, "Couldn't resolve given uri: " + intent.getDataString());
|
||||
return;
|
||||
}
|
||||
file_path = c.getString(c.getColumnIndex(Images.Media.DATA));
|
||||
file_name = c.getString(c.getColumnIndex(Images.Media.DISPLAY_NAME));
|
||||
mime_type = c.getString(c.getColumnIndex(Images.Media.MIME_TYPE));
|
||||
date_taken = System.currentTimeMillis();
|
||||
c.close();
|
||||
|
||||
if (file_path.equals(lastUploadedPhotoPath)) {
|
||||
Log_OC.d(TAG, "Duplicate detected: " + file_path + ". Ignore.");
|
||||
return;
|
||||
}
|
||||
|
||||
lastUploadedPhotoPath = file_path;
|
||||
Log_OC.d(TAG, "Path: " + file_path + "");
|
||||
|
||||
new FileUploader.UploadRequester();
|
||||
|
||||
int behaviour = getUploadBehaviour(context);
|
||||
Boolean subfolderByDate = PreferenceManager.instantPictureUploadPathUseSubfolders(context);
|
||||
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String uploadPathdef = context.getString(R.string.instant_upload_path);
|
||||
String uploadPath = pref.getString("instant_upload_path", uploadPathdef);
|
||||
|
||||
FileUploader.UploadRequester requester = new FileUploader.UploadRequester();
|
||||
requester.uploadNewFile(
|
||||
context,
|
||||
account,
|
||||
file_path,
|
||||
FileStorageUtils.getInstantUploadFilePath(uploadPath, file_name, date_taken, subfolderByDate),
|
||||
behaviour,
|
||||
mime_type,
|
||||
true, // create parent folder if not existent
|
||||
UploadFileOperation.CREATED_AS_INSTANT_PICTURE
|
||||
);
|
||||
}
|
||||
|
||||
private Integer getUploadBehaviour(Context context) {
|
||||
SharedPreferences appPreferences = android.preference.PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String behaviour = appPreferences.getString("prefs_instant_behaviour", "NOTHING");
|
||||
|
||||
if (behaviour.equalsIgnoreCase("NOTHING")) {
|
||||
Log_OC.d(TAG, "upload file and do nothing");
|
||||
return FileUploader.LOCAL_BEHAVIOUR_FORGET;
|
||||
} else if (behaviour.equalsIgnoreCase("MOVE")) {
|
||||
Log_OC.d(TAG, "upload file and move file to oc folder");
|
||||
return FileUploader.LOCAL_BEHAVIOUR_MOVE;
|
||||
} else if (behaviour.equalsIgnoreCase("DELETE")) {
|
||||
Log_OC.d(TAG, "upload file and delete original file");
|
||||
return FileUploader.LOCAL_BEHAVIOUR_DELETE;
|
||||
}
|
||||
return FileUploader.LOCAL_BEHAVIOUR_FORGET;
|
||||
}
|
||||
|
||||
private void handleNewVideoAction(Context context, Intent intent) {
|
||||
Cursor c = null;
|
||||
String file_path = null;
|
||||
String file_name = null;
|
||||
String mime_type = null;
|
||||
long date_taken = 0;
|
||||
|
||||
Log_OC.i(TAG, "New video received");
|
||||
|
||||
if (!PreferenceManager.instantVideoUploadEnabled(context)) {
|
||||
Log_OC.d(TAG, "Instant video upload disabled, ignoring new video");
|
||||
return;
|
||||
}
|
||||
|
||||
Account account = AccountUtils.getCurrentOwnCloudAccount(context);
|
||||
if (account == null) {
|
||||
Log_OC.w(TAG, "No account found for instant upload, aborting");
|
||||
return;
|
||||
}
|
||||
|
||||
String[] CONTENT_PROJECTION = {Video.Media.DATA, Video.Media.DISPLAY_NAME, Video.Media.MIME_TYPE,
|
||||
Video.Media.SIZE};
|
||||
c = context.getContentResolver().query(intent.getData(), CONTENT_PROJECTION, null, null, null);
|
||||
if (!c.moveToFirst()) {
|
||||
Log_OC.e(TAG, "Couldn't resolve given uri: " + intent.getDataString());
|
||||
return;
|
||||
}
|
||||
file_path = c.getString(c.getColumnIndex(Video.Media.DATA));
|
||||
file_name = c.getString(c.getColumnIndex(Video.Media.DISPLAY_NAME));
|
||||
mime_type = c.getString(c.getColumnIndex(Video.Media.MIME_TYPE));
|
||||
c.close();
|
||||
date_taken = System.currentTimeMillis();
|
||||
Log_OC.d(TAG, file_path + "");
|
||||
|
||||
int behaviour = getUploadBehaviour(context);
|
||||
FileUploader.UploadRequester requester = new FileUploader.UploadRequester();
|
||||
requester.uploadNewFile(
|
||||
context,
|
||||
account,
|
||||
file_path,
|
||||
FileStorageUtils.getInstantVideoUploadFilePath(context, file_name, date_taken),
|
||||
behaviour,
|
||||
mime_type,
|
||||
true, // create parent folder if not existent
|
||||
UploadFileOperation.CREATED_AS_INSTANT_VIDEO
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,223 +0,0 @@
|
|||
/**
|
||||
* ownCloud Android client application
|
||||
*
|
||||
* @author LukeOwncloud
|
||||
* Copyright (C) 2016 ownCloud Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.owncloud.android.files.services;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.owncloud.android.db.PreferenceManager;
|
||||
import com.owncloud.android.db.UploadResult;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
/**
|
||||
* Receives all connectivity action from Android OS at all times and performs
|
||||
* required OC actions. For now that are: - Signal connectivity to
|
||||
* {@link FileUploader}.
|
||||
*
|
||||
* Later can be added: - Signal connectivity to download service, deletion
|
||||
* service, ... - Handle offline mode (cf.
|
||||
* https://github.com/owncloud/android/issues/162)
|
||||
*
|
||||
* Have fun with the comments :S
|
||||
*/
|
||||
public class ConnectivityActionReceiver extends BroadcastReceiver {
|
||||
private static final String TAG = ConnectivityActionReceiver.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* Magic keyword, by Google.
|
||||
*
|
||||
* {@see http://developer.android.com/intl/es/reference/android/net/wifi/WifiInfo.html#getSSID()}
|
||||
*/
|
||||
private static final String UNKNOWN_SSID = "<unknown ssid>";
|
||||
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, Intent intent) {
|
||||
// LOG ALL EVENTS:
|
||||
Log_OC.v(TAG, "action: " + intent.getAction());
|
||||
Log_OC.v(TAG, "component: " + intent.getComponent());
|
||||
Bundle extras = intent.getExtras();
|
||||
if (extras != null) {
|
||||
for (String key : extras.keySet()) {
|
||||
Log_OC.v(TAG, "key [" + key + "]: " + extras.get(key));
|
||||
}
|
||||
} else {
|
||||
Log_OC.v(TAG, "no extras");
|
||||
}
|
||||
|
||||
if (intent.getAction().equals(Intent.ACTION_POWER_CONNECTED) &&
|
||||
(PreferenceManager.instantPictureUploadEnabled(context) &&
|
||||
PreferenceManager.instantPictureUploadWhenChargingOnly(context)) ||
|
||||
(PreferenceManager.instantVideoUploadEnabled(context) &&
|
||||
PreferenceManager.instantVideoUploadWhenChargingOnly(context))
|
||||
) {
|
||||
// for the moment, only recovery of instant uploads, similar to behaviour in release 1.9.1
|
||||
Log_OC.d(TAG, "Requesting retry of instant uploads (& friends) due to charging");
|
||||
FileUploader.UploadRequester requester = new FileUploader.UploadRequester();
|
||||
requester.retryFailedUploads(
|
||||
context,
|
||||
null,
|
||||
UploadResult.DELAYED_FOR_CHARGING // for the rest of enqueued when Wifi fell
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* There is an interesting mess to process WifiManager.NETWORK_STATE_CHANGED_ACTION and
|
||||
* ConnectivityManager.CONNECTIVITY_ACTION in a simple and reliable way.
|
||||
*
|
||||
* The former triggers much more events than what we really need to know about Wifi connection.
|
||||
*
|
||||
* But there are annoying uncertainties about ConnectivityManager.CONNECTIVITY_ACTION due
|
||||
* to the deprecation of ConnectivityManager.EXTRA_NETWORK_INFO in API level 14, and the absence
|
||||
* of ConnectivityManager.EXTRA_NETWORK_TYPE until API level 17. Dear Google, how should we
|
||||
* handle API levels 14 to 16?
|
||||
*
|
||||
* In the end maybe we need to keep in memory the current knowledge about connectivity
|
||||
* and update it taking into account several Intents received in a row
|
||||
*
|
||||
* But first let's try something "simple" to keep a basic retry of instant uploads in
|
||||
* version 1.9.2, similar to the existent until 1.9.1. To be improved.
|
||||
*/
|
||||
if(intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
|
||||
NetworkInfo networkInfo =
|
||||
intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
|
||||
WifiInfo wifiInfo =
|
||||
intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
|
||||
String bssid =
|
||||
intent.getStringExtra(WifiManager.EXTRA_BSSID);
|
||||
if(networkInfo.isConnected() && // not enough; see (*) right below
|
||||
wifiInfo != null &&
|
||||
!UNKNOWN_SSID.equals(wifiInfo.getSSID().toLowerCase()) &&
|
||||
bssid != null
|
||||
) {
|
||||
Log_OC.d(TAG, "WiFi connected");
|
||||
|
||||
wifiConnected(context);
|
||||
} else {
|
||||
// TODO tons of things to check to conclude disconnection;
|
||||
// TODO maybe alternative commented below, based on CONNECTIVITY_ACTION is better
|
||||
Log_OC.d(TAG, "WiFi disconnected ... but don't know if right now");
|
||||
}
|
||||
}
|
||||
// (*) When WiFi is lost, an Intent with network state CONNECTED and SSID "<unknown ssid>" is
|
||||
// received right before another Intent with network state DISCONNECTED; needs to
|
||||
// be differentiated of a new Wifi connection.
|
||||
//
|
||||
// Besides, with a new connection two Intents are received, having only the second the extra
|
||||
// WifiManager.EXTRA_BSSID, with the BSSID of the access point accessed.
|
||||
//
|
||||
// Not sure if this protocol is exact, since it's not documented. Only found mild references in
|
||||
// - http://developer.android.com/intl/es/reference/android/net/wifi/WifiInfo.html#getSSID()
|
||||
// - http://developer.android.com/intl/es/reference/android/net/wifi/WifiManager.html#EXTRA_BSSID
|
||||
// and reproduced in Nexus 5 with Android 6.
|
||||
|
||||
|
||||
/**
|
||||
* Possible alternative attending ConnectivityManager.CONNECTIVITY_ACTION.
|
||||
*
|
||||
* Let's see what QA has to say
|
||||
*
|
||||
if(intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
|
||||
NetworkInfo networkInfo = intent.getParcelableExtra(
|
||||
ConnectivityManager.EXTRA_NETWORK_INFO // deprecated in API 14
|
||||
);
|
||||
int networkType = intent.getIntExtra(
|
||||
ConnectivityManager.EXTRA_NETWORK_TYPE, // only from API level 17
|
||||
-1
|
||||
);
|
||||
boolean couldBeWifiAction =
|
||||
(networkInfo == null && networkType < 0) || // cases of lack of info
|
||||
networkInfo.getType() == ConnectivityManager.TYPE_WIFI ||
|
||||
networkType == ConnectivityManager.TYPE_WIFI;
|
||||
|
||||
if (couldBeWifiAction) {
|
||||
if (ConnectivityUtils.isAppConnectedViaUnmeteredWiFi(context)) {
|
||||
Log_OC.d(TAG, "WiFi connected");
|
||||
wifiConnected(context);
|
||||
} else {
|
||||
Log_OC.d(TAG, "WiFi disconnected");
|
||||
wifiDisconnected(context);
|
||||
}
|
||||
} /* else, CONNECTIVIY_ACTION is (probably) about other network interface (mobile, bluetooth, ...)
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
private void wifiConnected(Context context) {
|
||||
// for the moment, only recovery of instant uploads, similar to behaviour in release 1.9.1
|
||||
if (
|
||||
(PreferenceManager.instantPictureUploadEnabled(context) &&
|
||||
PreferenceManager.instantPictureUploadViaWiFiOnly(context)) ||
|
||||
(PreferenceManager.instantVideoUploadEnabled(context) &&
|
||||
PreferenceManager.instantVideoUploadViaWiFiOnly(context))
|
||||
) {
|
||||
Log_OC.d(TAG, "Requesting retry of instant uploads (& friends)");
|
||||
FileUploader.UploadRequester requester = new FileUploader.UploadRequester();
|
||||
requester.retryFailedUploads(
|
||||
context,
|
||||
null,
|
||||
UploadResult.NETWORK_CONNECTION // for the interrupted when Wifi fell, if any
|
||||
// (side effect: any upload failed due to network error will be retried too, instant or not)
|
||||
);
|
||||
requester.retryFailedUploads(
|
||||
context,
|
||||
null,
|
||||
UploadResult.DELAYED_FOR_WIFI // for the rest of enqueued when Wifi fell
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
private void wifiDisconnected() {
|
||||
// TODO something smart
|
||||
|
||||
// NOTE: explicit cancellation of only-wifi instant uploads is not needed anymore, since currently:
|
||||
// - any upload in progress will be interrupted due to the lack of connectivity while the device
|
||||
// reconnects through other network interface;
|
||||
// - FileUploader checks instant upload settings and connection state before executing each
|
||||
// upload operation, so other pending instant uploads after the current one will not be run
|
||||
// (currently are silently moved to FAILED state)
|
||||
}
|
||||
|
||||
|
||||
|
||||
static public void enableActionReceiver(Context context) {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
ComponentName compName = new ComponentName(context.getApplicationContext(), ConnectivityActionReceiver.class);
|
||||
pm.setComponentEnabledSetting(compName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
|
||||
PackageManager.DONT_KILL_APP);
|
||||
}
|
||||
|
||||
static public void disableActionReceiver(Context context) {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
ComponentName compName = new ComponentName(context.getApplicationContext(), ConnectivityActionReceiver.class);
|
||||
pm.setComponentEnabledSetting(compName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
|
||||
PackageManager.DONT_KILL_APP);
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
|
@ -34,7 +34,6 @@ import android.app.Service;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
|
@ -691,7 +690,7 @@ public class FileUploader extends Service
|
|||
// need to update now table in mUploadsStorageManager,
|
||||
// since the operation will not get to be run by FileUploader#uploadFile
|
||||
mUploadsStorageManager.removeUpload(accountName, remotePath);
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
} else {
|
||||
// try to cancel job in jobScheduler
|
||||
mUploadsStorageManager.cancelPendingJob(accountName, remotePath);
|
||||
}
|
||||
|
|
|
@ -211,12 +211,6 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
|
|||
setupDrawerMenu(mNavigationView);
|
||||
|
||||
setupQuotaElement();
|
||||
|
||||
// show folder sync menu item only for Android 6+
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M &&
|
||||
mNavigationView.getMenu().findItem(R.id.nav_folder_sync) != null) {
|
||||
mNavigationView.getMenu().removeItem(R.id.nav_folder_sync);
|
||||
}
|
||||
}
|
||||
|
||||
setupDrawerToggle();
|
||||
|
|
|
@ -282,9 +282,8 @@ public class FileDisplayActivity extends HookActivity
|
|||
*/
|
||||
private void upgradeNotificationForInstantUpload() {
|
||||
// check for Android 6+ if legacy instant upload is activated --> disable + show info
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
|
||||
(PreferenceManager.instantPictureUploadEnabled(this) ||
|
||||
PreferenceManager.instantPictureUploadEnabled(this))) {
|
||||
if (PreferenceManager.instantPictureUploadEnabled(this) ||
|
||||
PreferenceManager.instantPictureUploadEnabled(this)) {
|
||||
|
||||
// remove legacy shared preferences
|
||||
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit();
|
||||
|
|
Loading…
Reference in a new issue