Mario Danic 8 年之前
父节点
当前提交
b787ee6caa

+ 32 - 0
src/main/java/com/owncloud/android/db/PreferenceManager.java

@@ -46,7 +46,33 @@ public abstract class PreferenceManager {
     private static final String PREF__INSTANT_VIDEO_UPLOAD_PATH_USE_SUBFOLDERS = "instant_video_upload_path_use_subfolders";
     private static final String PREF__LEGACY_CLEAN = "legacyClean";
     private static final String PREF__AUTO_UPLOAD_UPDATE_PATH = "autoUploadPathUpdate";
+    private static final String PREF__PUSH_TOKEN = "pushToken";
+    private static final String PREF__PUSH_TOKEN_UPDATE_TIME = "pushTokenLastUpdated";
+    private static final String PREF__PUSH_TOKEN_LAST_REGISTRATION_TIME = "pushTokenLastSent";
 
+    public static void setPushTokenLastSentTime(Context context, long time) {
+        saveLongPreference(context, PREF__PUSH_TOKEN_LAST_REGISTRATION_TIME, time);
+    }
+
+    public static long getPushTokenLastSentTime(Context context) {
+        return getDefaultSharedPreferences(context).getLong(PREF__PUSH_TOKEN_LAST_REGISTRATION_TIME, -1);
+    }
+
+    public static void setPushToken(Context context, String pushToken) {
+        saveStringPreference(context, PREF__PUSH_TOKEN, pushToken);
+    }
+
+    public static String getPushToken(Context context) {
+        return getDefaultSharedPreferences(context).getString(PREF__PUSH_TOKEN, "");
+    }
+
+    public static void setPushTokenUpdateTime(Context context, long time) {
+        saveLongPreference(context, PREF__PUSH_TOKEN_UPDATE_TIME, time);
+    }
+
+    public static long getPushTokenUpdateTime(Context context) {
+        return getDefaultSharedPreferences(context).getLong(PREF__PUSH_TOKEN_UPDATE_TIME, -1);
+    }
 
     public static boolean instantPictureUploadEnabled(Context context) {
         return getDefaultSharedPreferences(context).getBoolean(PREF__INSTANT_UPLOADING, false);
@@ -267,6 +293,12 @@ public abstract class PreferenceManager {
         appPreferences.apply();
     }
 
+    private static void saveLongPreference(Context context, String key, long value) {
+        SharedPreferences.Editor appPreferences = getDefaultSharedPreferences(context.getApplicationContext()).edit();
+        appPreferences.putLong(key, value);
+        appPreferences.apply();
+    }
+
     public static SharedPreferences getDefaultSharedPreferences(Context context) {
         return android.preference.PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
     }

+ 12 - 0
src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java

@@ -82,6 +82,8 @@ import com.owncloud.android.operations.UploadFileOperation;
 import com.owncloud.android.services.observer.FileObserverService;
 import com.owncloud.android.syncadapter.FileSyncAdapter;
 import com.owncloud.android.ui.dialog.SortingOrderDialogFragment;
+import com.owncloud.android.ui.events.SearchEvent;
+import com.owncloud.android.ui.events.TokenPushEvent;
 import com.owncloud.android.ui.fragment.ExtendedListFragment;
 import com.owncloud.android.ui.fragment.FileDetailFragment;
 import com.owncloud.android.ui.fragment.FileFragment;
@@ -97,6 +99,11 @@ import com.owncloud.android.utils.DataHolderUtil;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.ErrorMessageAdapter;
 import com.owncloud.android.utils.PermissionUtil;
+import com.owncloud.android.utils.PushUtils;
+
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
 
 import java.io.File;
 import java.util.ArrayList;
@@ -314,6 +321,11 @@ public class FileDisplayActivity extends HookActivity
         }
     }
 
+    @Subscribe(threadMode = ThreadMode.BACKGROUND)
+    public void onMessageEvent(TokenPushEvent event) {
+        PushUtils.pushRegistrationToServer();
+    }
+
     @Override
     public void onRequestPermissionsResult(int requestCode,
                                            String permissions[], int[] grantResults) {

+ 27 - 0
src/main/java/com/owncloud/android/ui/events/TokenPushEvent.java

@@ -0,0 +1,27 @@
+/**
+ * Nextcloud Android client application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017 Mario Danic
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.owncloud.android.ui.events;
+
+/**
+ * Event to send push token where it belongs
+ */
+
+public class TokenPushEvent {
+}

+ 2 - 0
src/main/res/values/strings.xml

@@ -626,5 +626,7 @@
     <string name="activities_no_results_headline">No activity yet</string>
     <string name="activities_no_results_message">This stream will show events like\nadditions, changes &amp; shares</string>
 
+    <!-- Notifications -->
+    <string name="new_notification_received">New notification received</string>
 
 </resources>

+ 6 - 65
src/modified/java/com/owncloud/android/services/firebase/NCFirebaseInstanceIDService.java

@@ -19,31 +19,16 @@
  */
 package com.owncloud.android.services.firebase;
 
-import android.accounts.Account;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
-import android.content.Context;
 import android.text.TextUtils;
+import android.util.Log;
 
 import com.google.firebase.iid.FirebaseInstanceId;
 import com.google.firebase.iid.FirebaseInstanceIdService;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
-import com.owncloud.android.authentication.AccountUtils;
-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.operations.RemoteOperation;
-import com.owncloud.android.lib.common.operations.RemoteOperationResult;
-import com.owncloud.android.lib.common.utils.Log_OC;
-import com.owncloud.android.lib.resources.notifications.RegisterAccountDeviceForNotificationsOperation;
-import com.owncloud.android.lib.resources.notifications.RegisterAccountDeviceForProxyOperation;
-import com.owncloud.android.lib.resources.notifications.models.PushResponse;
+import com.owncloud.android.db.PreferenceManager;
 import com.owncloud.android.utils.PushUtils;
 
-import java.io.IOException;
-import java.security.PublicKey;
-
 public class NCFirebaseInstanceIDService extends FirebaseInstanceIdService {
     private static final String TAG = "NCFirebaseInstanceID";
 
@@ -51,57 +36,13 @@ public class NCFirebaseInstanceIDService extends FirebaseInstanceIdService {
     public void onTokenRefresh() {
         //You can implement this method to store the token on your server
         if (!TextUtils.isEmpty(getResources().getString(R.string.push_server_url))) {
-            PushUtils.generateRsa2048KeyPair();
-            sendRegistrationToServer(FirebaseInstanceId.getInstance().getToken());
+            PreferenceManager.setPushToken(MainApp.getAppContext(), FirebaseInstanceId.getInstance().getToken());
+            PreferenceManager.setPushTokenUpdateTime(MainApp.getAppContext(), System.currentTimeMillis());
         }
-    }
-
-    private void sendRegistrationToServer(String token) {
-        String pushTokenHash = PushUtils.generateSHA512Hash(token);
-        PublicKey devicePublicKey = (PublicKey) PushUtils.readKeyFromFile(true);
-        if (devicePublicKey != null) {
-            String publicKey = devicePublicKey.toString();
-
-            Context context = MainApp.getAppContext();
-            for (Account account : AccountUtils.getAccounts(context)) {
-                try {
-                    OwnCloudAccount ocAccount = new OwnCloudAccount(account, context);
-                    OwnCloudClient mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
-                            getClientFor(ocAccount, context);
-
-                    RemoteOperation registerAccountDeviceForNotificationsOperation =
-                            new RegisterAccountDeviceForNotificationsOperation(pushTokenHash,
-                        publicKey, context.getResources().getString(R.string.push_server_url));
-
-                    RemoteOperationResult remoteOperationResult = registerAccountDeviceForNotificationsOperation.
-                            execute(mClient);
-
-                    if (remoteOperationResult.isSuccess()) {
-                        PushResponse pushResponse = remoteOperationResult.getPushResponseData();
-
-                        RemoteOperation registerAccountDeviceForProxyOperation = new
-                                RegisterAccountDeviceForProxyOperation(
-                                context.getResources().getString(R.string.push_server_url),
-                                token, pushResponse.getDeviceIdentifier(), pushResponse.getSignature(),
-                                pushResponse.getPublicKey());
-
-                        remoteOperationResult = registerAccountDeviceForProxyOperation.execute(mClient);
-                    }
-                } catch (com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException e) {
-                    Log_OC.d(TAG, "Failed to find an account");
-                } catch (AuthenticatorException e) {
-                    Log_OC.d(TAG, "Failed via AuthenticatorException");
-                } catch (IOException e) {
-                    Log_OC.d(TAG, "Failed via IOException");
-                } catch (OperationCanceledException e) {
-                    Log_OC.d(TAG, "Failed via OperationCanceledException");
-                }
-
-            }
 
+        if (PreferenceManager.getPushTokenLastSentTime(MainApp.getAppContext()) != -1) {
+            PushUtils.pushRegistrationToServer();
         }
-
     }
-
 }
 

+ 2 - 4
src/modified/java/com/owncloud/android/services/firebase/NCFirebaseMessagingService.java

@@ -26,10 +26,10 @@ import android.content.Intent;
 import android.media.RingtoneManager;
 import android.net.Uri;
 import android.support.v4.app.NotificationCompat;
-import android.util.Log;
 
 import com.google.firebase.messaging.FirebaseMessagingService;
 import com.google.firebase.messaging.RemoteMessage;
+import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.ui.activity.NotificationsActivity;
 
@@ -39,10 +39,8 @@ public class NCFirebaseMessagingService extends FirebaseMessagingService {
     @Override
     public void onMessageReceived(RemoteMessage remoteMessage) {
         super.onMessageReceived(remoteMessage);
-        Log.d(TAG, "From: " + remoteMessage.getFrom());
-        Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
 
-        sendNotification(remoteMessage.getNotification().getTitle());
+        sendNotification(MainApp.getAppContext().getString(R.string.new_notification_received));
     }
 
     private void sendNotification(String contentTitle) {

+ 86 - 7
src/modified/java/com/owncloud/android/utils/PushUtils.java

@@ -20,8 +20,27 @@
 
 package com.owncloud.android.utils;
 
+import android.accounts.Account;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.Base64;
+import android.util.Log;
+
 import com.owncloud.android.MainApp;
+import com.owncloud.android.R;
+import com.owncloud.android.authentication.AccountUtils;
+import com.owncloud.android.db.PreferenceManager;
+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.operations.RemoteOperation;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.lib.resources.notifications.RegisterAccountDeviceForNotificationsOperation;
+import com.owncloud.android.lib.resources.notifications.RegisterAccountDeviceForProxyOperation;
+import com.owncloud.android.lib.resources.notifications.models.PushResponse;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -34,6 +53,7 @@ import java.security.KeyPair;
 import java.security.KeyPairGenerator;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
 import java.security.spec.InvalidKeySpecException;
 import java.security.spec.PKCS8EncodedKeySpec;
 import java.security.spec.X509EncodedKeySpec;
@@ -43,6 +63,7 @@ public class PushUtils {
     private static final String TAG = "PushUtils";
     private static final String KEYPAIR_FOLDER = "nc-keypair";
     private static final String KEYPAIR_FILE_NAME = "push_key";
+    private static final String KEYPAIR_PRIV_EXTENSION = ".priv";
     private static final String KEYPAIR_PUB_EXTENSION = ".pub";
 
     public static String generateSHA512Hash(String pushToken) {
@@ -68,15 +89,17 @@ public class PushUtils {
 
     public static int generateRsa2048KeyPair() {
         String keyPath = MainApp.getStoragePath() + File.separator + MainApp.getDataFolder() + File.separator
-                + KEYPAIR_FOLDER;;
+                + KEYPAIR_FOLDER;
+        ;
 
-        String privateKeyPath = keyPath + File.separator + KEYPAIR_FILE_NAME;
+        String privateKeyPath = keyPath + File.separator + KEYPAIR_FILE_NAME + KEYPAIR_PRIV_EXTENSION;
         String publicKeyPath = keyPath + File.separator + KEYPAIR_FILE_NAME + KEYPAIR_PUB_EXTENSION;
         File keyPathFile = new File(keyPath);
+
         if (!new File(privateKeyPath).exists() && !new File(publicKeyPath).exists()) {
             try {
                 if (!keyPathFile.exists()) {
-                    keyPathFile.createNewFile();
+                    keyPathFile.mkdir();
                 }
                 KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
                 keyGen.initialize(2048);
@@ -91,8 +114,6 @@ public class PushUtils {
                 } else {
                     return -2;
                 }
-            } catch (IOException e) {
-                Log_OC.d(TAG, "Failed to generate a keypair folder path" + e.getLocalizedMessage());
             } catch (NoSuchAlgorithmException e) {
                 Log_OC.d(TAG, "RSA algorithm not supported");
             }
@@ -105,10 +126,65 @@ public class PushUtils {
         return -2;
     }
 
+    public static void pushRegistrationToServer() {
+        String token = PreferenceManager.getPushToken(MainApp.getAppContext());
+        if (!TextUtils.isEmpty(MainApp.getAppContext().getResources().getString(R.string.push_server_url)) &&
+                !TextUtils.isEmpty(token)) {
+            PushUtils.generateRsa2048KeyPair();
+            String pushTokenHash = PushUtils.generateSHA512Hash(token).toUpperCase();
+            PublicKey devicePublicKey = (PublicKey) PushUtils.readKeyFromFile(true);
+            if (devicePublicKey != null) {
+                byte[] publicKeyBytes = Base64.encode(devicePublicKey.getEncoded(), 0);
+                String publicKey = new String(publicKeyBytes);
+
+                Context context = MainApp.getAppContext();
+                for (Account account : AccountUtils.getAccounts(context)) {
+                    try {
+                        OwnCloudAccount ocAccount = new OwnCloudAccount(account, context);
+                        OwnCloudClient mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
+                                getClientFor(ocAccount, context);
+
+                        RemoteOperation registerAccountDeviceForNotificationsOperation =
+                                new RegisterAccountDeviceForNotificationsOperation(pushTokenHash,
+                                        publicKey, context.getResources().getString(R.string.push_server_url));
+
+                        RemoteOperationResult remoteOperationResult = registerAccountDeviceForNotificationsOperation.
+                                execute(mClient);
+
+                        if (remoteOperationResult.isSuccess()) {
+                            PushResponse pushResponse = remoteOperationResult.getPushResponseData();
+
+                            RemoteOperation registerAccountDeviceForProxyOperation = new
+                                    RegisterAccountDeviceForProxyOperation(
+                                    context.getResources().getString(R.string.push_server_url),
+                                    token, pushResponse.getDeviceIdentifier(), pushResponse.getSignature(),
+                                    pushResponse.getPublicKey());
+
+                            remoteOperationResult = registerAccountDeviceForProxyOperation.execute(mClient);
+                            Log.d("THIS IS MARIO", "MARIO");
+                            PreferenceManager.setPushTokenLastSentTime(MainApp.getAppContext(),
+                                    System.currentTimeMillis());
+
+                        }
+                    } catch (com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException e) {
+                        Log_OC.d(TAG, "Failed to find an account");
+                    } catch (AuthenticatorException e) {
+                        Log_OC.d(TAG, "Failed via AuthenticatorException");
+                    } catch (IOException e) {
+                        Log_OC.d(TAG, "Failed via IOException");
+                    } catch (OperationCanceledException e) {
+                        Log_OC.d(TAG, "Failed via OperationCanceledException");
+                    }
+                }
+            }
+        }
+    }
+
     public static Key readKeyFromFile(boolean readPublicKey) {
         String keyPath = MainApp.getStoragePath() + File.separator + MainApp.getDataFolder() + File.separator
-                + KEYPAIR_FOLDER;;
-        String privateKeyPath = keyPath + File.separator + KEYPAIR_FILE_NAME;
+                + KEYPAIR_FOLDER;
+        ;
+        String privateKeyPath = keyPath + File.separator + KEYPAIR_FILE_NAME + KEYPAIR_PRIV_EXTENSION;
         String publicKeyPath = keyPath + File.separator + KEYPAIR_FILE_NAME + KEYPAIR_PUB_EXTENSION;
 
         String path;
@@ -153,6 +229,9 @@ public class PushUtils {
         byte[] encoded = key.getEncoded();
         FileOutputStream keyFileOutputStream = null;
         try {
+            if (!new File(path).exists()) {
+                new File(path).createNewFile();
+            }
             keyFileOutputStream = new FileOutputStream(path);
             keyFileOutputStream.write(encoded);
             keyFileOutputStream.close();