diff --git a/app/build.gradle b/app/build.gradle index 6b0780f48..c7a4df47f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,3 +1,6 @@ +import java.util.regex.Matcher +import java.util.regex.Pattern + apply plugin: 'com.android.application' def flavor android { @@ -65,8 +68,7 @@ android { } sourceSets { playstore { - - manifest.srcFile "src/common/AndroidManifest.xml" + manifest.srcFile "src/playstore/AndroidManifest.xml" assets.srcDirs = ['/src/mains/assets', 'src/common/assets'] java.srcDirs = ['src/main/java', 'src/playstore/java','src/common/java'] res.srcDirs = ['src/main/res', 'src/playstore/res','src/common/res'] @@ -178,7 +180,7 @@ dependencies { implementation 'com.huangyz0918:androidwm-light:0.1.2' - implementation 'com.github.UnifiedPush:android-connector:dev-SNAPSHOT' + implementation 'com.github.UnifiedPush:android-connector:1.1.0' implementation "com.madgag.spongycastle:bctls-jdk15on:1.58.0.0" //Flavors @@ -189,7 +191,7 @@ dependencies { playstoreImplementation 'org.framagit.tom79:country-picker-android:1.2.0' playstoreImplementation 'com.vanniktech:emoji-one:0.6.0' playstoreImplementation 'ja.burhanrashid52:photoeditor:0.4.0' - playstoreImplementation 'com.github.UnifiedPush:android-connector_fcm_added:dev-SNAPSHOT' + playstoreImplementation 'com.github.UnifiedPush:android-connector_fcm_added:1.0.0' //Fdroid fdroidApi 'com.theartofdev.edmodo:android-image-cropper:2.8.+' @@ -201,5 +203,26 @@ dependencies { } +def getCurrentFlavor() { + Gradle gradle = getGradle() + String tskReqStr = gradle.getStartParameter().getTaskRequests().toString() -apply plugin: 'com.google.gms.google-services' + Pattern pattern + + if( tskReqStr.contains( "assemble" ) ) + pattern = Pattern.compile("assemble(\\w+)(Release|Debug)") + else + pattern = Pattern.compile("generate(\\w+)(Release|Debug)") + Matcher matcher = pattern.matcher( tskReqStr ) + + if( matcher.find() ) { + return matcher.group(1).toLowerCase() + }else + { + println "NO MATCH FOUND" + return "" + } +} +if( getCurrentFlavor() == "playstore") { + apply plugin: 'com.google.gms.google-services' +} diff --git a/app/src/fdroidcommon/java/app/fedilab/android/helper/PushHelper.java b/app/src/fdroidcommon/java/app/fedilab/android/helper/PushHelper.java index f0760c53f..24aa114a3 100644 --- a/app/src/fdroidcommon/java/app/fedilab/android/helper/PushHelper.java +++ b/app/src/fdroidcommon/java/app/fedilab/android/helper/PushHelper.java @@ -2,18 +2,27 @@ package app.fedilab.android.helper; import android.app.Activity; import android.content.Context; +import android.content.SharedPreferences; import android.database.sqlite.SQLiteDatabase; +import android.text.SpannableString; +import android.text.method.LinkMovementMethod; +import android.text.util.Linkify; +import android.widget.TextView; + +import androidx.appcompat.app.AlertDialog; import org.unifiedpush.android.connector.Registration; import java.util.List; +import app.fedilab.android.R; import app.fedilab.android.client.Entities.Account; import app.fedilab.android.jobs.ApplicationJob; import app.fedilab.android.jobs.NotificationsSyncJob; import app.fedilab.android.sqlite.AccountDAO; import app.fedilab.android.sqlite.Sqlite; +import static android.content.Context.MODE_PRIVATE; import static app.fedilab.android.helper.BaseHelper.NOTIF_NONE; import static app.fedilab.android.helper.BaseHelper.NOTIF_PUSH; import static app.fedilab.android.helper.BaseHelper.liveNotifType; @@ -31,7 +40,7 @@ public class PushHelper { List accounts = new AccountDAO(context, db).getPushNotificationAccounts(); ((Activity) context).runOnUiThread(() -> { for (Account account : accounts) { - new Registration().registerAppWithDialog(context, account.getUsername() + "@" + account.getInstance()); + registerAppWithDialog(context, account.getUsername() + "@" + account.getInstance()); } }); }).start(); @@ -41,4 +50,54 @@ public class PushHelper { break; } } + + + private static void registerAppWithDialog(Context context, String slug) { + SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE); + int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); + int style; + if (theme == Helper.THEME_DARK) { + style = R.style.DialogDark; + } else if (theme == Helper.THEME_BLACK) { + style = R.style.DialogBlack; + } else { + style = R.style.Dialog; + } + + Registration registration = new Registration(); + List distributors = registration.getDistributors(context); + if (distributors.size() == 1 || !registration.getDistributor(context).isEmpty()) { + if (distributors.size() == 1) { + registration.saveDistributor(context, distributors.get(0)); + } else { + registration.saveDistributor(context, registration.getDistributor(context)); + } + registration.registerApp(context, slug); + return; + } + AlertDialog.Builder alert = new AlertDialog.Builder(context, style); + if (distributors.size() == 0) { + alert.setTitle(R.string.no_distributors_found); + final TextView message = new TextView(context); + String link = "https://fedilab.app/wiki/features/push-notifications#fdroid"; + final SpannableString s = + new SpannableString(context.getString(R.string.no_distributors_explanation, link)); + Linkify.addLinks(s, Linkify.WEB_URLS); + message.setText(s); + message.setPadding(30, 20, 30, 10); + message.setMovementMethod(LinkMovementMethod.getInstance()); + alert.setView(message); + alert.setPositiveButton(R.string.close, (dialog, whichButton) -> dialog.dismiss()); + } else { + alert.setTitle(R.string.select_distributors); + String[] distributorsStr = distributors.toArray(new String[0]); + alert.setSingleChoiceItems(distributorsStr, -1, (dialog, item) -> { + String distributor = distributorsStr[item]; + registration.saveDistributor(context, distributor); + registration.registerApp(context, slug); + dialog.dismiss(); + }); + } + alert.show(); + } } diff --git a/app/src/main/java/app/fedilab/android/activities/LoginActivity.java b/app/src/main/java/app/fedilab/android/activities/LoginActivity.java index 62ac6706a..f32d68305 100644 --- a/app/src/main/java/app/fedilab/android/activities/LoginActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/LoginActivity.java @@ -15,6 +15,7 @@ package app.fedilab.android.activities; import android.Manifest; +import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -121,6 +122,7 @@ public class LoginActivity extends BaseActivity { return Helper.instanceWithProtocol(context, instance) + Helper.EP_AUTHORIZE + "?" + queryString; } + @SuppressLint("ApplySharedPref") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -325,18 +327,23 @@ public class LoginActivity extends BaseActivity { thread.interrupt(); thread = null; } - if (oldSearch == null || !oldSearch.equals(s.toString().trim())) { thread = new Thread(() -> { try { - final String response = new HttpsConnection(LoginActivity.this, instance).get("https://instances.social/api/1.0" + action, 30, parameters, Helper.THEKINRAR_SECRET_TOKEN); + String response = null; + try { + response = new HttpsConnection(LoginActivity.this, instance).get("https://instances.social/api/1.0" + action, 30, parameters, Helper.THEKINRAR_SECRET_TOKEN); + } catch (Exception ignored) { + } + if (response == null) { return; } + String finalResponse = response; runOnUiThread(() -> { String[] instances; try { - JSONObject jsonObject = new JSONObject(response); + JSONObject jsonObject = new JSONObject(finalResponse); JSONArray jsonArray = jsonObject.getJSONArray("instances"); int length = 0; for (int i = 0; i < jsonArray.length(); i++) { @@ -744,18 +751,10 @@ public class LoginActivity extends BaseActivity { } Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.addCategory(Intent.CATEGORY_OPENABLE); - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { - intent.setType("*/*"); - String[] mimetypes = {"*/*"}; - intent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes); - startActivityForResult(intent, PICK_IMPORT); - } else { - intent.setType("*/*"); - Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); - Intent chooserIntent = Intent.createChooser(intent, getString(R.string.toot_select_import)); - chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{pickIntent}); - startActivityForResult(chooserIntent, PICK_IMPORT); - } + intent.setType("*/*"); + String[] mimetypes = {"*/*"}; + intent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes); + startActivityForResult(intent, PICK_IMPORT); } return super.onOptionsItemSelected(item); } diff --git a/app/src/main/java/app/fedilab/android/client/API.java b/app/src/main/java/app/fedilab/android/client/API.java index 695d40645..7205d25ee 100644 --- a/app/src/main/java/app/fedilab/android/client/API.java +++ b/app/src/main/java/app/fedilab/android/client/API.java @@ -23,6 +23,7 @@ import android.os.Bundle; import android.text.Html; import android.text.SpannableString; + import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.preference.PreferenceManager; @@ -5863,11 +5864,10 @@ public class API { .getDefaultSharedPreferences(context); String strPub = prefs.getString(kp_public, ""); String strPriv = prefs.getString(kp_private, ""); + ECDH ecdh = ECDH.getInstance(); if (strPub.trim().isEmpty() || strPriv.trim().isEmpty()) { newPair(context); } - - ECDH ecdh = ECDH.getInstance(); String pubKey = ecdh.getPublicKey(context); byte[] randBytes = new byte[16]; new Random().nextBytes(randBytes); diff --git a/app/src/main/java/app/fedilab/android/drawers/BaseStatusListAdapter.java b/app/src/main/java/app/fedilab/android/drawers/BaseStatusListAdapter.java index e7bbe1524..136c026be 100644 --- a/app/src/main/java/app/fedilab/android/drawers/BaseStatusListAdapter.java +++ b/app/src/main/java/app/fedilab/android/drawers/BaseStatusListAdapter.java @@ -632,15 +632,16 @@ public abstract class BaseStatusListAdapter extends RecyclerView.Adapter since_ids = new HashMap<>(); public static void task(Context context, Account account) { APIResponse apiResponse; + String key = account.getUsername() + "@" + account.getInstance(); + String last_notifid = null; + if (since_ids.containsKey(key)) { + last_notifid = since_ids.get(key); + } final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); //Check which notifications the user wants to see @@ -85,10 +91,10 @@ public class NotificationsHelper { if (!sharedpreferences.getBoolean(Helper.SET_WIFI_ONLY, false) || Helper.isOnWIFI(context)) { if (account.getSocial().compareTo("FRIENDICA") != 0 && account.getSocial().compareTo("GNU") != 0) { API api = new API(context, account.getInstance(), account.getToken()); - apiResponse = api.getNotificationsSince(DisplayNotificationsFragment.Type.ALL, null, false); + apiResponse = api.getNotificationsSince(DisplayNotificationsFragment.Type.ALL, last_notifid, false); } else { GNUAPI gnuApi = new GNUAPI(context, account.getInstance(), account.getToken()); - apiResponse = gnuApi.getNotificationsSince(DisplayNotificationsFragment.Type.ALL, null); + apiResponse = gnuApi.getNotificationsSince(DisplayNotificationsFragment.Type.ALL, last_notifid); } onRetrieveNotifications(context, apiResponse, account); } @@ -99,6 +105,8 @@ public class NotificationsHelper { List notificationsReceived = apiResponse.getNotifications(); if (apiResponse.getError() != null || notificationsReceived == null || notificationsReceived.size() == 0 || account == null) return; + String key = account.getUsername() + "@" + account.getInstance(); + since_ids.put(key, apiResponse.getNotifications().get(0).getId()); final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); boolean notif_follow = sharedpreferences.getBoolean(Helper.SET_NOTIF_FOLLOW, true); boolean notif_add = sharedpreferences.getBoolean(Helper.SET_NOTIF_ADD, true); diff --git a/app/src/main/java/app/fedilab/android/jobs/BaseNotificationsSyncJob.java b/app/src/main/java/app/fedilab/android/jobs/BaseNotificationsSyncJob.java index 59a20d5dc..3ce174f64 100644 --- a/app/src/main/java/app/fedilab/android/jobs/BaseNotificationsSyncJob.java +++ b/app/src/main/java/app/fedilab/android/jobs/BaseNotificationsSyncJob.java @@ -15,55 +15,26 @@ package app.fedilab.android.jobs; * see . */ import android.content.Context; -import android.content.Intent; import android.content.SharedPreferences; import android.database.sqlite.SQLiteDatabase; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.drawable.Drawable; -import android.os.Handler; -import android.os.Looper; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.load.DataSource; -import com.bumptech.glide.load.engine.GlideException; -import com.bumptech.glide.request.RequestListener; -import com.bumptech.glide.request.target.CustomTarget; -import com.bumptech.glide.request.target.Target; -import com.bumptech.glide.request.transition.Transition; import com.evernote.android.job.Job; import com.evernote.android.job.JobManager; import com.evernote.android.job.JobRequest; -import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; -import app.fedilab.android.R; -import app.fedilab.android.activities.MainActivity; -import app.fedilab.android.client.API; -import app.fedilab.android.client.APIResponse; import app.fedilab.android.client.Entities.Account; -import app.fedilab.android.client.Entities.Notification; -import app.fedilab.android.client.GNUAPI; -import app.fedilab.android.fragments.DisplayNotificationsFragment; import app.fedilab.android.helper.Helper; import app.fedilab.android.helper.NotificationsHelper; import app.fedilab.android.sqlite.AccountDAO; import app.fedilab.android.sqlite.Sqlite; -import static app.fedilab.android.helper.Helper.INTENT_ACTION; -import static app.fedilab.android.helper.Helper.INTENT_TARGETED_ACCOUNT; -import static app.fedilab.android.helper.Helper.NOTIFICATION_INTENT; -import static app.fedilab.android.helper.Helper.PREF_INSTANCE; -import static app.fedilab.android.helper.Helper.PREF_KEY_ID; import static app.fedilab.android.helper.Helper.canNotify; -import static app.fedilab.android.helper.Helper.getMainLogo; -import static app.fedilab.android.helper.Helper.notify_user; + /** @@ -138,15 +109,7 @@ public class BaseNotificationsSyncJob extends Job { return; //Retrieve users in db that owner has. for (Account account : accounts) { - APIResponse apiResponse; - if (account.getSocial().compareTo("FRIENDICA") != 0 && account.getSocial().compareTo("GNU") != 0) { - API api = new API(getContext(), account.getInstance(), account.getToken()); - apiResponse = api.getNotificationsSince(DisplayNotificationsFragment.Type.ALL, null, false); - } else { - GNUAPI gnuApi = new GNUAPI(getContext(), account.getInstance(), account.getToken()); - apiResponse = gnuApi.getNotificationsSince(DisplayNotificationsFragment.Type.ALL, null); - } - NotificationsHelper.onRetrieveNotifications(getContext(), apiResponse, account); + NotificationsHelper.task(getContext(), account); } } } diff --git a/app/src/main/java/app/fedilab/android/services/UnifiedPushService.java b/app/src/main/java/app/fedilab/android/services/UnifiedPushService.java index 1f40dd643..d85c2676b 100644 --- a/app/src/main/java/app/fedilab/android/services/UnifiedPushService.java +++ b/app/src/main/java/app/fedilab/android/services/UnifiedPushService.java @@ -15,7 +15,6 @@ package app.fedilab.android.services; * see . */ import android.content.Context; import android.database.sqlite.SQLiteDatabase; -import android.util.Log; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -23,12 +22,7 @@ import org.unifiedpush.android.connector.MessagingReceiver; import org.unifiedpush.android.connector.MessagingReceiverHandler; -import app.fedilab.android.client.API; -import app.fedilab.android.client.APIResponse; import app.fedilab.android.client.Entities.Account; -import app.fedilab.android.client.GNUAPI; -import app.fedilab.android.fragments.DisplayNotificationsFragment; -import app.fedilab.android.helper.Helper; import app.fedilab.android.helper.NotificationsHelper; import app.fedilab.android.helper.PushNotifications; import app.fedilab.android.sqlite.AccountDAO; @@ -40,42 +34,31 @@ class handler implements MessagingReceiverHandler { @Override public void onMessage(@Nullable Context context, @NotNull String s, @NotNull String slug) { + new Thread(() -> { SQLiteDatabase db = Sqlite.getInstance(context.getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); String[] slugArray = slug.split("@"); Account account = new AccountDAO(context, db).getUniqAccountUsernameInstance(slugArray[0], slugArray[1]); - APIResponse apiResponse; - if (account.getSocial().compareTo("FRIENDICA") != 0 && account.getSocial().compareTo("GNU") != 0) { - API api = new API(context, account.getInstance(), account.getToken()); - apiResponse = api.getNotificationsSince(DisplayNotificationsFragment.Type.ALL, null, false); - } else { - GNUAPI gnuApi = new GNUAPI(context, account.getInstance(), account.getToken()); - apiResponse = gnuApi.getNotificationsSince(DisplayNotificationsFragment.Type.ALL, null); - } - NotificationsHelper.onRetrieveNotifications(context, apiResponse, account); + NotificationsHelper.task(context, account); }).start(); } @Override public void onNewEndpoint(@Nullable Context context, @NotNull String endpoint, @NotNull String slug) { - Log.v(Helper.TAG, "onNewEndpoint: " + slug); new PushNotifications() .registerPushNotifications(context, endpoint, slug); } @Override public void onRegistrationFailed(@Nullable Context context, @NotNull String s) { - Log.v(Helper.TAG, "onRegistrationFailed"); } @Override public void onRegistrationRefused(@Nullable Context context, @NotNull String s) { - Log.v(Helper.TAG, "onRegistrationFailed"); } @Override public void onUnregistered(@Nullable Context context, @NotNull String s) { - Log.v(Helper.TAG, "onRegistrationFailed"); } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8eecf8373..21e7f8ba4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1241,5 +1241,8 @@ Video cache in MB, zero means no cache. Watermarks Automatically add a watermark at the bottom of pictures. The text can be customized for each account. + No distributors found! + You need a distributor for receiving push notifications.\nYou will find more details at %1$s.\n\nYou can also disable push notifications in settings for ignoring that message. + Select a distributor diff --git a/app/src/playstore/AndroidManifest.xml b/app/src/playstore/AndroidManifest.xml index 00e9f419d..b55a17c82 100644 --- a/app/src/playstore/AndroidManifest.xml +++ b/app/src/playstore/AndroidManifest.xml @@ -1,5 +1,5 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file + diff --git a/app/src/playstore/java/app/fedilab/android/services/HandlerFCM.java b/app/src/playstore/java/app/fedilab/android/services/HandlerFCM.java index 92f32dad8..ed6e3a53d 100644 --- a/app/src/playstore/java/app/fedilab/android/services/HandlerFCM.java +++ b/app/src/playstore/java/app/fedilab/android/services/HandlerFCM.java @@ -11,7 +11,7 @@ public class HandlerFCM implements GetEndpointHandler { @Override public @NotNull String getEndpoint(@Nullable Context context, @NotNull String token, @NotNull String instance) { - return "https://gotify.fedilab.org/UP?token=" + token; + return "https://gotify.fedilab.app/FCM?token=" + token + "&instance=" + instance; }