Send a notification when the app is closed
You can use this service all you need to do is Start this service onStop() in your activity lifecycle. With this code:
startService(new Intent(this, NotificationService.class));
then you can create a new Java Class and paste this code in it:
public class NotificationService extends Service {
Timer timer;
TimerTask timerTask;
String TAG = "Timers";
int Your_X_SECS = 5;
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand");
super.onStartCommand(intent, flags, startId);
startTimer();
return START_STICKY;
}
@Override
public void onCreate() {
Log.e(TAG, "onCreate");
}
@Override
public void onDestroy() {
Log.e(TAG, "onDestroy");
stoptimertask();
super.onDestroy();
}
//we are going to use a handler to be able to run in our TimerTask
final Handler handler = new Handler();
public void startTimer() {
//set a new Timer
timer = new Timer();
//initialize the TimerTask's job
initializeTimerTask();
//schedule the timer, after the first 5000ms the TimerTask will run every 10000ms
timer.schedule(timerTask, 5000, Your_X_SECS * 1000); //
//timer.schedule(timerTask, 5000,1000); //
}
public void stoptimertask() {
//stop the timer, if it's not already null
if (timer != null) {
timer.cancel();
timer = null;
}
}
public void initializeTimerTask() {
timerTask = new TimerTask() {
public void run() {
//use a handler to run a toast that shows the current timestamp
handler.post(new Runnable() {
public void run() {
//TODO CALL NOTIFICATION FUNC
YOURNOTIFICATIONFUNCTION();
}
});
}
};
}
}
After this you only need to combine the service with the manifest.xml:
<service
android:name=".NotificationService"
android:label="@string/app_name">
<intent-filter>
<action android:name="your.app.domain.NotificationService" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
Isn't there any way to show notification when app is closed in all devices?
All of them given above aren't working when app is killed or closed. Then I tried Firebase cloud messaging
and it worked[tested in android 7,10] even if app is closed or killed.
RequestQueue requestQueue;
requestQueue = Volley.newRequestQueue(this);
--
public void sendNotificationToUser() {
JSONObject mainObj = new JSONObject();
try {
mainObj.put("to", "/topics/" + topic_name);//
JSONObject notificationObj = new JSONObject();
notificationObj.put("title", "About title");
notificationObj.put("body", "Enter you message here");
mainObj.put("notification", notificationObj);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, value,
mainObj, new Response.Listener<JSONObject>() {//value="https://fcm.googleapis.com/fcm/send"
@Override
public void onResponse(JSONObject response) {
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}) {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> header = new HashMap<>();
header.put("content-type", "application/json");
header.put("authorization", "key=" + server-key);
return header;
}
};
Toast.makeText(this, "Successfully added", Toast.LENGTH_SHORT).show();
requestQueue.add(jsonObjectRequest);
//
}
}
Make sure to import
implementation 'com.mcxiaoke.volley:library:1.0.19'
Don't put your server-key inside your app. You can use Firebase cloud function
for this[not free]. Above code will send notification to all of the user who are subcribed to topic_name
.
How i can send notifications when my app is closed in Ionic?
If your user kill the app you can not make sure your user keep your app active. But if you really want to try you can use this.
The most efficient is to use Push Notifications. Your server can send notification to your app when new data will be stored.
EDIT
Server side you can run a function to send push notification with something like this :
function sendGCM($message, $id) {
$url = 'https://fcm.googleapis.com/fcm/send';
$fields = array (
'registration_ids' => array (
$id
),
'data' => array (
"message" => $message
)
);
$fields = json_encode ( $fields );
$headers = array (
'Authorization: key=' . "YOUR_KEY_HERE",
'Content-Type: application/json'
);
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $url );
curl_setopt ( $ch, CURLOPT_POST, true );
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $fields );
$result = curl_exec ( $ch );
echo $result;
curl_close ( $ch );
}
?>
Run this function each 5 minutes in php if you want but better when new data are stored.
SOURCE
And, Ionic side, you can execute a function to get your data when you catch a push notification. Somethink like this :
import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { HomePage } from '../pages/home/home';
import {
Push,
PushToken
} from '@ionic/cloud-angular';
@Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage = HomePage;
constructor(platform: Platform, public push: Push) {
platform.ready().then(() => {
StatusBar.styleDefault();
Splashscreen.hide();
this.push.register().then((t: PushToken) => {
return this.push.saveToken(t);
}).then((t: PushToken) => {
console.log('Token saved:', t.token);
});
this.push.rx.notification()
.subscribe((msg) => {
// CALL SERVE TO GET DATA
});
});
}
}
SOURCE
Open Activity on notification button click when app is closed
You can try to receive the click in a BroadcastReceiver
and then open activity from there.
- Try this to add a action button o your notification:
timerNotificationBuilder.addAction(createNotificationActionButton("STOP");
Where the createNotificationActionButton
method is this:
public NotificationCompat.Action createNotificationActionButton(String text){
Intent intent = new Intent(this, StopwatchNotificationActionReceiver.class);
@SuppressLint("InlinedApi") PendingIntent pendingIntent = PendingIntent.getBroadcast(this, new Random().nextInt(100), intent, PendingIntent.FLAG_IMMUTABLE);
return new NotificationCompat.Action(0, text, pendingIntent);
}
- Create a class named
StopwatchNotificationActionReceiver
and make it extent a BroadcastReceiver`. This is the code for that class:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class StopwatchNotificationActionReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
PrefUtil.setIsRunningInBackground(context, false);
PrefUtil.setTimerSecondsPassed(context, 0);
PrefUtil.setWasTimerRunning(context, false);
context.stopService(MainActivity.serviceIntent);
Intent activityIntent = new Intent(context, MainActivity.class);
activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActvity(activityIntent);
}
}
Also you need to register that receiver in your manifest like this:
<receiver android:name="StopwatchNotificationActionReceiver"/>
- Where the
MainActivity.serviceIntent
is a public static variable which looks like this:
public static Intent serviceIntent;
And this intent is only used to start the service like this:
//In onCreate
serviceIntent = new Intent(this, TimerService.class);
//In onPause
PrefUtil.setTimerSecondsPassed(this,seconds);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(serviceIntent);
}
Or you can try the simple method:
if (action != null && action.equals(ACTION_STOP_SERVICE)) {
Context context = this;
Intent activityIntent = new Intent(context, MainActivity.class);
activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActvity(activityIntent);
killService();
}
Edit
Another solution is here. Again. You need to refer to my repo as I have made changes to the files in order to complete your task. In the service class, refer to this method. There, I start the activity if the action is reset(r). Or else, it opens the broadcast receiver. Then, in the activity, I receive that extra in the onResume()
method. If the reset button is not clicked, it opens the Receiver class.
And as always, you can view the result of the app from here.
I hope that code will do your work.
Related Topics
Download Multiple Files with a Progress Bar in Listview Android
Android Button Has Setontouchlistener Called on It But Does Not Override Performclick
How to Create Converter for My Class in Android Retrofit Library
Caused By: Java.Lang.Outofmemoryerror: Bitmap Size Exceeds Vm Budget
Return Type for Android Room Joins
Limit Height of Listview on Android
Calculate the Size of a List View or How to Tell It to Fully Expand
How to Add Action Bar Options Menu in Android Fragments
How to Create Expandable Listview in Flutter
Play Rtsp Streaming in an Android Application
Android: Change Default Home Application
Add Google Maps API V2 in a Fragment
Android Upload Video to Remote Server Using Http Multipart Form Data
Get Selected Text from Textview
Travis Ci Failed Because Cannot Accept License Constrain Layout
Android: How to Change the Actionbar "Home" Icon to Be Something Other Than the App Icon
Android: How Does Gridview Auto_Fit Find the Number of Columns