diff --git a/app/build.gradle b/app/build.gradle
index a716129..3714b87 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -35,8 +35,11 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
- implementation "org.jmonkeyengine:jme3-core:3.4.0-beta3"
- implementation "org.jmonkeyengine:jme3-effects:3.4.0-beta3"
- implementation "org.jmonkeyengine:jme3-android-native:3.4.0-beta3"
+ implementation "org.jmonkeyengine:jme3-core:3.4.0-beta4"
+ implementation "org.jmonkeyengine:jme3-effects:3.4.0-beta4"
+ implementation "org.jmonkeyengine:jme3-android-native:3.4.0-beta4"
implementation 'com.github.Scrappers-glitch:Superior-Extended-Engine:1.5.1-alpha2'
+ implementation "androidx.work:work-runtime:2.5.0"
+ implementation "androidx.concurrent:concurrent-futures:1.1.0"
+
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index fc24eb5..ad7fa12 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -22,6 +22,9 @@
+
diff --git a/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/AnimationFactory.java b/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/AnimationFactory.java
index d7985a4..4c6cd69 100644
--- a/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/AnimationFactory.java
+++ b/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/AnimationFactory.java
@@ -5,14 +5,17 @@
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.app.Activity;
+import android.app.NotificationManager;
+import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable;
+import android.net.Uri;
+import android.os.Build;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
-import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.GridLayout;
import android.widget.ImageView;
@@ -21,9 +24,11 @@
import android.widget.Toast;
import com.jme3.anim.AnimComposer;
import com.jme3.anim.TransformTrack;
+import com.jme3.anim.tween.action.Action;
import com.jme3.app.Application;
import com.jme3.app.jmeSurfaceView.JmeSurfaceView;
import com.jme3.app.state.BaseAppState;
+import com.jme3.math.ColorRGBA;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.scrappers.dbtraining.R;
@@ -38,10 +43,16 @@
import com.scrappers.dbtraining.mainScreens.prefaceScreen.renderer.animationWrapper.builders.AnimEventEntity;
import com.scrappers.dbtraining.mainScreens.prefaceScreen.renderer.triggersUtils.TriggerID;
import com.scrappers.dbtraining.mainScreens.prefaceScreen.renderer.triggersUtils.TriggerModel;
+import com.scrappers.dbtraining.notifications.NotificationUtils;
import com.scrappers.superiorExtendedEngine.menuStates.UiStateManager;
import com.scrappers.superiorExtendedEngine.menuStates.UiStatesLooper;
import com.scrappers.superiorExtendedEngine.menuStates.uiPager.UiPager;
+
+import java.io.File;
+import java.io.IOException;
import java.util.Objects;
+
+import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import static android.view.View.GONE;
@@ -52,6 +63,7 @@
import static com.scrappers.dbtraining.mainScreens.prefaceScreen.renderer.Scene.defaultStack;
import static com.scrappers.dbtraining.mainScreens.prefaceScreen.renderer.Scene.defaultThree;
import static com.scrappers.dbtraining.mainScreens.prefaceScreen.renderer.Scene.defaultTwo;
+import static com.scrappers.dbtraining.notifications.BackgroundTask.NOTIFICATION_REQUEST;
/**
* @author pavl_g
@@ -66,6 +78,8 @@ public class AnimationFactory extends BaseAppState implements View.OnClickListen
private float timer=0.0f;
private static final char SCROLLABLE_CONTENT = 'S' + 'C' + 'R' + 'O' + 'L' + 'L';
private static boolean gridOn = false;
+ private EmitterTween emitterTween;
+
public AnimationFactory(Spatial dataBaseStack, JmeSurfaceView jmeSurfaceView) {
this.dataBaseStack=dataBaseStack;
this.jmeSurfaceView=jmeSurfaceView;
@@ -109,26 +123,26 @@ protected void initialize(Application app) {
getStateManager().attach(new BasicArmature("BasicArmatureTrack", dataBaseStack));
getStateManager().attach(new StackLoops("StackLoopsTrack", dataBaseStack));
getStateManager().attach(new BasicTween("BasicTweenTrack", dataBaseStack));
- EmitterTween emitterTween = new EmitterTween("EmitterTween", dataBaseStack);
+ emitterTween = new EmitterTween("EmitterTween", dataBaseStack);
emitterTween.setAnimationEvents(new AnimEventEntity.AnimationEvents() {
@Override
- public void onAnimationStart(AnimComposer animComposer, TransformTrack transformationStart) {
+ public void onAnimationStart(AnimComposer animComposer, Action transformationStart) {
}
@Override
- public void onAnimationEnd(AnimComposer animComposer, TransformTrack transformEnd) {
+ public void onAnimationEnd(AnimComposer animComposer, Action transformEnd) {
jmeSurfaceView.getLegacyApplication().enqueue(()->{
-// emitterTween.electricWaves1.getMaterial().setColor("GlowColor",ColorRGBA.randomColor().mult(ColorRGBA.Blue));
-// emitterTween.electricWaves2.getMaterial().setColor("GlowColor",ColorRGBA.randomColor().mult(ColorRGBA.Blue));
-// emitterTween.electricWaves3.getMaterial().setColor("GlowColor",ColorRGBA.randomColor().mult(ColorRGBA.Blue));
-// emitterTween.electricWaves4.getMaterial().setColor("GlowColor",ColorRGBA.randomColor().mult(ColorRGBA.Blue));
-// emitterTween.electricWaves5.getMaterial().setColor("GlowColor",ColorRGBA.randomColor().mult(ColorRGBA.Blue));
-// emitterTween.electricWaves6.getMaterial().setColor("GlowColor",ColorRGBA.randomColor().mult(ColorRGBA.Blue));
-// emitterTween.electricWaves7.getMaterial().setColor("GlowColor",ColorRGBA.randomColor().mult(ColorRGBA.Blue));
-// emitterTween.electricWaves8.getMaterial().setColor("GlowColor",ColorRGBA.randomColor().mult(ColorRGBA.Blue));
-// emitterTween.electricWaves9.getMaterial().setColor("GlowColor",ColorRGBA.randomColor().mult(ColorRGBA.Blue));
-// emitterTween.electricWaves10.getMaterial().setColor("GlowColor",ColorRGBA.randomColor().mult(ColorRGBA.Blue));
+ emitterTween.electricWaves1.getMaterial().setColor("GlowColor", ColorRGBA.randomColor());
+ emitterTween.electricWaves2.getMaterial().setColor("GlowColor",ColorRGBA.randomColor());
+ emitterTween.electricWaves3.getMaterial().setColor("GlowColor",ColorRGBA.randomColor());
+ emitterTween.electricWaves4.getMaterial().setColor("GlowColor",ColorRGBA.randomColor());
+ emitterTween.electricWaves5.getMaterial().setColor("GlowColor",ColorRGBA.randomColor());
+ emitterTween.electricWaves6.getMaterial().setColor("GlowColor",ColorRGBA.randomColor());
+ emitterTween.electricWaves7.getMaterial().setColor("GlowColor",ColorRGBA.randomColor());
+ emitterTween.electricWaves8.getMaterial().setColor("GlowColor",ColorRGBA.randomColor());
+ emitterTween.electricWaves9.getMaterial().setColor("GlowColor",ColorRGBA.randomColor());
+ emitterTween.electricWaves10.getMaterial().setColor("GlowColor",ColorRGBA.randomColor());
});
}
@@ -177,6 +191,7 @@ public void update(float tpf) {
}
}
+ @RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onClick(View v) {
if(v.getId()==R.id.animationSettings){
@@ -200,7 +215,16 @@ public void onClick(View v) {
}
});
Toast.makeText(jmeSurfaceView.getContext(),"Resettled the Scene !", LENGTH_LONG).show();
-
+ emitterTween.electricWaves1.getMaterial().setColor("GlowColor", ColorRGBA.Cyan.mult(50f));
+ emitterTween.electricWaves2.getMaterial().setColor("GlowColor",ColorRGBA.Cyan.mult(50f));
+ emitterTween.electricWaves3.getMaterial().setColor("GlowColor",ColorRGBA.Cyan.mult(50f));
+ emitterTween.electricWaves4.getMaterial().setColor("GlowColor",ColorRGBA.Cyan.mult(50f));
+ emitterTween.electricWaves5.getMaterial().setColor("GlowColor",ColorRGBA.Cyan.mult(50f));
+ emitterTween.electricWaves6.getMaterial().setColor("GlowColor",ColorRGBA.Cyan.mult(50f));
+ emitterTween.electricWaves7.getMaterial().setColor("GlowColor",ColorRGBA.Cyan.mult(50f));
+ emitterTween.electricWaves8.getMaterial().setColor("GlowColor",ColorRGBA.Cyan.mult(50f));
+ emitterTween.electricWaves9.getMaterial().setColor("GlowColor",ColorRGBA.Cyan.mult(50f));
+ emitterTween.electricWaves10.getMaterial().setColor("GlowColor",ColorRGBA.Cyan.mult(50f));
}else if(v.getId() == R.id.gridSwitcher){
if(gridOn){
gridOn = false;
@@ -217,8 +241,12 @@ public void onClick(View v) {
R.color.lightBlack),ContextCompat.getColor(v.getContext(),R.color.lightBlack)});
invalidateUiPager(gridOn);
}else if(v.getId() == R.id.dismissForever){
+
((ViewGroup)((ViewGroup)v.getParent()).getParent()).setVisibility(GONE);
Toast.makeText(jmeSurfaceView.getContext(), "Powered By Jme Android", Toast.LENGTH_LONG).show();
+
+ NotificationUtils.initializeInBackground(jmeSurfaceView.getContext());
+
}else if(v.getId() == TriggerID.closeTrigger){
((RelativeLayout)jmeSurfaceView.getParent()).findViewById(R.id.animationSettings).animate().setDuration(600).rotation(-45).start();
@@ -381,9 +409,7 @@ protected void invalidateUiPager(boolean gridOn){
}
uiPager.attachUiState(relativeLayout, UiPager.SEQUENTIAL_ADD);
}
- uiPager.attachUiState(topUpMenu ,0);
uiPager.invalidate();
-
}
/**
diff --git a/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/animationWrapper/BlendableAnimation.java b/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/animationWrapper/BlendableAnimation.java
index 4cf6cfe..c6fad13 100644
--- a/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/animationWrapper/BlendableAnimation.java
+++ b/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/animationWrapper/BlendableAnimation.java
@@ -46,6 +46,8 @@ public class BlendableAnimation extends BaseAppState implements BlendSpace {
private BlendAction blendAction;
private BaseAction baseAction;
private float count = 0;
+ private static final float minValueOfBlendSlider = 6;
+ private static final float maxValueOfBlendSlider = 12;
public BlendableAnimation(final String id, final Spatial dataBaseStack){
super(id);
this.dataBaseStack=dataBaseStack;
@@ -98,8 +100,7 @@ protected void initialize(Application app) {
capRotationClip.setLength(10f);
capRotationClip.setTransitionLength(10f);
//9)feed the BlendableActions to a single BlendAction
- float minValueOfBlendSlider = 6;
- float maxValueOfBlendSlider = 12;
+
linearBlendSpace = new LinearBlendSpace(minValueOfBlendSlider, maxValueOfBlendSlider);
linearBlendSpace.setValue(FastMath.interpolateLinear(0.5f, 6, 12));
blendAction=new BlendAction(linearBlendSpace, capRotationClip, bottleTractionClip);
@@ -139,7 +140,7 @@ protected void onDisable() {
public void update(float tpf) {
count += tpf;
if(count > blendAction.getLength()){
- linearBlendSpace.setValue(FastMath.interpolateLinear(1, 6, 12));
+ linearBlendSpace.setValue(FastMath.interpolateLinear(1f, minValueOfBlendSlider, maxValueOfBlendSlider));
}
}
diff --git a/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/animationWrapper/EmitterTween.java b/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/animationWrapper/EmitterTween.java
index 1188def..df35c5f 100644
--- a/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/animationWrapper/EmitterTween.java
+++ b/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/animationWrapper/EmitterTween.java
@@ -154,7 +154,6 @@ protected void initialize(Application app) {
electricWavesTrack10.setTarget(electricWaves10);
shockThunderTrack.setTarget(shockThunder);
- setTransformTrack(electricWavesTrack1);
//1st track
electricWavesTrack1.setTimes(new float[]{2,4,8,16});
@@ -324,6 +323,8 @@ protected void initialize(Application app) {
//make a new Animation Layer that would hold a one current running action.....
animComposer.makeLayer(LayerBuilder.LAYER_EMITTER_TWEEN, new ArmatureMask());
+ setAction(shockMyScreen);
+
}
@Override
@@ -346,6 +347,7 @@ protected void onEnable() {
animComposer.setEnabled(true);
//run shockMyScreen action
animComposer.setCurrentAction("ShockMyScreen", LayerBuilder.LAYER_EMITTER_TWEEN);
+
}
if(shockThunder!=null &&
(shockThunder.getStatus()== AudioSource.Status.Paused || shockThunder.getStatus()== AudioSource.Status.Stopped)){
@@ -372,7 +374,7 @@ private ParticleEmitter loadElectricWaves(int id){
electrics.setTexture("Texture", getApplication().getAssetManager().loadTexture("AssetsForRenderer/Textures/Fire.png"));
electrics.setTexture("GlowMap", getApplication().getAssetManager().loadTexture("AssetsForRenderer/Textures/Fire.png"));
electrics.selectTechnique("Glow",getApplication().getRenderManager());
- electrics.setColor("GlowColor",ColorRGBA.Blue.mult(50f));
+ electrics.setColor("GlowColor",ColorRGBA.Cyan.mult(50f));
electricWaves.setMaterial(electrics);
electricWaves.getParticleInfluencer().setInitialVelocity(Vector3f.ZERO.negate().mult(5.5f));
electricWaves.setImagesX(1);
diff --git a/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/animationWrapper/SimpleScaleTrack.java b/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/animationWrapper/SimpleScaleTrack.java
index 8630acf..f970962 100644
--- a/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/animationWrapper/SimpleScaleTrack.java
+++ b/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/animationWrapper/SimpleScaleTrack.java
@@ -45,8 +45,6 @@ protected void initialize(Application app) {
/*set the bone or the spatial*/
transformTrack.setTarget(stackOne);
- /*set the transformTrack to be used by the animationEvents*/
- setTransformTrack(transformTrack);
//the frame tracks are in-sequence or in parallel with each transform track , notice it must be in a pattern form , in which the proceeding value
//is delayed by (n) * the preceding value , n is scaleFactor of delayFactor , is determinant by the coder , here its simply 2.
@@ -106,6 +104,9 @@ protected void initialize(Application app) {
*/
animComposer.addAction(clip.getName(), new ClipAction(clip));
animComposer.makeLayer(LayerBuilder.LAYER_SIMPLE_TRACK, new ArmatureMask());
+ /*set the transformTrack to be used by the animationEvents*/
+ setAction(animComposer.getAction(clip.getName()));
+
}
@Override
diff --git a/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/animationWrapper/builders/AnimEventEntity.java b/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/animationWrapper/builders/AnimEventEntity.java
index 282e9a2..5b80cf0 100644
--- a/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/animationWrapper/builders/AnimEventEntity.java
+++ b/app/src/main/java/com/scrappers/dbtraining/mainScreens/prefaceScreen/renderer/animationWrapper/builders/AnimEventEntity.java
@@ -2,16 +2,16 @@
import com.jme3.anim.AnimComposer;
import com.jme3.anim.TransformTrack;
+import com.jme3.anim.tween.action.Action;
import com.jme3.app.Application;
import com.jme3.app.state.BaseAppState;
-import com.jme3.math.FastMath;
public class AnimEventEntity extends BaseAppState {
protected AnimationEvents animationEvents;
private float counter=0f;
private int keyFrameIndex=1;
private AnimComposer animComposer;
- private TransformTrack transformTrack;
+ private Action action;
private float delayStartCounter=0;
private float delayEndCounter=0;
private float delayStart = 0.2f;
@@ -46,7 +46,7 @@ public void update(float tpf) {
if(delayStartCounter >= delayStart ){
//fire an event on the start of the Animation --works fine--
if ( animationEvents != null ){
- animationEvents.onAnimationStart(animComposer, transformTrack);
+ animationEvents.onAnimationStart(animComposer, action);
}
delayStartCounter = 0f;
}
@@ -55,22 +55,16 @@ public void update(float tpf) {
counter += tpf;
keyFrameIndex += 1;
- if ( (keyFrameIndex < transformTrack.getTimes().length-1) && (counter >= FastMath.interpolateLinear(1, transformTrack.getTimes()[keyFrameIndex-1], transformTrack.getTimes()[keyFrameIndex])) ){
- //fire an event between the current interpolated frames --Cannot figure this out--WIP--
- if ( animationEvents != null ){
- animationEvents.onAnimationShuffle(animComposer ,transformTrack, keyFrameIndex-1, keyFrameIndex);
- }
- }else if (counter >= transformTrack.getLength()/6f){
- if ( delayEndCounter >= delayEnd ){
+ if (counter > action.getLength()/6f){
//fire an end event --works fine--
if ( animationEvents != null ){
- animationEvents.onAnimationEnd(animComposer, transformTrack);
+ animationEvents.onAnimationEnd(animComposer, action);
}
//reset everything
counter = 0;
keyFrameIndex = 1;
delayEndCounter = 0f;
- }
+
}
}
@@ -90,12 +84,17 @@ public int getKeyFrameIndex() {
return keyFrameIndex;
}
- public void setTransformTrack(TransformTrack transformTrack) {
- this.transformTrack = transformTrack;
+ public void setAction(Action action) {
+ this.action = action;
}
+
+ public Action getAction() {
+ return action;
+ }
+
public interface AnimationEvents{
- void onAnimationStart(AnimComposer animComposer, TransformTrack transformationStart);
- void onAnimationEnd(AnimComposer animComposer, TransformTrack transformEnd);
+ void onAnimationStart(AnimComposer animComposer, Action transformationStart);
+ void onAnimationEnd(AnimComposer animComposer, Action transformEnd);
void onAnimationShuffle(AnimComposer animComposer, TransformTrack transformTrack, int i, int keyFrameIndex);
}
diff --git a/app/src/main/java/com/scrappers/dbtraining/notifications/BackgroundTask.java b/app/src/main/java/com/scrappers/dbtraining/notifications/BackgroundTask.java
new file mode 100644
index 0000000..4500a8c
--- /dev/null
+++ b/app/src/main/java/com/scrappers/dbtraining/notifications/BackgroundTask.java
@@ -0,0 +1,101 @@
+package com.scrappers.dbtraining.notifications;
+
+import android.annotation.SuppressLint;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.service.notification.StatusBarNotification;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.scrappers.dbtraining.R;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executors;
+import androidx.annotation.NonNull;
+import androidx.core.app.NotificationCompat;
+import androidx.work.ListenableWorker;
+import androidx.work.WorkerParameters;
+import androidx.work.impl.utils.futures.SettableFuture;
+
+public class BackgroundTask extends ListenableWorker {
+ public static final String ACTION_TEST_JME = "ActionTestJme";
+ public static final String ACTION_DISMISS = "ActionTestJme";
+ public static final int NOTIFICATION_REQUEST = 209;
+ private final WorkerParameters workerParameters;
+ private final List results = new ArrayList<>();
+ /**
+ * @param appContext The application {@link Context}
+ * @param workerParams Parameters to setup the internal state of this worker
+ */
+ public BackgroundTask(@NonNull Context appContext, @NonNull WorkerParameters workerParams) {
+ super(appContext, workerParams);
+ this.workerParameters = workerParams;
+ }
+
+ @NonNull
+ @Override
+ @SuppressLint("RestrictedApi")
+ public ListenableFuture startWork() {
+ final SettableFuture finalResult = SettableFuture.create();
+ synchronized(this) {
+ try {
+ return Executors.callable(() -> {
+ Notification builder = NotificationUtils.initializeNow(getApplicationContext())
+ // .setLargeIcon(Bitmap.createBitmap())
+ .setSmallIcon(R.mipmap.db_server_layer)
+ .setContentTitle("Time to test jme3-beta")
+ .setContentText("Hi, we are happy you are here to test our engine beta version.....")
+ .addAction(R.drawable.ic_baseline_videogame_asset_24, "Test Jme3-Beta", createPendingIntent(ACTION_TEST_JME, NOTIFICATION_REQUEST, OnActionsListener.class))
+ .addAction(R.drawable.ic_baseline_close_24, "Dismiss", createPendingIntent(ACTION_DISMISS, NOTIFICATION_REQUEST, OnActionsListener.class))
+ .setAutoCancel(true)
+ .setPriority(NotificationCompat.PRIORITY_MAX)
+ .setCategory(NotificationCompat.CATEGORY_PROMO)
+ .setChannelId(NotificationUtils.CHANNEL_ID)
+ .build();
+ //notify using the NotificationManager system service binding to the packageManager
+ NotificationManager notificationManager =
+ ((NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE));
+ notificationManager.notify(NOTIFICATION_REQUEST, builder);
+
+ //loop over status bar notifications
+ for (StatusBarNotification notification : notificationManager.getActiveNotifications()) {
+ if ( notification.getPackageName().equals(getApplicationContext().getPackageName()) ){
+ //add result success & break it off
+ results.add(Result.success());
+ break;
+ } else {
+ //retry if the notification is still not there
+ results.add(Result.retry());
+ }
+ }
+ if ( results.contains(Result.success()) ){
+ finalResult.set(Result.success());
+ } else {
+ finalResult.set(Result.retry());
+ }
+ }, finalResult).call();
+ } catch (Exception e) {
+ e.printStackTrace();
+ finalResult.set(Result.failure());
+ return finalResult;
+ }
+ }
+ }
+
+ /**
+ * Create a launch-able pending intent
+ * @param action action name
+ * @param requestCode req code name
+ * @param clazz the foreground task class, ie Service Class that uses Intents (intended mapped actions)
+ * @return a pending intent instance
+ */
+ private PendingIntent createPendingIntent(String action, int requestCode, Class extends Service> clazz){
+ Intent actionState = new Intent(getApplicationContext(), clazz);
+ actionState.setAction(action);
+ return PendingIntent.getService(getApplicationContext(),
+ requestCode, actionState, PendingIntent.FLAG_CANCEL_CURRENT);
+ }
+}
diff --git a/app/src/main/java/com/scrappers/dbtraining/notifications/NotificationUtils.java b/app/src/main/java/com/scrappers/dbtraining/notifications/NotificationUtils.java
new file mode 100644
index 0000000..afbc675
--- /dev/null
+++ b/app/src/main/java/com/scrappers/dbtraining/notifications/NotificationUtils.java
@@ -0,0 +1,81 @@
+package com.scrappers.dbtraining.notifications;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.media.AudioAttributes;
+import android.net.Uri;
+import android.os.Build;
+
+import com.scrappers.dbtraining.R;
+
+import java.time.Duration;
+import java.util.concurrent.TimeUnit;
+import androidx.annotation.RequiresApi;
+import androidx.core.app.NotificationCompat;
+import androidx.work.BackoffPolicy;
+import androidx.work.Constraints;
+import androidx.work.Data;
+import androidx.work.ExistingPeriodicWorkPolicy;
+import androidx.work.PeriodicWorkRequest;
+import androidx.work.WorkManager;
+
+public class NotificationUtils {
+ public static final String CHANNEL_ID = "DB-Training";
+
+ @RequiresApi(api = Build.VERSION_CODES.O)
+ public static PeriodicWorkRequest initializeInBackground(Context context){
+ //set work-request flags
+ //the work-request flags are the conditions in which the background thread would be executed & upon it the notification display
+ Constraints constraints = new Constraints.Builder()
+ .setRequiresBatteryNotLow(false)
+ .build();
+ Data.Builder dataBuilder = new Data.Builder()
+ .putString("Notification-Test", CHANNEL_ID);
+ //set the periodic request to a time, that will display notifications every day
+ PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(BackgroundTask.class, 24, TimeUnit.HOURS)
+ .setInitialDelay(Duration.ofDays(1))
+ //the backoff criteria is used to set how you would want to retry the operation, only if the conditions aren't met(if the periodic work isn't executed by the WorkManager upon request from the WorkRequest)
+ // , whether the previous task is a success or not
+ .setBackoffCriteria(BackoffPolicy.LINEAR, PeriodicWorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS)
+ //the conditions in which the background thread would be executed & upon it the notification display
+ .setConstraints(constraints)
+ .setInputData(dataBuilder.build())
+ .addTag("Notification-Test")
+ .build();
+ //register work request to the workManager to be unique, replace itself if it's still running
+ WorkManager.getInstance(context)
+ .enqueueUniquePeriodicWork("Notification-Test", ExistingPeriodicWorkPolicy.REPLACE, workRequest);
+ return workRequest;
+ }
+ public static NotificationCompat.Builder initializeNow(Context context){
+ NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+ AudioAttributes audioAttributes = new AudioAttributes.Builder()
+ .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+ .setUsage(AudioAttributes.USAGE_NOTIFICATION)
+ .build();
+ Uri soundUri =
+ Uri.parse("file:///android_assets/"+"AssetsForRenderer/Audio/shocks.wav");
+
+ if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ){
+ NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_ID, NotificationManager.IMPORTANCE_HIGH);
+ channel.enableLights(true);
+ channel.enableVibration(true);
+ channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
+ if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q ){
+ channel.setAllowBubbles(true);
+ }
+ notificationManager.createNotificationChannel(channel);
+ channel.setSound(soundUri, audioAttributes);
+
+ }
+ NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID);
+ builder.setPriority(NotificationCompat.PRIORITY_HIGH);
+ builder.setSmallIcon(R.mipmap.db_server_layer);
+ builder.setAutoCancel(false);
+ builder.setSound(soundUri);
+ return builder;
+ }
+}
diff --git a/app/src/main/java/com/scrappers/dbtraining/notifications/OnActionsListener.java b/app/src/main/java/com/scrappers/dbtraining/notifications/OnActionsListener.java
new file mode 100644
index 0000000..14033a6
--- /dev/null
+++ b/app/src/main/java/com/scrappers/dbtraining/notifications/OnActionsListener.java
@@ -0,0 +1,47 @@
+package com.scrappers.dbtraining.notifications;
+
+import android.app.IntentService;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.widget.Toast;
+import com.scrappers.dbtraining.HolderActivity;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+
+import static android.widget.Toast.LENGTH_LONG;
+
+public class OnActionsListener extends IntentService {
+
+
+ /**
+ * Creates an IntentService. Invoked by your subclass's constructor.
+ *
+ */
+ public OnActionsListener() {
+ super("DB-Training-Service");
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.O)
+ @Override
+ protected void onHandleIntent(@Nullable Intent notificationIntent) {
+ assert notificationIntent != null;
+ if(notificationIntent.getAction().equals(BackgroundTask.ACTION_TEST_JME)){
+ //start another explicit intent implicitly from an IntentService which is directed using a PendingIntent from a notification action
+ Intent intent = new Intent(getApplication(), HolderActivity.class);
+ //start an activity from outside the context flag
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent);
+ NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
+ notificationManager.deleteNotificationChannel(NotificationUtils.CHANNEL_ID);
+ notificationManager.cancelAll();
+ Toast.makeText(getApplicationContext(), "Powered By Jme", LENGTH_LONG).show();
+ }else if(notificationIntent.getAction().equals(BackgroundTask.ACTION_DISMISS)){
+ NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
+ notificationManager.deleteNotificationChannel(NotificationUtils.CHANNEL_ID);
+ notificationManager.cancelAll();
+
+ }
+ }
+}
diff --git a/app/src/main/res/drawable/ic_baseline_videogame_asset_24.xml b/app/src/main/res/drawable/ic_baseline_videogame_asset_24.xml
new file mode 100644
index 0000000..259cea1
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_videogame_asset_24.xml
@@ -0,0 +1,5 @@
+
+
+