I am creating an android app that consists of android push notifications.Here i need the push notifications that will run even when the app was closed. I had achieved it by calling the notification in a service. But here when i was running the code in the android >5.x devices my code was running perfectly even when app was closed notification was coming for every 5 sec but when i was running app on devices <5.x notifications was displaying only when the app was opened or when it was minimised not receiving any notifications when app was closed can any one help me what my mistake is and this is my code
SERVICE:
package com.example.servicesandroid;
import java.util.Timer;
import java.util.TimerTask;
import com.example.servicesandroid.MainActivity.MyTimerTask;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;
public class Androidservice extends Service {
final static String ACTION = "NotifyServiceAction";
final static String STOP_SERVICE = "";
final static int RQS_STOP_SERVICE = 1;
NotifyServiceReceiver notifyServiceReceiver;
private static final int MY_NOTIFICATION_ID = 1;
private NotificationManager notificationManager;
private Notification myNotification;
Timer timer;
TimerTask timer_task;
Handler handler;
#Override
public void onCreate() {
// TODO Auto-generated method stub
notifyServiceReceiver = new NotifyServiceReceiver();
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
MyTimerTask myTask = new MyTimerTask();
Timer myTimer = new Timer();
myTimer.schedule(myTask, 5000, 1500);
// TODO Auto-generated method stub
return Service.START_STICKY;
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
this.unregisterReceiver(notifyServiceReceiver);
super.onDestroy();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
public class NotifyServiceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
int rqs = arg1.getIntExtra("RQS", 0);
if (rqs == RQS_STOP_SERVICE) {
stopSelf();
}
}
}
class MyTimerTask extends TimerTask {
public void run() {
generateNotification(getApplicationContext(), "Hello");
}
}
private void generateNotification(Context context, String message) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
String appname = context.getResources().getString(R.string.app_name);
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
Notification notification;
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MainActivity.class), 0);
// To support 2.3 os, we use "Notification" class and 3.0+ os will use
// "NotificationCompat.Builder" class.
if (currentapiVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
notification = new Notification(icon, message, 0);
notification.setLatestEventInfo(context, appname, message,
contentIntent);
notification.flags = Notification.FLAG_AUTO_CANCEL;
notificationManager.notify((int) when, notification);
} else {
NotificationCompat.Builder builder = new NotificationCompat.Builder(
context);
notification = builder.setContentIntent(contentIntent)
.setSmallIcon(icon).setTicker(appname).setWhen(0)
.setAutoCancel(true).setContentTitle(appname)
.setContentText(message).build();
notificationManager.notify((int) when, notification);
}
}
}
This is my activity:
package com.example.servicesandroid;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent serviceIntent = new Intent(MainActivity.this,Androidservice.class);
startService(serviceIntent);
}
This is my Broadcast receiver when device reboots:
package com.example.servicesandroid;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class Boot_Completed extends BroadcastReceiver {
private final String BOOT_COMPLETED_ACTION = "android.intent.action.BOOT_COMPLETED";
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(intent.getAction().equals(BOOT_COMPLETED_ACTION)){
Intent myIntent = new Intent(context, Androidservice.class);
context.startService(myIntent);
}
}
}
This is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.servicesandroid"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".Androidservice"/>
<receiver android:name=".Boot_Completed" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
Please any one help me with this
Related
I have to create an Android app that can receive message from a sensor and send a notification to the user when a message is received. I have to do this with out using service like Google Firebase because all the system must run locally. I thought to use MQTT in a service, but when I kill the app, it disconnect from the broker. If the app is running in background this implementation works but I need to keep the connection alive also when app is killed.
This is my implementation of the service:
package it.unisalento.sonoff.helper;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.net.wifi.aware.AttachCallback;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.widget.Toast;
import androidx.core.app.NotificationCompat;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import java.util.ArrayList;
import java.util.List;
import it.unisalento.sonoff.R;
import it.unisalento.sonoff.view.MainActivity;
public class Service extends android.app.Service {
private Looper serviceLooper;
private ServiceHandler serviceHandler;
private List ids = new ArrayList();
private MqttHelper mqttHelper;
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message msg) {
showNotification("Aggiornamento di stato", String.valueOf(msg.arg1));
}
}
#Override
public void onCreate() {
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
serviceLooper = thread.getLooper();
serviceHandler = new ServiceHandler(serviceLooper);
mqttHelper = new MqttHelper(getApplicationContext());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
mqttHelper = new MqttHelper(getApplicationContext());
mqttHelper.setCallback(new MqttCallbackExtended() {
#Override
public void connectComplete(boolean reconnect, String serverURI) {
}
#Override
public void connectionLost(Throwable cause) {
}
#Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
Message msg = serviceHandler.obtainMessage();
msg.arg1 = startId;
serviceHandler.sendMessage(msg);
}
#Override
public void deliveryComplete(IMqttDeliveryToken token) {
}
});
mqttHelper.connect();
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
#Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
private void showNotification(String title, String message) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
String channelId = "notification_channel";
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.mipmap.ic_launcher_round)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setPriority(Notification.PRIORITY_MAX)
.setDefaults(Notification.DEFAULT_VIBRATE)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(getApplicationContext().NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId, "lock", NotificationManager.IMPORTANCE_HIGH);
channel.enableVibration(true);
notificationManager.createNotificationChannel(channel);
}
int id;
if(ids.isEmpty()){
id=0;
}
else{
id = ids.size();
}
ids.add(id);
notificationManager.notify(id , notificationBuilder.build());
}
}
And here my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="it.unisalento.sonoff">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme.FullScreen"
android:usesCleartextTraffic="true">
<!-- MqttService -->
<service android:name="org.eclipse.paho.android.service.MqttService" />
<service android:name=".helper.Service"
android:exported="false"
android:stopWithTask="false"/>
<activity android:name=".view.DashboardActivity"/>
<activity
android:name=".view.LoginActivity"
android:exported="true"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".view.MainActivity"/>
</application>
You need to use Foreground Services and pass the notification you built in startForeground method.
I have made an app to test to show a foreground service and then tried to implement it in real app to close wifi after certain time, the code is the same as my test app but it doesn't show notification.
the service works fine but without notification
Main Activity
package com.example.countdownclosewifi.UI;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.widget.Toast;
import com.example.countdownclosewifi.MyService;
import com.example.countdownclosewifi.R;
import com.example.countdownclosewifi.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
private BroadcastReceiver receiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
// Intent filter to set the same action of the broadcast sender
IntentFilter intentFilter_getRemainingTime = new IntentFilter();
intentFilter_getRemainingTime.addAction("Count");
// what will happen when the app receive a broadcast
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int i = intent.getIntExtra("Show", 0);
binding.timeLeft.setText(String.valueOf(i));
}
};
registerReceiver(receiver, intentFilter_getRemainingTime);
binding.start.setOnClickListener(view -> {
if (binding.setTime.getText().toString().isEmpty() || Long.parseLong(binding.setTime.getText().toString()) == 0) {
Toast.makeText(MainActivity.this, "Enter the duration", Toast.LENGTH_SHORT).show();
} else {
Intent serviceIntent = new Intent(this, MyService.class);
int time = Integer.parseInt(binding.setTime.getText().toString());
serviceIntent.putExtra("Time", time);
if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.O){
startForegroundService(serviceIntent);
}
else {
startService(serviceIntent);
}
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
}
Service class
package com.example.countdownclosewifi;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
//import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.IBinder;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import com.example.countdownclosewifi.UI.MainActivity;
import java.util.Timer;
import java.util.TimerTask;
public class MyService extends Service {
private WifiManager wifiManager;
private int timeRemaining;
private Timer timer;
// Intent intent;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
IntentFilter intentFilter_stop = new IntentFilter();
intentFilter_stop.addAction("Stop timer");
timeRemaining = intent.getIntExtra("Time", 0);
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
if (timeRemaining == 0) {
wifiManager.setWifiEnabled(false);
timer.cancel();
stopSelf();
}
setNotification(timeRemaining);
Intent intent = new Intent();
intent.setAction("Count");
intent.putExtra("Show", timeRemaining);
sendBroadcast(intent);
timeRemaining -= 1;
}
}, 0, 1000);
return START_STICKY;
}
public void setNotification(int timeRemaining) {
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent =
PendingIntent.getActivity(this, 0, notificationIntent, 0);
String channel_id = "id";
Notification notification;
if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.O) {
notification = new Notification.Builder(this, channel_id)
.setContentTitle("You are running out of time")
.setContentText(String.valueOf(timeRemaining))
.setSmallIcon(R.drawable.wifi_24)
.setContentIntent(pendingIntent)
.setOnlyAlertOnce(true)
.build();
} else {
notification = new NotificationCompat.Builder(this, channel_id)
.setContentTitle("You are running out of time")
.setContentText(String.valueOf(timeRemaining))
.setSmallIcon(R.drawable.wifi_24)
.setContentIntent(pendingIntent)
.setOnlyAlertOnce(true)
.build();
}
// Notification ID cannot be 0.
startForeground(1, notification);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String id = "Notification Channel";
CharSequence name = "notification";
NotificationChannel notificationChannel = new NotificationChannel(id, name, NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(notificationChannel);
}
}
#Override
public void onDestroy() {
super.onDestroy();
stopForeground(true);
}
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.countdownclosewifi">
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.CountDownCloseWIFI">
<activity android:name=".UI.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyService"/>
</application>
</manifest>
it's so clear but i cant see what i am missing to show this notification.
use countdowntimer class instead of timerTask
and set the priority as MAX
NotificationManager.IMPORTANCE_HIGH
I Solved it, the problem was that the Notification ID was not the same as the Channel ID
My target was Restarting the Service when app is in background or even killed from home page by sweeping. App & Service is working nice while app is in foreground and background but while I killed the app by force(sweeping out from home page), the Service stopped working. That's okay but I implemented a Broadcast Receiver to restart the Service but it seems like its (Broadcast Receiver) not even called itself or the Service while app was killed forcefully / sweeping from home page.
My device is : Xiaomi Redmi Note 4
I included my codes here :
MainActivity.java
package com.turzo.servicetest;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
private String TAG = "ServiceTest";
Intent mServiceIntent;
private SensorService mSensorService;
Context ctx;
public Context getCtx() {
return ctx;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ctx = this;
registerRec();
setContentView(R.layout.activity_main);
mSensorService = new SensorService(getCtx());
mServiceIntent = new Intent(getCtx(), mSensorService.getClass());
if (!isMyServiceRunning(mSensorService.getClass())) {
startService(mServiceIntent);
}
}
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
Log.i (TAG, true+"");
return true;
}
}
Log.i (TAG, false+"");
return false;
}
#Override
protected void onDestroy() {
stopService(mServiceIntent);
Log.i(TAG, "onDestroy!");
super.onDestroy();
}
public void registerRec(){
SensorRestarterBroadcastReceiver myreceiver = new SensorRestarterBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver((BroadcastReceiver) myreceiver, intentFilter);
}
}
SensorService.java
package com.turzo.servicetest;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import java.util.Timer;
import java.util.TimerTask;
public class SensorService extends Service {
public int counter=0;
private String TAG = "ServiceTest";
public SensorService(Context applicationContext) {
super();
Log.i(TAG , "here I am!");
}
public SensorService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
startTimer();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG , "ondestroy!");
Intent broadcastIntent = new Intent("com.turzo.servicetest.ActivityRecognition.RestartSensor");
sendBroadcast(broadcastIntent);
stoptimertask();
}
private Timer timer;
private TimerTask timerTask;
long oldTime=0;
public void startTimer() {
//set a new Timer
timer = new Timer();
//initialize the TimerTask's job
initializeTimerTask();
//schedule the timer, to wake up every 1 second
timer.schedule(timerTask, 1000, 1000); //
}
/**
* it sets the timer to print the counter every x seconds
*/
public void initializeTimerTask() {
timerTask = new TimerTask() {
public void run() {
Log.i(TAG , "in timer ++++ "+ (counter++));
}
};
}
/**
* not needed
*/
public void stoptimertask() {
//stop the timer, if it's not already null
if (timer != null) {
timer.cancel();
timer = null;
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
SensorRestarterBroadcastReceiver.java
package com.turzo.servicetest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class SensorRestarterBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i(SensorRestarterBroadcastReceiver.class.getSimpleName(), "Service Stops! Oooooooooooooppppssssss!!!!");
context.startService(new Intent(context, SensorService.class));
}
}
AndroidManifext.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.turzo.servicetest">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.turzo.servicetest.SensorService"
android:enabled="true" >
</service>
<receiver
android:name="com.turzo.servicetest.SensorRestarterBroadcastReceiver"
android:enabled="true"
android:exported="true"
android:label="RestartServiceWhenStopped">
<intent-filter>
<action android:name="com.turzo.servicetest.ActivityRecognition.RestartSensor"/>
</intent-filter>
</receiver>
</application>
</manifest>
You should restart Service in onTaskRemoved().
#Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartService = new Intent(getApplicationContext(),
this.getClass());
restartService.setPackage(getPackageName());
PendingIntent restartServicePI = PendingIntent.getService(
getApplicationContext(), 1, restartService,
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePI);
}
NOTE:- Starting from android O . You can not call startService.
The startService() method now throws an IllegalStateException if an app targeting Android 8.0 tries to use that method in a situation when it isn't permitted to create background services.
This does not apply to foreground services, which are noticeable to the user. It can run in background with a notification on top. By default, these restrictions only apply to apps that target Android 8.0 (API level 26) or higher. However, users can enable most of these restrictions for any app from the Settings screen, even if the app targets an API level lower than 26. So in case if user enables the restrictions for below API 26 your Service will not work.
Read Background Execution Limits.
So Try to avoid using Service if you can . Make use of WorkManager if it fits the requirements.
I have this service class
package com.example.test43;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class ProximityService extends Service {
private String PROX_ALERT_INTENT = "com.example.proximityalert";
private BroadcastReceiver locationReminderReceiver;
private LocationManager locationManager;
private PendingIntent proximityIntent;
//#override
public void onCreate() {
locationReminderReceiver = new ProximityIntentReceiver();
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Toast.makeText(this, "created", Toast.LENGTH_LONG).show();
double lat = 55.586568;
double lng = 13.0459;
float radius = 1000;
long expiration = -1;
IntentFilter filter = new IntentFilter(PROX_ALERT_INTENT);
registerReceiver(locationReminderReceiver, filter);
Intent intent = new Intent(PROX_ALERT_INTENT);
intent.putExtra("alert", "Test Zone");
proximityIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
locationManager.addProximityAlert(lat, lng, radius, expiration, proximityIntent);
}
// #override
public void onDestroy() {
Toast.makeText(this, "Proximity Service Stopped", Toast.LENGTH_LONG).show();
try {
unregisterReceiver(locationReminderReceiver);
} catch (IllegalArgumentException e) {
Log.d("receiver", e.toString());
}
}
// #override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "Proximity Service Started", Toast.LENGTH_LONG).show();
}
//#override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
public class ProximityIntentReceiver extends BroadcastReceiver {
private static final int NOTIFICATION_ID = 1000;
//#suppressWarnings("deprecation")
//#override
public void onReceive(Context arg0, Intent arg1) {
String place = arg1.getExtras().getString("alert");
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent pendingIntent = PendingIntent.getActivity(arg0, 0, arg1, 0);
Notification notification = createNotification();
notification.setLatestEventInfo(arg0, "Entering Proximity!", "You are approaching a " + place + " marker.", pendingIntent);
notificationManager.notify(NOTIFICATION_ID, notification);
locationManager.removeProximityAlert(proximityIntent);
}
private Notification createNotification() {
Notification notification = new Notification();
notification.icon = R.drawable.ic_launcher;
notification.when = System.currentTimeMillis();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
notification.defaults |= Notification.DEFAULT_VIBRATE;
notification.defaults |= Notification.DEFAULT_SOUND;
return notification;
}
}
}
Here manifest :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test43"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<service android:enabled="true" android:name="com.example.ProximityService" />
<activity
android:name="com.example.test43.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Main
package com.example.test43;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, ProximityService.class));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
I want to know how do I start the service? I put a toast in the on create when the service starts just to know when starts but I don't see it. Am I doing something wrong here?
Any help would be appreciated
Your package name is incorrect when defining the service. Change you Service declaration in Androidmanifest.xml as below:
<service android:enabled="true"
android:name="com.example.test43.ProximityService" />
I am making notification bar in my app and this is my code :
MainActivity:
package com.example.notificationservicedemo;
import java.util.Calendar;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.TimePicker;
public class MainActivity extends Activity implements OnClickListener {
EditText editMsg;
DatePicker datePicker;
TimePicker timePicker;
Button btnSetNotification;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
editMsg = (EditText) findViewById(R.id.editText1);
datePicker = (DatePicker) findViewById(R.id.datePicker1);
timePicker = (TimePicker) findViewById(R.id.timePicker1);
btnSetNotification = (Button) findViewById(R.id.buttonSetNotification);
btnSetNotification.setOnClickListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onClick(View view) {
Intent intent = new Intent();
// TODO Auto-generated method stub
switch(view.getId()){
case R.id.buttonSetNotification:
String message=editMsg.getText().toString();
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.MONTH, datePicker.getMonth());
calendar.set(Calendar.DAY_OF_MONTH, datePicker.getDayOfMonth());
calendar.set(Calendar.YEAR, datePicker.getYear());
calendar.set(Calendar.HOUR, timePicker.getCurrentHour());
calendar.set(Calendar.MINUTE, timePicker.getCurrentHour());
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
intent.setClass(this, MyNotificationService.class);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
//startService(intent);
break;
}
}
}
MyNotificationService:
package com.example.notificationservicedemo;
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.os.IBinder;
import android.widget.Toast;
public class MyNotificationService extends Service {
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Toast.makeText(this, "OnCreate()", Toast.LENGTH_SHORT).show();
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Toast.makeText(this, "OnDestroy()", Toast.LENGTH_SHORT).show();
}
#Override
#Deprecated
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
Toast.makeText(this, "OnStart()", Toast.LENGTH_SHORT).show();
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent= new Intent(this,MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification = new Notification(R.drawable.ic_launcher, "Bla bla bla", System.currentTimeMillis());
String contentTitle="Title";
String contentText="This is your message";
notification.setLatestEventInfo(this, contentTitle, contentText, pendingIntent);
notificationManager.notify(123, notification);
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.notificationservicedemo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.notificationservicedemo.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.example.notificationservicedemo.MyNotificationService"></service>
</application>
</manifest>
Problem is that when I pick time when notification has to come up I press my button to save and then notification comes up immediately it ignores my timePicker and datePicker. What is the peoblem?
This is my solution for launch a notification on android :
public class MyNotification {
private NotificationManager nm;
private Notification nf;
private int notification_id;
public MyNotification(Context context, Class<?> cls, int icon, CharSequence tickerText, CharSequence title, CharSequence text, int notification_id) {
nm = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
nm.cancelAll();
Intent activity = new Intent(context, cls);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, activity, 0);
Notification.Builder builder = new Notification.Builder(context);
builder.setContentIntent(contentIntent); //-> Activity open after click
builder.setAutoCancel(true);
builder.setSmallIcon(icon);
builder.setWhen(System.currentTimeMillis());
builder.setTicker(tickerText);
builder.setContentTitle(title);
builder.setContentText(text);
//builder.setSound(Uri.parse("android.resource://"+this.getPackageName()+R.raw.good)); //-> Song
//builder.setContent(new RemoteViews(getPackageName(), R.layout.note)); //-> Layout
//builder.setVibrate(new long[]{0, 100, 25, 100}); // -> Vibration
Notification nf = builder.getNotification();
this.nf = nf;
this.notification_id = notification_id;
}
public void show() {
this.nm.notify(notification_id, nf);
}
}
I hope i have helped you!