- bugfix
[pub/Android/ownCloud.git] / src / com / owncloud / android / files / InstantUploadBroadcastReceiver.java
1 /* ownCloud Android client application
2 * Copyright (C) 2012 Bartek Przybylski
3 * Copyright (C) 2012-2014 ownCloud Inc.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2,
7 * as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19 package com.owncloud.android.files;
20
21 import java.io.File;
22
23 import com.owncloud.android.MainApp;
24 import com.owncloud.android.authentication.AccountUtils;
25 import com.owncloud.android.db.DbHandler;
26 import com.owncloud.android.files.services.FileUploader;
27 import com.owncloud.android.lib.common.utils.Log_OC;
28 import com.owncloud.android.utils.FileStorageUtils;
29
30 import android.accounts.Account;
31 import android.content.BroadcastReceiver;
32 import android.content.Context;
33 import android.content.Intent;
34 import android.content.IntentFilter;
35 import android.database.Cursor;
36 import android.net.ConnectivityManager;
37 import android.net.NetworkInfo.State;
38 import android.os.BatteryManager;
39 import android.preference.PreferenceManager;
40 import android.provider.MediaStore.Images;
41 import android.provider.MediaStore.Video;
42 import android.webkit.MimeTypeMap;
43
44
45 public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
46
47 private static String TAG = InstantUploadBroadcastReceiver.class.getName();
48 // Image action
49 // Unofficial action, works for most devices but not HTC. See: https://github.com/owncloud/android/issues/6
50 private static String NEW_PHOTO_ACTION_UNOFFICIAL = "com.android.camera.NEW_PICTURE";
51 // Officially supported action since SDK 14: http://developer.android.com/reference/android/hardware/Camera.html#ACTION_NEW_PICTURE
52 private static String NEW_PHOTO_ACTION = "android.hardware.action.NEW_PICTURE";
53 // Video action
54 // Officially supported action since SDK 14: http://developer.android.com/reference/android/hardware/Camera.html#ACTION_NEW_VIDEO
55 private static String NEW_VIDEO_ACTION = "android.hardware.action.NEW_VIDEO";
56
57 @Override
58 public void onReceive(Context context, Intent intent) {
59 Log_OC.d(TAG, "Received: " + intent.getAction());
60 if (intent.getAction().equals(android.net.ConnectivityManager.CONNECTIVITY_ACTION) || intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)) {
61 handleConnectivityAction(context, intent);
62 }else if (intent.getAction().equals(NEW_PHOTO_ACTION_UNOFFICIAL)) {
63 handleNewPictureAction(context, intent);
64 Log_OC.d(TAG, "UNOFFICIAL processed: com.android.camera.NEW_PICTURE");
65 } else if (intent.getAction().equals(NEW_PHOTO_ACTION)) {
66 handleNewPictureAction(context, intent);
67 Log_OC.d(TAG, "OFFICIAL processed: android.hardware.action.NEW_PICTURE");
68 } else if (intent.getAction().equals(NEW_VIDEO_ACTION)) {
69 Log_OC.d(TAG, "OFFICIAL processed: android.hardware.action.NEW_VIDEO");
70 handleNewVideoAction(context, intent);
71 } else {
72 Log_OC.e(TAG, "Incorrect intent sent: " + intent.getAction());
73 }
74 }
75
76 private void handleNewPictureAction(Context context, Intent intent) {
77 Cursor c = null;
78 String file_path = null;
79 String file_name = null;
80 String mime_type = null;
81
82 Log_OC.w(TAG, "New photo received");
83
84 if (!instantPictureUploadEnabled(context)) {
85 Log_OC.d(TAG, "Instant picture upload disabled, ignoring new picture");
86 return;
87 }
88
89 Account account = AccountUtils.getCurrentOwnCloudAccount(context);
90 if (account == null) {
91 Log_OC.w(TAG, "No owncloud account found for instant upload, aborting");
92 return;
93 }
94
95 String[] CONTENT_PROJECTION = { Images.Media.DATA, Images.Media.DISPLAY_NAME, Images.Media.MIME_TYPE, Images.Media.SIZE };
96 c = context.getContentResolver().query(intent.getData(), CONTENT_PROJECTION, null, null, null);
97 if (!c.moveToFirst()) {
98 Log_OC.e(TAG, "Couldn't resolve given uri: " + intent.getDataString());
99 return;
100 }
101 file_path = c.getString(c.getColumnIndex(Images.Media.DATA));
102 file_name = c.getString(c.getColumnIndex(Images.Media.DISPLAY_NAME));
103 mime_type = c.getString(c.getColumnIndex(Images.Media.MIME_TYPE));
104 c.close();
105 Log_OC.d(TAG, file_path + "");
106
107 // save always temporally the picture to upload
108 DbHandler db = new DbHandler(context);
109 db.putFileForLater(file_path, account.name, null);
110 db.close();
111
112 if (!isOnline(context)
113 || (instantPictureUploadViaWiFiOnly(context) && !isConnectedViaWiFi(context))
114 || (instantUploadWhenChargingOnly(context) && !isCharging(context))
115 ) {
116 return;
117 }
118
119 Intent i = new Intent(context, FileUploader.class);
120 i.putExtra(FileUploader.KEY_ACCOUNT, account);
121 i.putExtra(FileUploader.KEY_LOCAL_FILE, file_path);
122 i.putExtra(FileUploader.KEY_REMOTE_FILE, FileStorageUtils.getInstantUploadFilePath(context, file_name));
123 i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
124 i.putExtra(FileUploader.KEY_MIME_TYPE, mime_type);
125 i.putExtra(FileUploader.KEY_INSTANT_UPLOAD, true);
126 context.startService(i);
127 }
128
129 private void handleNewVideoAction(Context context, Intent intent) {
130 Cursor c = null;
131 String file_path = null;
132 String file_name = null;
133 String mime_type = null;
134
135 Log_OC.w(TAG, "New video received");
136
137 if (!instantVideoUploadEnabled(context)) {
138 Log_OC.d(TAG, "Instant video upload disabled, ignoring new video");
139 return;
140 }
141
142 Account account = AccountUtils.getCurrentOwnCloudAccount(context);
143 if (account == null) {
144 Log_OC.w(TAG, "No owncloud account found for instant upload, aborting");
145 return;
146 }
147
148 String[] CONTENT_PROJECTION = { Video.Media.DATA, Video.Media.DISPLAY_NAME, Video.Media.MIME_TYPE, Video.Media.SIZE };
149 c = context.getContentResolver().query(intent.getData(), CONTENT_PROJECTION, null, null, null);
150 if (!c.moveToFirst()) {
151 Log_OC.e(TAG, "Couldn't resolve given uri: " + intent.getDataString());
152 return;
153 }
154 file_path = c.getString(c.getColumnIndex(Video.Media.DATA));
155 file_name = c.getString(c.getColumnIndex(Video.Media.DISPLAY_NAME));
156 mime_type = c.getString(c.getColumnIndex(Video.Media.MIME_TYPE));
157 c.close();
158 Log_OC.d(TAG, file_path + "");
159
160 // save always temporally the picture to upload
161 DbHandler db = new DbHandler(context);
162 db.putFileForLater(file_path, account.name, null);
163 db.close();
164
165 if (!isOnline(context)
166 || (instantVideoUploadViaWiFiOnly(context) && !isConnectedViaWiFi(context))
167 || (instantUploadWhenChargingOnly(context) && !isCharging(context))
168 ) {
169 return;
170 }
171
172 Intent i = new Intent(context, FileUploader.class);
173 i.putExtra(FileUploader.KEY_ACCOUNT, account);
174 i.putExtra(FileUploader.KEY_LOCAL_FILE, file_path);
175 i.putExtra(FileUploader.KEY_REMOTE_FILE, FileStorageUtils.getInstantUploadFilePath(context, file_name));
176 i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
177 i.putExtra(FileUploader.KEY_MIME_TYPE, mime_type);
178 i.putExtra(FileUploader.KEY_INSTANT_UPLOAD, true);
179 context.startService(i);
180
181 }
182
183 private void handleConnectivityAction(Context context, Intent intent) {
184 if (!instantPictureUploadEnabled(context) && !instantVideoUploadEnabled(context)) {
185 Log_OC.d(TAG, "Instant upload disabled, don't upload anything");
186 return;
187 }
188
189 if (!intent.hasExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY)
190 && isOnline(context)
191 && (!instantUploadWhenChargingOnly(context) || (instantUploadWhenChargingOnly(context) == isCharging(context) == true))
192 && (!instantPictureUploadViaWiFiOnly(context) || (instantPictureUploadViaWiFiOnly(context) == isConnectedViaWiFi(context) == true))
193 && (!instantVideoUploadViaWiFiOnly(context) || (instantVideoUploadViaWiFiOnly(context) == isConnectedViaWiFi(context) == true))
194 ) {
195 DbHandler db = new DbHandler(context);
196 Cursor c = db.getAwaitingFiles();
197 if (c.moveToFirst()) {
198 do {
199 String account_name = c.getString(c.getColumnIndex("account"));
200 String file_path = c.getString(c.getColumnIndex("path"));
201 File f = new File(file_path);
202 if (f.exists()) {
203 Account account = new Account(account_name, MainApp.getAccountType());
204
205 String mimeType = null;
206 try {
207 mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
208 f.getName().substring(f.getName().lastIndexOf('.') + 1));
209
210 } catch (Throwable e) {
211 Log_OC.e(TAG, "Trying to find out MIME type of a file without extension: " + f.getName());
212 }
213 if (mimeType == null)
214 mimeType = "application/octet-stream";
215
216 Intent i = new Intent(context, FileUploader.class);
217 i.putExtra(FileUploader.KEY_ACCOUNT, account);
218 i.putExtra(FileUploader.KEY_LOCAL_FILE, file_path);
219 i.putExtra(FileUploader.KEY_REMOTE_FILE, FileStorageUtils.getInstantUploadFilePath(context, f.getName()));
220 i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
221 i.putExtra(FileUploader.KEY_INSTANT_UPLOAD, true);
222 context.startService(i);
223
224 } else {
225 Log_OC.w(TAG, "Instant upload file " + f.getAbsolutePath() + " dont exist anymore");
226 }
227 } while (c.moveToNext());
228 }
229 c.close();
230 db.close();
231 }
232 }
233
234 public static boolean isOnline(Context context) {
235 ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
236 return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected();
237 }
238
239 public static boolean isConnectedViaWiFi(Context context) {
240 ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
241 return cm != null && cm.getActiveNetworkInfo() != null
242 && cm.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI
243 && cm.getActiveNetworkInfo().getState() == State.CONNECTED;
244 }
245
246 public static boolean isCharging(Context context){
247 IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
248 Intent batteryStatus = context.registerReceiver(null, ifilter);
249
250 int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
251 return status == BatteryManager.BATTERY_STATUS_CHARGING ||
252 status == BatteryManager.BATTERY_STATUS_FULL;
253 }
254
255 public static boolean instantPictureUploadEnabled(Context context) {
256 return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("instant_uploading", false);
257 }
258
259 public static boolean instantVideoUploadEnabled(Context context) {
260 return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("instant_video_uploading", false);
261 }
262
263 public static boolean instantPictureUploadViaWiFiOnly(Context context) {
264 return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("instant_upload_on_wifi", false);
265 }
266
267 public static boolean instantVideoUploadViaWiFiOnly(Context context) {
268 return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("instant_video_upload_on_wifi", false);
269 }
270 public static boolean instantUploadWhenChargingOnly(Context context) {
271 return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("instant_upload_on_charging", false);
272 }
273 }