diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..d2cf345
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,31 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 29
+ buildToolsVersion "29.0.1"
+ defaultConfig {
+ applicationId "com.test.app.myapplication.feed"
+ minSdkVersion 16
+ targetSdkVersion 29
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+
+ implementation 'androidx.appcompat:appcompat:1.1.0'
+ implementation project(path: ':feed_push')
+ implementation 'com.google.firebase:firebase-messaging:20.0.0'
+ implementation 'com.android.volley:volley:1.1.1'
+ implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'com.google.android.material:material:1.0.0'
+
+}
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/app/src/androidTest/java/com/test/app/myapplication/feed/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/test/app/myapplication/feed/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..082e057
--- /dev/null
+++ b/app/src/androidTest/java/com/test/app/myapplication/feed/ExampleInstrumentedTest.java
@@ -0,0 +1,27 @@
+package com.test.app.myapplication.feed;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+
+ assertEquals("com.test.app.myapplication.feed", appContext.getPackageName());
+ }
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..6fee30c
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/assets/google-services.json b/app/src/main/assets/google-services.json
new file mode 100644
index 0000000..5a4a8b0
--- /dev/null
+++ b/app/src/main/assets/google-services.json
@@ -0,0 +1,383 @@
+{
+ "project_info": {
+ "project_number": "969472863896",
+ "firebase_url": "https://fabric-1534989119451.firebaseio.com",
+ "project_id": "fabric-1534989119451",
+ "storage_bucket": "fabric-1534989119451.appspot.com"
+ },
+ "client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:969472863896:android:197df252522ce144",
+ "android_client_info": {
+ "package_name": "app.store.bits.ux.firebasetesting"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyA4LrpivzME6tx0qovh_dQBFachoTdmWMc"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ },
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:969472863896:android:81c0b7ad11a05880",
+ "android_client_info": {
+ "package_name": "app.store.bits.ux.newfirebase"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyA4LrpivzME6tx0qovh_dQBFachoTdmWMc"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ },
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:969472863896:android:e07d8e26ca45cec1",
+ "android_client_info": {
+ "package_name": "auth.app.fabric.com.fabricauth"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "969472863896-7j1g1dvt9uonn3vohucjdo46m3s4105e.apps.googleusercontent.com",
+ "client_type": 1,
+ "android_info": {
+ "package_name": "auth.app.fabric.com.fabricauth",
+ "certificate_hash": "2a8bdbf96bdc9ba47fe43f10d7baa8c347fe6e49"
+ }
+ },
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyA4LrpivzME6tx0qovh_dQBFachoTdmWMc"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ },
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:969472863896:android:cbe2231b516a651c",
+ "android_client_info": {
+ "package_name": "client.messging.bits.fabric.mygreenfingers"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyA4LrpivzME6tx0qovh_dQBFachoTdmWMc"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ },
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:969472863896:android:f1c429ed868ea378",
+ "android_client_info": {
+ "package_name": "com.bits.com.fabrics"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "969472863896-g7v7k0f71d5jnirllge9nnhjsk2fnats.apps.googleusercontent.com",
+ "client_type": 1,
+ "android_info": {
+ "package_name": "com.bits.com.fabrics",
+ "certificate_hash": "49c3b9b6861c3397ba3f0fbe829b756b5b00b22d"
+ }
+ },
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyA4LrpivzME6tx0qovh_dQBFachoTdmWMc"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ },
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:969472863896:android:94a50443efeb9f7e",
+ "android_client_info": {
+ "package_name": "com.bits.com.quick"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "969472863896-i8erov55kamkj76fpk5qrsohdaoicj8s.apps.googleusercontent.com",
+ "client_type": 1,
+ "android_info": {
+ "package_name": "com.bits.com.quick",
+ "certificate_hash": "49c3b9b6861c3397ba3f0fbe829b756b5b00b22d"
+ }
+ },
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyA4LrpivzME6tx0qovh_dQBFachoTdmWMc"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ },
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:969472863896:android:9cfaeeb5d1487d9738aaed",
+ "android_client_info": {
+ "package_name": "com.example.bottes"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyA4LrpivzME6tx0qovh_dQBFachoTdmWMc"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ },
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:969472863896:android:a6bdeec323f6b68738aaed",
+ "android_client_info": {
+ "package_name": "com.feedify.app"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyA4LrpivzME6tx0qovh_dQBFachoTdmWMc"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ },
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:969472863896:android:21df20fca564e3c238aaed",
+ "android_client_info": {
+ "package_name": "com.test.app.feedyfi_push"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyA4LrpivzME6tx0qovh_dQBFachoTdmWMc"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ },
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:969472863896:android:8958098a5585f33a38aaed",
+ "android_client_info": {
+ "package_name": "com.test.app.flutter_notification_test"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyA4LrpivzME6tx0qovh_dQBFachoTdmWMc"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ },
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:969472863896:android:f799d5f394466cf538aaed",
+ "android_client_info": {
+ "package_name": "com.test.app.myapplication.feed"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyA4LrpivzME6tx0qovh_dQBFachoTdmWMc"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ },
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:969472863896:android:c356ed78c02308ef",
+ "android_client_info": {
+ "package_name": "com.test.app.pushapplication"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyA4LrpivzME6tx0qovh_dQBFachoTdmWMc"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "969472863896-35d5o9pq6rbfkofcrio61c3prsb5u0so.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "configuration_version": "1"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/test/app/myapplication/feed/MainActivity.java b/app/src/main/java/com/test/app/myapplication/feed/MainActivity.java
new file mode 100644
index 0000000..c7f6bb6
--- /dev/null
+++ b/app/src/main/java/com/test/app/myapplication/feed/MainActivity.java
@@ -0,0 +1,14 @@
+package com.test.app.myapplication.feed;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import android.os.Bundle;
+
+public class MainActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ }
+}
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..1f6bb29
--- /dev/null
+++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..0d025f9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..4fc2444
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..898f3ed
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..dffca36
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..64ba76f
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..dae5e08
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..e5ed465
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..14ed0af
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b0907ca
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..d8ae031
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..2c18de9
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..beed3cd
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..69b2233
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #008577
+ #00574B
+ #D81B60
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..7533437
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,6 @@
+
+ My Application
+ YOR_USER
+ YOUR_DKEY
+ YOUR_DOMAIN
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..5885930
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/app/src/test/java/com/test/app/myapplication/feed/ExampleUnitTest.java b/app/src/test/java/com/test/app/myapplication/feed/ExampleUnitTest.java
new file mode 100644
index 0000000..5f397ad
--- /dev/null
+++ b/app/src/test/java/com/test/app/myapplication/feed/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.test.app.myapplication.feed;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..80c69c6
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,27 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ google()
+ jcenter()
+
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.5.1'
+ classpath 'com.google.gms:google-services:4.2.0'
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ maven { url 'https://jitpack.io' }
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/feed_push/.gitignore b/feed_push/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/feed_push/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/feed_push/README.md b/feed_push/README.md
new file mode 100644
index 0000000..13cab20
--- /dev/null
+++ b/feed_push/README.md
@@ -0,0 +1,105 @@
+# Feedify SDK (0.0.1)
+
+Feedify SDK is Android API framework built top on [Feedify API](https://feedify.net).
+Implement your feedify notifications in your mobile apps rapidly.
+
+## Installation
+
+Installation is very straightforward, you need to add app in your firebase console. You can follow
+this guide [Firebase Setup](https://firebase.google.com/docs/android/setup). Skip apply google-services plugin,
+this should be handled by Feedify SDK itself. Just download google-services.json.
+
+Now copy this google-services.json into your root of app assets directory this is important step.
+Note this location is different than mentioned in official document, since it's handled by SDK not by plugin.
+
+On your project level gradle make sure to add classpath
+
+ classpath 'com.google.gms:google-services:4.2.0'
+
+Ignore this line in your app level gradle. (do not add this line)
+
+ apply plugin: 'com.google.gms.google-services'
+
+## Dependencies
+Add following dependencies in your app gradle.
+
+ implementation 'com.github.feedify:feed-notify:0.0.1'
+
+ //support dependencies (required by SDK)
+ implementation 'androidx.appcompat:appcompat:1.1.0'
+ implementation "androidx.preference:preference:1.0.0"
+ implementation 'com.google.firebase:firebase-messaging:20.0.0'
+ implementation 'com.android.volley:volley:1.1.1'
+
+## Credentials settings
+Login to your feedify console and set your firebase cloud-messaging
+API Key and project-id under:
+
+ Setting > Setting > Push Sending Settings
+
+Finally add feedify credentials to your app under strings.xml as follow:
+
+ YOR_USER
+ YOUR_DKEY
+ YOUR_DOMAIN
+
+these strings will automatically detect and used by Feedify SDK.
+In case not mentioned you'll get exception.
+Make sure to change your credentials in string value.
+
+That's all done!.
+You can test push notification from your feedify console.
+
+
+## Advanced user
+
+You can extend application class as follow and change notification icon and on click event.
+In case event not defined it will open notification url in browser. Don't forgot to specify
+application class in your app AndroidManifest.xml.
+
+ public class MyApplication extends FeedSDK {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ //set notification small icon (optional)
+ setNotificationIcon(R.drawable.ic_stat_notifications);
+ //this activity will be open when clicked on notification (optional)
+ setStartActivity(MyActivity.class);
+ }
+ }
+
+
+In case you need to handle other firebase notification you can extend 'FirebaseMessagingService' as follow:
+
+
+ public class CustomMessageHandler extends FeedMessagingService {
+
+ //Note all 'FirebaseMessagingService' feature is available since 'FeedMessagingService' extended by 'FeedMessagingService'
+
+ @Override
+ public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
+ super.onMessageReceived(remoteMessage);
+ }
+ }
+
+In your app AndroidManifest.xml:
+
+
+
+
+
+
+
+Additionally you can turn off/on notification as follow:
+
+ // turn off notification
+ FeedSDK.setEnabled(false);
+
+ //check status
+ boolean isEnabled = FeedSDK.isEnabled();
+
+
+## Read more about Feedify
+
+[Feedify](https://feedify.net)
+
\ No newline at end of file
diff --git a/feed_push/build.gradle b/feed_push/build.gradle
new file mode 100644
index 0000000..248a56d
--- /dev/null
+++ b/feed_push/build.gradle
@@ -0,0 +1,34 @@
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion 29
+ buildToolsVersion "29.0.1"
+
+
+ defaultConfig {
+ minSdkVersion 16
+ targetSdkVersion 29
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+
+}
+
+dependencies {
+
+ implementation 'androidx.appcompat:appcompat:1.1.0'
+ implementation "androidx.preference:preference:1.0.0"
+ implementation 'com.google.firebase:firebase-messaging:20.0.0'
+ implementation 'com.android.volley:volley:1.1.1'
+
+}
diff --git a/feed_push/proguard-rules.pro b/feed_push/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/feed_push/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/feed_push/src/androidTest/java/com/feed/sdk/push/ExampleInstrumentedTest.java b/feed_push/src/androidTest/java/com/feed/sdk/push/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..07c1d1d
--- /dev/null
+++ b/feed_push/src/androidTest/java/com/feed/sdk/push/ExampleInstrumentedTest.java
@@ -0,0 +1,27 @@
+package com.feed.sdk.push;
+
+import android.content.Context;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.feed.sdk.push.test", appContext.getPackageName());
+ }
+}
diff --git a/feed_push/src/main/AndroidManifest.xml b/feed_push/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..16c2fd6
--- /dev/null
+++ b/feed_push/src/main/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/feed_push/src/main/java/com/feed/sdk/push/Const.java b/feed_push/src/main/java/com/feed/sdk/push/Const.java
new file mode 100644
index 0000000..a5b70c4
--- /dev/null
+++ b/feed_push/src/main/java/com/feed/sdk/push/Const.java
@@ -0,0 +1,7 @@
+package com.feed.sdk.push;
+
+public class Const {
+ public static final String PUSH_REGISTER="https://feedify.net/push/register";
+ public static final String DELIVER_ENDPOINT="https://deliver.feedify.net/deliver?endpoint";
+ public static final String PREF_ENABLE_KEY="PREF_ENABLE_KEY";
+}
diff --git a/feed_push/src/main/java/com/feed/sdk/push/DataProvider.java b/feed_push/src/main/java/com/feed/sdk/push/DataProvider.java
new file mode 100644
index 0000000..e28dede
--- /dev/null
+++ b/feed_push/src/main/java/com/feed/sdk/push/DataProvider.java
@@ -0,0 +1,40 @@
+package com.feed.sdk.push;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+
+import com.android.volley.Request;
+import com.android.volley.Response;
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.StringRequest;
+import com.feed.sdk.push.common.Logs;
+import com.feed.sdk.push.common.Pref;
+
+public class DataProvider {
+
+ public static void loadData(final Context context){
+ String token = Pref.get(context).getString(FeedMessagingService.FCM_TOKEN,null);
+ if(token!=null) {
+ String dataUrl = String.format("%s=%s", Const.DELIVER_ENDPOINT, token);
+ VolleyManager vm = VolleyManager.getInstance();
+ StringRequest stringRequest = new StringRequest(Request.Method.GET, dataUrl,
+ new Response.Listener() {
+ @SuppressLint("NewApi")
+ @Override
+ public void onResponse(String response) {
+ Logs.d("DataProvider", "Response is: " + response);
+ NotificationProvider.onMessageReceived(context, response);
+ }
+ }, new Response.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ error.printStackTrace();
+ Logs.d("DataProvider", "That didn't work!");
+ }
+ });
+ vm.addRequest(stringRequest, "get_data");
+ }
+ }
+
+
+}
diff --git a/feed_push/src/main/java/com/feed/sdk/push/FeedMessagingService.java b/feed_push/src/main/java/com/feed/sdk/push/FeedMessagingService.java
new file mode 100644
index 0000000..e0cdbe6
--- /dev/null
+++ b/feed_push/src/main/java/com/feed/sdk/push/FeedMessagingService.java
@@ -0,0 +1,33 @@
+package com.feed.sdk.push;
+
+import androidx.annotation.NonNull;
+import com.feed.sdk.push.common.Logs;
+import com.feed.sdk.push.common.Pref;
+import com.google.firebase.messaging.FirebaseMessagingService;
+import com.google.firebase.messaging.RemoteMessage;
+
+
+
+public class FeedMessagingService extends FirebaseMessagingService {
+
+ private static final String TAG = "FeedMessagingService";
+ public static final String FCM_TOKEN = "Feed_FCM_TOKEN";
+
+ @Override
+ public void onMessageReceived(final RemoteMessage remoteMessage) {
+ super.onMessageReceived(remoteMessage);
+ Logs.d("onMessageReceived....");
+ if(FeedSDK.isEnabled())
+ DataProvider.loadData(this);
+
+ }
+
+
+ @Override
+ public void onNewToken(@NonNull String token) {
+ super.onNewToken(token);
+ Logs.i("Token:",token);
+ Pref.get(this).put(FCM_TOKEN,token);
+ FeedRegisterManager.invoke(this);
+ }
+}
diff --git a/feed_push/src/main/java/com/feed/sdk/push/FeedRegisterManager.java b/feed_push/src/main/java/com/feed/sdk/push/FeedRegisterManager.java
new file mode 100644
index 0000000..ace4b57
--- /dev/null
+++ b/feed_push/src/main/java/com/feed/sdk/push/FeedRegisterManager.java
@@ -0,0 +1,79 @@
+package com.feed.sdk.push;
+
+import android.content.Context;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import com.android.volley.Request;
+import com.android.volley.Response;
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.StringRequest;
+import com.feed.sdk.push.common.Logs;
+import com.feed.sdk.push.common.Pref;
+import com.feed.sdk.push.model.ModelDeviceApp;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class FeedRegisterManager {
+
+ private Context context;
+
+ public FeedRegisterManager(Context context) {
+ this.context = context;
+ }
+
+ public static void invoke(Context context){
+ String token = Pref.get(context).getString(FeedMessagingService.FCM_TOKEN, null);
+ if(token!=null) {
+ FeedRegisterManager fm = new FeedRegisterManager(context);
+ fm.register(context,VolleyManager.getInstance(),ModelDeviceApp.getInstance(context), token);
+ }
+ }
+
+ public void register(final Context context, VolleyManager volleyManager, @NonNull final ModelDeviceApp modelDeviceApp, @NonNull final String token) {
+ //put register logic here
+
+
+ final String feedify_user = context.getString(R.string.feedify_user);
+ final String feedify_dkey = context.getString(R.string.feedify_dkey);
+ final String feedify_domain = context.getString(R.string.feedify_domain);
+
+ if(!feedify_dkey.trim().isEmpty()&&!feedify_dkey.trim().isEmpty()&&!feedify_domain.isEmpty()) {
+ Logs.i("Registering token...",true);
+
+ StringRequest stringRequest = new StringRequest(Request.Method.POST, Const.PUSH_REGISTER,
+ new Response.Listener() {
+ @Override
+ public void onResponse(String response) {
+ Logs.e("Token sent!!!",token);
+ }
+ }, new Response.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ Logs.e("That didn't work!");
+ }
+ }) {
+ protected Map getParams() {
+ Map MyData = new HashMap();
+ MyData.put("agent", "Feedify Android Application 1.0");
+ MyData.put("endpoint", "https://fcm.googleapis.com/fcm/send/" + token);
+ MyData.put("registration_id", token);
+ MyData.put("user_id", feedify_user);
+ MyData.put("domkey", feedify_dkey);
+ MyData.put("referrer", feedify_domain);
+ MyData.put("browser", "Android Application");
+ MyData.put("uuid", modelDeviceApp.device_uuid);
+ return MyData;
+ }
+ };
+
+ volleyManager.addRequest(stringRequest, "token_register");
+
+ }
+ else {
+ Logs.e("Feedify","Missing (feedify_user, feedify_dkey, feedify_domain) strings please make sure to update your feedify credentials in strings.xml.");
+ }
+ }
+}
diff --git a/feed_push/src/main/java/com/feed/sdk/push/FeedSDK.java b/feed_push/src/main/java/com/feed/sdk/push/FeedSDK.java
new file mode 100644
index 0000000..26c4daa
--- /dev/null
+++ b/feed_push/src/main/java/com/feed/sdk/push/FeedSDK.java
@@ -0,0 +1,96 @@
+package com.feed.sdk.push;
+
+import android.app.Application;
+import android.content.Context;
+
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+
+import com.feed.sdk.push.common.Logs;
+import com.feed.sdk.push.common.Pref;
+import com.feed.sdk.push.exception.GoogleServiceJsonException;
+import com.feed.sdk.push.model.ModelDeviceApp;
+import com.feed.sdk.push.model.ModelFirebaseApp;
+import com.google.firebase.FirebaseApp;
+import com.google.firebase.FirebaseOptions;
+
+public class FeedSDK extends Application {
+
+ private static final String TAG = "FeedSDK";
+
+ protected static Class activityClass;
+ protected static @DrawableRes int notificationIcon=R.drawable.ic_notification;
+
+ public void setStartActivity(Class activityClass){
+ FeedSDK.activityClass = activityClass;
+ }
+
+ public static void setNotificationIcon(@DrawableRes int icon){
+ notificationIcon=icon;
+ }
+
+ public static void setEnabled(boolean enable){
+ Pref.get(mContext).put(Const.PREF_ENABLE_KEY,enable);
+ }
+
+ public static boolean isEnabled(){
+ return Pref.get(mContext).getBoolean(Const.PREF_ENABLE_KEY,true);
+ }
+
+
+ private static Context mContext;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mContext = this;
+ Logs.setEnabled(BuildConfig.DEBUG);
+ //init network manager
+ VolleyManager.init(this);
+ //init firebase
+ initializeApp(this);
+ //debug logs
+ Logs.i("ModelDeviceApp info...",true);
+ ModelDeviceApp modelDeviceApp = ModelDeviceApp.getInstance(this);
+ Logs.i("device_name",modelDeviceApp.device_name);
+ Logs.i("device_uuid",modelDeviceApp.device_uuid);
+ Logs.i("package_name",modelDeviceApp.package_name);
+ Logs.i("app_name",modelDeviceApp.app_name);
+ Logs.i("platform",modelDeviceApp.platform);
+
+ FeedRegisterManager.invoke(this);
+
+ }
+
+
+ private void initializeApp(@NonNull Context context){
+ try {
+ ModelFirebaseApp modelFirebaseApp = ModelFirebaseApp.getInstance(this);
+
+ Logs.i("ModelFirebaseApp model initiated successfully...",true);
+ Logs.i("api_key",modelFirebaseApp.api_key);
+ Logs.i("firebase_url",modelFirebaseApp.firebase_url);
+ Logs.i("mobilesdk_app_id",modelFirebaseApp.mobilesdk_app_id);
+ Logs.i("project_number",modelFirebaseApp.project_number);
+ Logs.i("storage_bucket",modelFirebaseApp.storage_bucket);
+
+
+ FirebaseApp.initializeApp(context, new FirebaseOptions.Builder().
+ setApiKey(modelFirebaseApp.api_key).
+ setApplicationId(modelFirebaseApp.mobilesdk_app_id).
+ setDatabaseUrl(modelFirebaseApp.firebase_url).
+ setGcmSenderId(modelFirebaseApp.project_number).
+ setStorageBucket(modelFirebaseApp.storage_bucket).build());
+
+ } catch (GoogleServiceJsonException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static String getToken(Context context){
+ return Pref.get(context).getString(FeedMessagingService.FCM_TOKEN,null);
+ }
+
+
+
+}
diff --git a/feed_push/src/main/java/com/feed/sdk/push/NotificationProvider.java b/feed_push/src/main/java/com/feed/sdk/push/NotificationProvider.java
new file mode 100644
index 0000000..81ae850
--- /dev/null
+++ b/feed_push/src/main/java/com/feed/sdk/push/NotificationProvider.java
@@ -0,0 +1,221 @@
+package com.feed.sdk.push;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Build;
+import android.widget.ImageView;
+
+import androidx.core.app.NotificationCompat;
+import androidx.core.app.NotificationManagerCompat;
+
+import com.android.volley.Response;
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.ImageRequest;
+import com.feed.sdk.push.common.Cache;
+import com.feed.sdk.push.model.ModelNotification;
+import com.google.firebase.messaging.RemoteMessage;
+
+import org.json.JSONException;
+
+public class NotificationProvider {
+
+ private ModelNotification model;
+
+ NotificationProvider(ModelNotification model){
+ this.model = model;
+ }
+
+ private void showNotification(final VolleyManager volleyManager,final Context context){
+ String feed_channel="feed_channel";
+ createNotificationChannel(context,feed_channel,"Feed", "Feed notification.", NotificationManager.IMPORTANCE_MAX);
+
+ final NotificationCompat.Builder builder = new NotificationCompat.Builder( context, feed_channel)
+ .setSmallIcon(FeedSDK.notificationIcon)
+ .setContentTitle(model.title)
+ .setContentText(model.body)
+ .setStyle(new NotificationCompat.BigTextStyle()
+ .bigText(model.body))
+ .setAutoCancel(true)
+ .setPriority(NotificationCompat.PRIORITY_MAX);
+
+ PendingIntent pendingIntent = PendingIntent.getActivity(context, model.id, getIntent(context), PendingIntent.FLAG_UPDATE_CURRENT);
+ builder.setContentIntent(pendingIntent);
+ if(model.button!=null)
+ builder.addAction(R.drawable.ic_action_open,model.button,pendingIntent);
+
+ if(model.icon!=null&&model.image==null){
+ Bitmap bitmap = Cache.getBitmap(context,model.icon);
+ if(bitmap==null) {
+ ImageRequest request = new ImageRequest(model.icon, new Response.Listener() {
+ @Override
+ public void onResponse(Bitmap response) {
+ Cache.save_bitmap(context,model.icon,response);
+ builder.setLargeIcon(response);
+ NotificationManagerCompat.from(context).notify(model.id, builder.build());
+ }
+ }, 0, 0, ImageView.ScaleType.CENTER, null, new Response.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ error.printStackTrace();
+ }
+ });
+ volleyManager.addRequest(request, "remote_icon");
+ }
+ else {
+ builder.setLargeIcon(bitmap);
+ NotificationManagerCompat.from(context).notify(model.id, builder.build());
+ }
+
+
+ }
+ else if(model.icon==null&&model.image!=null){
+ Bitmap bitmap = Cache.getBitmap(context,model.image);
+ if(bitmap==null) {
+ ImageRequest requestImage = new ImageRequest(model.image, new Response.Listener() {
+ @Override
+ public void onResponse(Bitmap response) {
+ Cache.save_bitmap(context,model.image,response);
+ builder.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(response));
+ NotificationManagerCompat.from(context).notify(model.id, builder.build());
+ }
+ }, 0, 0, ImageView.ScaleType.CENTER, null, new Response.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ error.printStackTrace();
+ }
+ });
+ volleyManager.addRequest(requestImage, "remote_image");
+ }
+ else {
+ builder.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(bitmap));
+ NotificationManagerCompat.from(context).notify(model.id, builder.build());
+ }
+ }
+
+ else if(model.icon!=null&&model.image!=null) {
+ final Bitmap bitmap = Cache.getBitmap(context, model.icon);
+ if (bitmap == null) {
+ ImageRequest request = new ImageRequest(model.icon, new Response.Listener() {
+ @Override
+ public void onResponse(Bitmap response) {
+ Cache.save_bitmap(context,model.icon,response);
+ builder.setLargeIcon(response);
+ Bitmap bitmapLarge = Cache.getBitmap(context, model.image);
+ if(bitmapLarge==null) {
+ ImageRequest requestImage = new ImageRequest(model.image, new Response.Listener() {
+ @Override
+ public void onResponse(Bitmap response) {
+ Cache.save_bitmap(context,model.image,response);
+ builder.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(response));
+ NotificationManagerCompat.from(context).notify(model.id, builder.build());
+ }
+ }, 0, 0, ImageView.ScaleType.CENTER, null, new Response.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ error.printStackTrace();
+ }
+ });
+ volleyManager.addRequest(requestImage, "remote_image");
+ }
+ else {
+ builder.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(bitmapLarge));
+ NotificationManagerCompat.from(context).notify(model.id, builder.build());
+ }
+
+ }
+ }, 0, 0, ImageView.ScaleType.CENTER, null, new Response.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ error.printStackTrace();
+ }
+ });
+ volleyManager.addRequest(request, "remote_icon");
+ }
+ else {
+ builder.setLargeIcon(bitmap);
+ Bitmap bitmapLarge = Cache.getBitmap(context, model.image);
+ if(bitmapLarge==null) {
+ ImageRequest requestImage = new ImageRequest(model.image, new Response.Listener() {
+ @Override
+ public void onResponse(Bitmap response) {
+ Cache.save_bitmap(context,model.image,response);
+ builder.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(response));
+ NotificationManagerCompat.from(context).notify(model.id, builder.build());
+ }
+ }, 0, 0, ImageView.ScaleType.CENTER, null, new Response.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ error.printStackTrace();
+ }
+ });
+ volleyManager.addRequest(requestImage, "remote_image");
+ }
+ else {
+ builder.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(bitmapLarge));
+ NotificationManagerCompat.from(context).notify(model.id, builder.build());
+ }
+ }
+ }
+ else {
+ NotificationManagerCompat.from(context).notify(model.id, builder.build());
+ }
+
+
+ }
+
+ private Intent getIntent(Context context){
+ if(FeedSDK.activityClass!=null){
+ Intent intent = new Intent(context, FeedSDK.activityClass);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ return intent;
+ }
+ else if(model.url!=null) {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.setData(Uri.parse(model.url));
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ return intent;
+ }
+ else {
+ PackageManager pm = context.getPackageManager();
+ Intent intent = pm.getLaunchIntentForPackage(context.getPackageName());
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ return intent;
+ }
+ }
+
+ public static void onMessageReceived(Context context, String jsonString){
+ try {
+ ModelNotification model = ModelNotification.getInstance(jsonString);
+ NotificationProvider np = new NotificationProvider(model);
+ np.showNotification(VolleyManager.getInstance(),context);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ public static void onMessageReceived(Context context, RemoteMessage remoteMessage){
+ try {
+ ModelNotification model = ModelNotification.getInstance(remoteMessage);
+ NotificationProvider np = new NotificationProvider(model);
+ np.showNotification(VolleyManager.getInstance(),context);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ private static void createNotificationChannel(Context context,String channel_id, String channel_name, String channel_description, int importance) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ NotificationChannel channel = new NotificationChannel(channel_id, channel_name, importance);
+ channel.setDescription(channel_description);
+ NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
+ notificationManager.createNotificationChannel(channel);
+ }
+ }
+
+
+
+}
diff --git a/feed_push/src/main/java/com/feed/sdk/push/VolleyManager.java b/feed_push/src/main/java/com/feed/sdk/push/VolleyManager.java
new file mode 100644
index 0000000..e81e075
--- /dev/null
+++ b/feed_push/src/main/java/com/feed/sdk/push/VolleyManager.java
@@ -0,0 +1,50 @@
+package com.feed.sdk.push;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+
+import com.android.volley.Request;
+import com.android.volley.RequestQueue;
+import com.android.volley.toolbox.Volley;
+
+public class VolleyManager {
+
+
+ private RequestQueue mRequestQueue;
+ private static VolleyManager mInstance;
+ private Context context;
+
+
+ public VolleyManager(Context context){
+ this.context = context;
+ }
+
+
+ public static void init(Context context){
+ mInstance = new VolleyManager(context);
+ }
+
+
+ public static synchronized VolleyManager getInstance() {
+ return mInstance;
+ }
+
+ public RequestQueue getRequestQueue() {
+ if (mRequestQueue == null)
+ mRequestQueue = Volley.newRequestQueue(context);
+ return mRequestQueue;
+ }
+
+ public void addRequest(Request req, @NonNull String tag) {
+ req.setTag(tag);
+ getRequestQueue().add(req);
+ }
+
+ public void cancelRequests(String tag) {
+ if (mRequestQueue != null) {
+ mRequestQueue.cancelAll(tag);
+ }
+ }
+
+}
diff --git a/feed_push/src/main/java/com/feed/sdk/push/common/Assets.java b/feed_push/src/main/java/com/feed/sdk/push/common/Assets.java
new file mode 100644
index 0000000..2385a30
--- /dev/null
+++ b/feed_push/src/main/java/com/feed/sdk/push/common/Assets.java
@@ -0,0 +1,17 @@
+package com.feed.sdk.push.common;
+
+import android.content.Context;
+
+import java.io.IOException;
+import java.io.InputStream;
+public class Assets {
+
+ public static String textFileToString(Context context,String fileName) throws IOException {
+ InputStream inputStream = context.getAssets().open(fileName);
+ int size = inputStream.available();
+ byte[] buffer = new byte[size];
+ inputStream.read(buffer);
+ inputStream.close();
+ return new String(buffer);
+ }
+}
diff --git a/feed_push/src/main/java/com/feed/sdk/push/common/Cache.java b/feed_push/src/main/java/com/feed/sdk/push/common/Cache.java
new file mode 100644
index 0000000..60d7e13
--- /dev/null
+++ b/feed_push/src/main/java/com/feed/sdk/push/common/Cache.java
@@ -0,0 +1,78 @@
+package com.feed.sdk.push.common;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.util.Base64;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+public class Cache {
+
+ public static void save_bitmap(Context context, String key, Bitmap bitmap) {
+ key = Base64.encodeToString(key.getBytes(),Base64.DEFAULT);
+ Logs.e("=========key====save======",key);
+ if (bitmap != null) {
+ File cacheDir = context.getCacheDir();
+ File file = new File(cacheDir, key);
+ try {
+ FileOutputStream out = new FileOutputStream(file);
+ bitmap.compress(Bitmap.CompressFormat.PNG, 0, out);
+ out.flush();
+ out.close();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static Bitmap getBitmap(Context context, String key) {
+ key = Base64.encodeToString(key.getBytes(),Base64.DEFAULT);
+ Logs.e("=========key====take======",key);
+ File cacheDir = context.getCacheDir();
+ File file = new File(cacheDir, key);
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(file);
+ } catch (FileNotFoundException e) {
+ }
+ if (fis != null) {
+ return BitmapFactory.decodeStream(fis);
+ }
+ return null;
+
+ }
+
+ public static long getLastModified(Context context, String key){
+ return new File(context.getCacheDir(), key).lastModified();
+ }
+
+ public static void deleteCache(Context context) {
+ try {
+ File dir = context.getCacheDir();
+ if (dir != null && dir.isDirectory()) {
+ deleteDir(dir);
+ }
+ } catch (Exception e) {
+ }
+ }
+
+ public static boolean deleteDir(File dir) {
+ if (dir != null && dir.isDirectory()) {
+ String[] children = dir.list();
+ for (int i = 0; i < children.length; i++) {
+ boolean success = deleteDir(new File(dir, children[i]));
+ if (!success) {
+ return false;
+ }
+ }
+ }
+ return dir.delete();
+ }
+}
diff --git a/feed_push/src/main/java/com/feed/sdk/push/common/Logs.java b/feed_push/src/main/java/com/feed/sdk/push/common/Logs.java
new file mode 100644
index 0000000..d3bc52d
--- /dev/null
+++ b/feed_push/src/main/java/com/feed/sdk/push/common/Logs.java
@@ -0,0 +1,106 @@
+package com.feed.sdk.push.common;
+
+import android.util.Log;
+import java.util.List;
+
+
+public class Logs {
+
+
+ public static boolean enabled;
+ public static List debuggingClasses;
+
+ public static void setEnabled(boolean enable) {
+ enabled = enable;
+ }
+
+ public static void setDebuggingOn(List classes) {
+ debuggingClasses = classes;
+ }
+
+ public static void debug(Class clazz, String string) {
+ if (debuggingClasses!=null && debuggingClasses.contains(clazz))
+ Log.i("Logs", string);
+ }
+
+ public static void debug(Class clazz, String key, String string) {
+ if (debuggingClasses!=null && debuggingClasses.contains(clazz))
+ Log.i(key, string);
+ }
+
+ @Deprecated
+ public static void print(String string) {
+ if (enabled)
+ Log.d("Logs", string);
+ }
+
+ @Deprecated
+ public static void print(String key, String string) {
+ if (enabled)
+ Log.d(key, string);
+ }
+
+ public static void d(String string) {
+ if (enabled)
+ Log.d("Logs", string);
+ }
+
+ public static void d(String key, String string) {
+ if (enabled)
+ Log.d(key, string);
+ }
+
+ //
+ public static void e(String string) {
+ if (enabled)
+ Log.e("Logs", string);
+ }
+
+ public static void e(String key, String string) {
+ if (enabled)
+ Log.e(key, string);
+ }
+
+
+ //
+ public static void w(String string) {
+ if (enabled)
+ Log.w("Logs", string);
+ }
+
+ public static void w(String key, String string) {
+ if (enabled)
+ Log.w(key, string);
+ }
+
+ //
+ public static void i(String string) {
+ if (enabled)
+ Log.i("Logs", string);
+ }
+
+ public static void i(String string,boolean header) {
+ if (enabled) {
+ Log.i("Logs", string);
+ Logs.i("---------------------------------------------------------");
+ }
+ }
+
+
+ public static void i(String key, String string) {
+ if (enabled)
+ Log.i(key, string);
+ }
+
+
+ //
+ public static void v(String string) {
+ if (enabled)
+ Log.v("Logs", string);
+ }
+
+ public static void v(String key, String string) {
+ if (enabled)
+ Log.v(key, string);
+ }
+}
diff --git a/feed_push/src/main/java/com/feed/sdk/push/common/Pref.java b/feed_push/src/main/java/com/feed/sdk/push/common/Pref.java
new file mode 100644
index 0000000..3058ad2
--- /dev/null
+++ b/feed_push/src/main/java/com/feed/sdk/push/common/Pref.java
@@ -0,0 +1,110 @@
+package com.feed.sdk.push.common;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.SharedPreferences;
+
+import androidx.preference.PreferenceManager;
+
+@SuppressLint("NewApi")
+public class Pref {
+ private SharedPreferences privatePref;
+ private SharedPreferences editablePref;
+ private String KEY_PREFERENCE_ID = "astro_lab";
+
+
+
+ public String default_secure_key="ad8e75cf";
+
+
+ public static Pref get(Context context){
+ return new Pref(context);
+ }
+ public static Pref get(Context context, String prefs){
+ return new Pref(context,prefs);
+ }
+
+
+ public Pref(Context context) {
+ privatePref = context.getSharedPreferences(KEY_PREFERENCE_ID, Context.MODE_PRIVATE);
+ editablePref= PreferenceManager.getDefaultSharedPreferences(context);
+ }
+
+ public Pref(Context context, String prefKey) {
+ privatePref = context.getSharedPreferences(prefKey, Context.MODE_PRIVATE);
+ editablePref= PreferenceManager.getDefaultSharedPreferences(context);
+ }
+
+ public void put(String name, String data) {
+ privatePref.edit().putString(name, data).commit();
+ }
+
+ public String getString(String name, String data) {
+ return privatePref.getString(name, data);
+ }
+
+
+ public void put(String name, boolean data) {
+
+ privatePref.edit().putBoolean(name, data).commit();
+ }
+
+ public void put(String name, int data) {
+
+ privatePref.edit().putInt(name, data).commit();
+ }
+
+ public void put(String name, float data) {
+
+ privatePref.edit().putFloat(name, data).commit();
+
+ }
+
+ public void put(String name, long data) {
+
+ privatePref.edit().putLong(name, data).commit();
+ }
+
+
+ public boolean getBoolean(String name, boolean data) {
+
+ return privatePref.getBoolean(name, data);
+ }
+
+ public int getInt(String name, int data) {
+
+ return privatePref.getInt(name, data);
+ }
+
+ public float getFloat(String name, float data) {
+
+ return privatePref.getFloat(name, data);
+
+ }
+
+ public long getLong(String name, long data) {
+ return privatePref.getLong(name, data);
+ }
+
+ public String getEditableString(String name, String data) {
+
+ return editablePref.getString(name, data);
+ }
+ public boolean getEditableBoolean(String name, boolean data) {
+
+ return editablePref.getBoolean(name, data);
+ }
+ public void putEditable(String name, String data) {
+ editablePref.edit().putString(name, data).commit();
+ }
+ public void putEditable(String name, boolean data) {
+ editablePref.edit().putBoolean(name, data).commit();
+ }
+ public void clearAll(){
+ privatePref.edit().clear().commit();
+ }
+
+ public void clear(String key){
+ privatePref.edit().remove(key).commit();
+ }
+}
diff --git a/feed_push/src/main/java/com/feed/sdk/push/exception/GoogleServiceJsonException.java b/feed_push/src/main/java/com/feed/sdk/push/exception/GoogleServiceJsonException.java
new file mode 100644
index 0000000..136ad55
--- /dev/null
+++ b/feed_push/src/main/java/com/feed/sdk/push/exception/GoogleServiceJsonException.java
@@ -0,0 +1,9 @@
+package com.feed.sdk.push.exception;
+
+public class GoogleServiceJsonException extends Exception {
+
+ public GoogleServiceJsonException(String message) {
+ super(message);
+ }
+
+}
diff --git a/feed_push/src/main/java/com/feed/sdk/push/model/ModelDeviceApp.java b/feed_push/src/main/java/com/feed/sdk/push/model/ModelDeviceApp.java
new file mode 100644
index 0000000..ec5c9db
--- /dev/null
+++ b/feed_push/src/main/java/com/feed/sdk/push/model/ModelDeviceApp.java
@@ -0,0 +1,28 @@
+package com.feed.sdk.push.model;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import com.feed.sdk.push.R;
+
+public class ModelDeviceApp {
+
+ public String device_name;
+ public String package_name;
+ public String device_uuid;
+ public String app_name;
+ public String platform;
+
+
+ public static ModelDeviceApp getInstance(Context context){
+ ModelDeviceApp modelDeviceApp = new ModelDeviceApp();
+ modelDeviceApp.device_uuid = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
+ modelDeviceApp.device_name = android.os.Build.MODEL;
+ modelDeviceApp.platform = "android";
+ modelDeviceApp.app_name = context.getString(R.string.app_name);
+ modelDeviceApp.package_name = context.getPackageName();
+ return modelDeviceApp;
+ }
+
+
+}
diff --git a/feed_push/src/main/java/com/feed/sdk/push/model/ModelFirebaseApp.java b/feed_push/src/main/java/com/feed/sdk/push/model/ModelFirebaseApp.java
new file mode 100644
index 0000000..62cd5cf
--- /dev/null
+++ b/feed_push/src/main/java/com/feed/sdk/push/model/ModelFirebaseApp.java
@@ -0,0 +1,63 @@
+package com.feed.sdk.push.model;
+
+import android.content.Context;
+
+import com.feed.sdk.push.R;
+import com.feed.sdk.push.common.Assets;
+import com.feed.sdk.push.exception.GoogleServiceJsonException;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.IOException;
+
+public class ModelFirebaseApp {
+
+ private static final String TAG = "ModelFirebaseApp";
+
+ public String api_key;
+ public String mobilesdk_app_id;
+ public String project_number;
+ public String firebase_url;
+ public String storage_bucket;
+
+
+ public static ModelFirebaseApp getInstance(Context context) throws GoogleServiceJsonException {
+ try {
+ String googleServicesJson = Assets.textFileToString(context,"google-services.json");
+
+ JSONObject root = new JSONObject(googleServicesJson);
+ JSONObject project_info = root.getJSONObject("project_info");
+ JSONArray client = root.getJSONArray("client");
+
+ for(int i=0;i
+
+
diff --git a/feed_push/src/main/res/drawable-hdpi/ic_action_open.png b/feed_push/src/main/res/drawable-hdpi/ic_action_open.png
new file mode 100644
index 0000000..3e4f148
Binary files /dev/null and b/feed_push/src/main/res/drawable-hdpi/ic_action_open.png differ
diff --git a/feed_push/src/main/res/drawable-hdpi/ic_notification.png b/feed_push/src/main/res/drawable-hdpi/ic_notification.png
new file mode 100644
index 0000000..bf84665
Binary files /dev/null and b/feed_push/src/main/res/drawable-hdpi/ic_notification.png differ
diff --git a/feed_push/src/main/res/drawable-mdpi/ic_action_open.png b/feed_push/src/main/res/drawable-mdpi/ic_action_open.png
new file mode 100644
index 0000000..7af03c5
Binary files /dev/null and b/feed_push/src/main/res/drawable-mdpi/ic_action_open.png differ
diff --git a/feed_push/src/main/res/drawable-mdpi/ic_notification.png b/feed_push/src/main/res/drawable-mdpi/ic_notification.png
new file mode 100644
index 0000000..c46a983
Binary files /dev/null and b/feed_push/src/main/res/drawable-mdpi/ic_notification.png differ
diff --git a/feed_push/src/main/res/drawable-xhdpi/ic_action_open.png b/feed_push/src/main/res/drawable-xhdpi/ic_action_open.png
new file mode 100644
index 0000000..642ea31
Binary files /dev/null and b/feed_push/src/main/res/drawable-xhdpi/ic_action_open.png differ
diff --git a/feed_push/src/main/res/drawable-xhdpi/ic_notification.png b/feed_push/src/main/res/drawable-xhdpi/ic_notification.png
new file mode 100644
index 0000000..d55ee08
Binary files /dev/null and b/feed_push/src/main/res/drawable-xhdpi/ic_notification.png differ
diff --git a/feed_push/src/main/res/drawable-xxhdpi/ic_action_open.png b/feed_push/src/main/res/drawable-xxhdpi/ic_action_open.png
new file mode 100644
index 0000000..d6682c0
Binary files /dev/null and b/feed_push/src/main/res/drawable-xxhdpi/ic_action_open.png differ
diff --git a/feed_push/src/main/res/drawable-xxhdpi/ic_notification.png b/feed_push/src/main/res/drawable-xxhdpi/ic_notification.png
new file mode 100644
index 0000000..3a6f10e
Binary files /dev/null and b/feed_push/src/main/res/drawable-xxhdpi/ic_notification.png differ
diff --git a/feed_push/src/main/res/drawable-xxxhdpi/ic_notification.png b/feed_push/src/main/res/drawable-xxxhdpi/ic_notification.png
new file mode 100644
index 0000000..e7bde00
Binary files /dev/null and b/feed_push/src/main/res/drawable-xxxhdpi/ic_notification.png differ
diff --git a/feed_push/src/main/res/values/strings.xml b/feed_push/src/main/res/values/strings.xml
new file mode 100644
index 0000000..bb0f645
--- /dev/null
+++ b/feed_push/src/main/res/values/strings.xml
@@ -0,0 +1,17 @@
+
+ feed_push
+
+
+ Error google-services.json not found in assets please make sure to place correct google-services.json file in assets.
+ Invalid google-services.json data please make sure to place correct google-services.json file in assets.
+ Error google-services.json not contain given app package.
+
+
+
+
+
+
+
+
+
+
diff --git a/feed_push/src/test/java/com/feed/sdk/push/ExampleUnitTest.java b/feed_push/src/test/java/com/feed/sdk/push/ExampleUnitTest.java
new file mode 100644
index 0000000..14103e6
--- /dev/null
+++ b/feed_push/src/test/java/com/feed/sdk/push/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.feed.sdk.push;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..199d16e
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,20 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Automatically convert third-party libraries to use AndroidX
+android.enableJetifier=true
+
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..f6b961f
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..9efcc9f
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Sat Nov 16 12:26:24 IST 2019
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..cccdd3d
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..f955316
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..95d108f
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,2 @@
+include ':app', ':feed_push'
+rootProject.name='My Application'