1 /* ownCloud Android client application 
   2  *   Copyright (C) 2012  Bartek Przybylski 
   3  *   Copyright (C) 2012-2013 ownCloud Inc. 
   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. 
   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. 
  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/>. 
  19 package com
.owncloud
.android
.files
; 
  23 import com
.owncloud
.android
.Log_OC
; 
  24 import com
.owncloud
.android
.MainApp
; 
  25 import com
.owncloud
.android
.authentication
.AccountUtils
; 
  26 import com
.owncloud
.android
.db
.DbHandler
; 
  27 import com
.owncloud
.android
.files
.services
.FileUploader
; 
  28 import com
.owncloud
.android
.utils
.FileStorageUtils
; 
  31 import android
.accounts
.Account
; 
  32 import android
.content
.BroadcastReceiver
; 
  33 import android
.content
.Context
; 
  34 import android
.content
.Intent
; 
  35 //import android.content.IntentFilter; 
  36 import android
.database
.Cursor
; 
  37 import android
.net
.ConnectivityManager
; 
  38 import android
.net
.NetworkInfo
.State
; 
  39 import android
.preference
.PreferenceManager
; 
  40 import android
.provider
.MediaStore
.Images
.Media
; 
  41 import android
.webkit
.MimeTypeMap
; 
  44 public class InstantUploadBroadcastReceiver 
extends BroadcastReceiver 
{ 
  46     private static String TAG 
= "InstantUploadBroadcastReceiver"; 
  47     private static final String
[] CONTENT_PROJECTION 
= { Media
.DATA
, Media
.DISPLAY_NAME
, Media
.MIME_TYPE
, Media
.SIZE 
}; 
  48     //Unofficial action, works for most devices but not HTC. See: https://github.com/owncloud/android/issues/6 
  49     private static String NEW_PHOTO_ACTION_UNOFFICIAL 
= "com.android.camera.NEW_PICTURE"; 
  50     //Officially supported action since SDK 14: http://developer.android.com/reference/android/hardware/Camera.html#ACTION_NEW_PICTURE 
  51     private static String NEW_PHOTO_ACTION 
= "android.hardware.action.NEW_PICTURE"; 
  54     public void onReceive(Context context
, Intent intent
) { 
  55         Log_OC
.d(TAG
, "Received: " + intent
.getAction()); 
  56         if (intent
.getAction().equals(android
.net
.ConnectivityManager
.CONNECTIVITY_ACTION
)) { 
  57             handleConnectivityAction(context
, intent
); 
  58         }else if (intent
.getAction().equals(NEW_PHOTO_ACTION_UNOFFICIAL
)) { 
  59             handleNewPhotoAction(context
, intent
); 
  60             Log_OC
.d(TAG
, "UNOFFICIAL processed: com.android.camera.NEW_PICTURE"); 
  61         } else if (intent
.getAction().equals(NEW_PHOTO_ACTION
)) { 
  62             handleNewPhotoAction(context
, intent
); 
  63             Log_OC
.d(TAG
, "OFFICIAL processed: android.hardware.action.NEW_PICTURE"); 
  64         } else if (intent
.getAction().equals(FileUploader
.getUploadFinishMessage())) { 
  65             handleUploadFinished(context
, intent
); 
  67             Log_OC
.e(TAG
, "Incorrect intent sent: " + intent
.getAction()); 
  71     private void handleUploadFinished(Context context
, Intent intent
) { 
  72         // remove successfull uploading, ignore rest for reupload on reconnect 
  74         if (intent.getBooleanExtra(FileUploader.EXTRA_UPLOAD_RESULT, false)) { 
  75             DbHandler db = new DbHandler(context); 
  76             String localPath = intent.getStringExtra(FileUploader.EXTRA_OLD_FILE_PATH); 
  77             if (!db.removeIUPendingFile(localPath)) { 
  78                 Log_OC.w(TAG, "Tried to remove non existing instant upload file " + localPath); 
  85     private void handleNewPhotoAction(Context context
, Intent intent
) { 
  86         if (!instantUploadEnabled(context
)) { 
  87             Log_OC
.d(TAG
, "Instant upload disabled, aborting uploading"); 
  91         Account account 
= AccountUtils
.getCurrentOwnCloudAccount(context
); 
  92         if (account 
== null
) { 
  93             Log_OC
.w(TAG
, "No owncloud account found for instant upload, aborting"); 
  97         Cursor c 
= context
.getContentResolver().query(intent
.getData(), CONTENT_PROJECTION
, null
, null
, null
); 
  99         if (!c
.moveToFirst()) { 
 100             Log_OC
.e(TAG
, "Couldn't resolve given uri: " + intent
.getDataString()); 
 104         String file_path 
= c
.getString(c
.getColumnIndex(Media
.DATA
)); 
 105         String file_name 
= c
.getString(c
.getColumnIndex(Media
.DISPLAY_NAME
)); 
 106         String mime_type 
= c
.getString(c
.getColumnIndex(Media
.MIME_TYPE
)); 
 109         Log_OC
.e(TAG
, file_path 
+ ""); 
 111         // same always temporally the picture to upload 
 112         DbHandler db 
= new DbHandler(context
); 
 113         db
.putFileForLater(file_path
, account
.name
, null
); 
 116         if (!isOnline(context
) || (instantUploadViaWiFiOnly(context
) && !isConnectedViaWiFi(context
))) { 
 120         // register for upload finishe message 
 121         // there is a litte problem with android API, we can register for 
 123         // intent in registerReceiver but we cannot unregister from precise 
 125         // we can unregister from entire listenings but thats suck a bit. 
 126         // On the other hand this might be only for dynamicly registered 
 127         // broadcast receivers, needs investigation. 
 128         /*IntentFilter filter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE); 
 129         context.getApplicationContext().registerReceiver(this, filter);*/ 
 131         Intent i 
= new Intent(context
, FileUploader
.class); 
 132         i
.putExtra(FileUploader
.KEY_ACCOUNT
, account
); 
 133         i
.putExtra(FileUploader
.KEY_LOCAL_FILE
, file_path
); 
 134         i
.putExtra(FileUploader
.KEY_REMOTE_FILE
, FileStorageUtils
.getInstantUploadFilePath(context
, file_name
)); 
 135         i
.putExtra(FileUploader
.KEY_UPLOAD_TYPE
, FileUploader
.UPLOAD_SINGLE_FILE
); 
 136         i
.putExtra(FileUploader
.KEY_MIME_TYPE
, mime_type
); 
 137         i
.putExtra(FileUploader
.KEY_INSTANT_UPLOAD
, true
); 
 138         context
.startService(i
); 
 142     private void handleConnectivityAction(Context context
, Intent intent
) { 
 143         if (!instantUploadEnabled(context
)) { 
 144             Log_OC
.d(TAG
, "Instant upload disabled, abording uploading"); 
 148         if (!intent
.hasExtra(ConnectivityManager
.EXTRA_NO_CONNECTIVITY
) 
 150                 && (!instantUploadViaWiFiOnly(context
) || (instantUploadViaWiFiOnly(context
) == isConnectedViaWiFi(context
) == true
))) { 
 151             DbHandler db 
= new DbHandler(context
); 
 152             Cursor c 
= db
.getAwaitingFiles(); 
 153             if (c
.moveToFirst()) { 
 154                 //IntentFilter filter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE); 
 155                 //context.getApplicationContext().registerReceiver(this, filter); 
 157                     String account_name 
= c
.getString(c
.getColumnIndex("account")); 
 158                     String file_path 
= c
.getString(c
.getColumnIndex("path")); 
 159                     File f 
= new File(file_path
); 
 161                         Account account 
= new Account(account_name
, MainApp
.getAccountType()); 
 163                         String mimeType 
= null
; 
 165                             mimeType 
= MimeTypeMap
.getSingleton().getMimeTypeFromExtension( 
 166                                     f
.getName().substring(f
.getName().lastIndexOf('.') + 1)); 
 168                         } catch (Throwable e
) { 
 169                             Log_OC
.e(TAG
, "Trying to find out MIME type of a file without extension: " + f
.getName()); 
 171                         if (mimeType 
== null
) 
 172                             mimeType 
= "application/octet-stream"; 
 174                         Intent i 
= new Intent(context
, FileUploader
.class); 
 175                         i
.putExtra(FileUploader
.KEY_ACCOUNT
, account
); 
 176                         i
.putExtra(FileUploader
.KEY_LOCAL_FILE
, file_path
); 
 177                         i
.putExtra(FileUploader
.KEY_REMOTE_FILE
, FileStorageUtils
.getInstantUploadFilePath(context
, f
.getName())); 
 178                         i
.putExtra(FileUploader
.KEY_UPLOAD_TYPE
, FileUploader
.UPLOAD_SINGLE_FILE
); 
 179                         i
.putExtra(FileUploader
.KEY_INSTANT_UPLOAD
, true
); 
 180                         context
.startService(i
); 
 183                         Log_OC
.w(TAG
, "Instant upload file " + f
.getAbsolutePath() + " dont exist anymore"); 
 185                 } while (c
.moveToNext()); 
 193     public static boolean isOnline(Context context
) { 
 194         ConnectivityManager cm 
= (ConnectivityManager
) context
.getSystemService(Context
.CONNECTIVITY_SERVICE
); 
 195         return cm
.getActiveNetworkInfo() != null 
&& cm
.getActiveNetworkInfo().isConnected(); 
 198     public static boolean isConnectedViaWiFi(Context context
) { 
 199         ConnectivityManager cm 
= (ConnectivityManager
) context
.getSystemService(Context
.CONNECTIVITY_SERVICE
); 
 200         return cm 
!= null 
&& cm
.getActiveNetworkInfo() != null
 
 201                 && cm
.getActiveNetworkInfo().getType() == ConnectivityManager
.TYPE_WIFI
 
 202                 && cm
.getActiveNetworkInfo().getState() == State
.CONNECTED
; 
 205     public static boolean instantUploadEnabled(Context context
) { 
 206         return PreferenceManager
.getDefaultSharedPreferences(context
).getBoolean("instant_uploading", false
); 
 209     public static boolean instantUploadViaWiFiOnly(Context context
) { 
 210         return PreferenceManager
.getDefaultSharedPreferences(context
).getBoolean("instant_upload_on_wifi", false
);