I'm working on a project and I use Intent Service with wakefulBroadcastReceiver to schedule alarm and send notification. There are no problems this far. But I want when I open my app, it don't displaying notification again. Please any idea for this problem?.
In your notification receiver when you receive the notification you can check whether the app is in background or not and take a decision of showing the notification accordingly.
Here's a code to check whether the app is in background or not.
public class MyGcmPushReceiver extends GcmListenerService {
/**
* Called when message is received.
* #param from SenderID of the sender.
* #param bundle Data bundle containing message data as key/value pairs.
* For Set of keys use data.keySet().
*/
#Override
public void onMessageReceived(String from, Bundle bundle) {
// Check here whether the app is in background or running.
if(isAppIsInBackground(getApplicationContext())) {
// Show the notification
} else {
// Don't show notification
}
}
/**
* Method checks if the app is in background or not
*/
private boolean isAppIsInBackground(Context context) {
boolean isInBackground = true;
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) {
List<ActivityManager.RunningAppProcessInfo> runningProcesses = am.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) {
if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
for (String activeProcess : processInfo.pkgList) {
if (activeProcess.equals(context.getPackageName())) {
isInBackground = false;
}
}
}
}
}
else
{
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
if (componentInfo.getPackageName().equals(context.getPackageName())) {
isInBackground = false;
}
}
return isInBackground;
}
}
Related
I'm trying to handle the event when a user presses "ok" or "cancel" on the automatic permission dialog presented when I connect a "known" USB device to the android phone.
I'm using the android.usb.host library and can send and receive between the android phone and the device. Futhermore do I handle the "USB_DEVICE_ATTACHED" and "USB_DEVICE_DETACHED" using a BroadcastReceiver without any problems.
I want to enable a sort of "autoconnect" feature and therefore I need to know when the user has pressed "ok" in the automatically displayed permission dialog, but I can't find anything online at all. All I find is "bypass dialog", but this is not what I want or need.
When I connect the usb device to the android phone, a permission dialog is automatically displayed because I use the "device_filter.xml" solution from androids documentation which can be seen here Android Usb Docs.
This is how I handle the USB_DEVICE_ATTATCHED and USB_DEVICE_DETACHED events:
public NativeUsbService(ReactApplicationContext reactContext) {
...
// register device attached/detached event listeners
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
reactContext.registerReceiver(usbReceiver, filter);
...
}
And then the Broadcast Receiver:
private final BroadcastReceiver usbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
synchronized (this) {
UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if(device != null){
usbDevice = device;
} else {
Log.d(TAG, "onReceive: DEVICE WAS ATTACHED AND WAS NULL :(");
}
}
} else if (action.equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {
Log.d(TAG, "onReceive: Device was detached!");
if(connection != null) {
connection.releaseInterface(usbDeviceInterface);
connection.close();
}
connection = null;
usbDevice = null;
endpointIn = null;
endpointOut = null;
}
}
};
I have tried multiple different approaches, but nothing has worked.
I have tried getting the user response in from the intent, like with a manual permission request like below:
private final BroadcastReceiver usbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
synchronized (this) {
UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if(device != null){
usbDevice = device;
// THIS DOES NOT WORK ↓↓↓
if(intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
// The code never gets here...
}
} else {
Log.d(TAG, "onReceive: DEVICE WAS ATTACHED AND WAS NULL :(");
sendEvent("onDeviceAttached", false);
}
}
} else if (action.equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {
if(connection != null) {
connection.releaseInterface(usbDeviceInterface);
connection.close();
}
connection = null;
usbDevice = null;
endpointIn = null;
endpointOut = null;
}
}
};
I have also tried by adding a usb permission listener to the broadcast receiver by first adding the action name to my class variables:
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
Then adding the action to my intent filter like so:
public NativeUsbService(ReactApplicationContext reactContext) {
// register device attached/detached event listeners
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
filter.addAction(ACTION_USB_PERMISSION); // added action to my intent filter
reactContext.registerReceiver(usbReceiver, filter);
}
And finally reacting to the action like so:
private final BroadcastReceiver usbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
synchronized (this) {
UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if(device != null){
usbDevice = device;
}
}
} else if (action.equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {
Log.d(TAG, "onReceive: Device was detached!");
if(connection != null) {
connection.releaseInterface(usbDeviceInterface);
connection.close();
}
connection = null;
usbDevice = null;
endpointIn = null;
endpointOut = null;
sendEvent("onDeviceDetached", true);
}
else if (action.equals(ACTION_USB_PERMISSION)) {
Log.d(TAG, "onReceive: ACTION_USB_PERMISSION");
if(intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
Log.d(TAG, "onReceive: EXTRA_PERMISSION_GRANTED = true");
} else Log.d(TAG, "onReceive: EXTRA_PERMISSION_GRANTED = false");
}
}
};
Please make me aware of any missing information.
Any help is greatly appreciated.
Answering my own question in case someone else is facing the same issue.
I though about manually requesting the permission again, after permission was granted, since it is possible to handle this manual permission request when user presses an option in the dialog. I discarded this idea, not because it wouldn't work, but because I saw it as unecessary for the user to also have to press another dialog after the initial (automatic dialog).
I must add that I have not implemented this solution, so I do not know with certainty that it would prompt the user again, but I have had trouble with the manual permission request previously. If you want to try this approach the method belongs to the UsbManager class and is invoke like so usbManger.requestPermission(usbDevice).
I ended up with a solution where I start a thread which runs a loop calling usbManager.hasPermission(usbDevice) until it has permission and then emits an event (emitting this event is my use case, implement it how you like).
The solution can be seen here:
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import com.facebook.react.bridge.ReactApplicationContext;
...
private static volatile boolean permissionThreadShouldStop = false;
private static Thread activePermissionThread = null;
...
public static void usbPermissionEventEmitter(ReactApplicationContext reactContext, UsbManager usbManager, UsbDevice usbDevice) {
if((activePermissionThread != null && activePermissionThread.isAlive())) {
activePermissionThread.interrupt();
}
permissionThreadShouldStop = false;
activePermissionThread = new Thread(new Runnable() {
#Override
public void run() {
while (!usbManager.hasPermission(usbDevice) && !permissionThreadShouldStop) {
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
if(usbManager.hasPermission(usbDevice)) {
sendEvent(reactContext, "onUsbPermissionGranted", true);
}
}
});
activePermissionThread.start();
}
The ReactApplicationContext can be swapped with the normal android context. But this is for a react native module, so I use the reactContext.
I hope this will be helpful for someone, because i'm honestly really surpriced how scarse the android documentation is in regards to implementing Usb functionality using the android.hardware.usb library.
Also in general when searching for information online, I have often found myself lost since there is very little information on this subject.
Here is the situation:
When a user creates a Geofence, I save it to backend and I register a Geofence with the OS. But whenever my app restarts I fetch geofences from my backend and reregister them with the OS again, since they keep disappearing.
I have two classes MainActivity and FormActivity. Both of these activities register Geofences, so I have extracted the actual registration to an ordinary POJO Geofences.java
Here is the problem:
Now the strange thing is, triggers are only received when a map activity is on the screen. I do have a map activity in my app, but it doesn't even have to be my map-activity, even if I launch google maps geofence triggers start firing.
What am I doing wrong?
Geofences.java:
public class Geofences {
private final String TAG = Geofences.class.getSimpleName();
private final float RADIUS = 150.0F; //meter
private boolean success = false;
private final int LOITERING_IN_MILLISECONDS = 30000;// 30 seconds
public boolean doGeofenceStuff(GeoTemp newTemp, String geofenceId, PendingIntent pendingIntent, GeofencingClient geofencingClient) {
Geofence geofence = createGeofence(newTemp, geofenceId);
GeofencingRequest geofencingRequest = createGeofenceRequest(geofence);
geofencingClient.addGeofences(geofencingRequest, pendingIntent)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
success = true;
Log.i(TAG, "onComplete: DEBUG-Message: Geofence has been added.");
} else {
success = false;
Log.i(TAG, "onComplete: Geofence could not be added");
}
}
}); // handle error here
return success;
}
// Create a Geofence
private Geofence createGeofence(GeoTemp geoTemp, String geofenceId) {
long expiration = getExpirationForCurrentGeofence();
if (expiration < 1) {
Log.e(TAG, "createGeofence: Can't create Geofence, since expiration is less than zero");
return null;
}
Log.d(TAG, "createGeofence");
return new Geofence.Builder()
.setRequestId(geofenceId)
.setCircularRegion(getLat(), getLong(), RADIUS)
.setExpirationDuration(expiration)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_DWELL | Geofence.GEOFENCE_TRANSITION_EXIT)
.setLoiteringDelay(LOITERING_IN_MILLISECONDS)
.build();
}
// Create a Geofence Request
private GeofencingRequest createGeofenceRequest(Geofence geofence) {
Log.d(TAG, "createGeofenceRequest");
return new GeofencingRequest.Builder()
.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_DWELL)
.addGeofence(geofence)
.build();
}
}
This POJO Geofences.java is then used by two of my activities:
MainActivity:
public class MainActivity extends AppCompatActivity {
private static String TAG = "MainActivity";
private final int GEOFENCE_REQ_CODE = 0;
private GeofencingClient geofencingClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
geofencingClient = LocationServices.getGeofencingClient(this);
getCurrentTemps();
}
private void refreshGeofence(GeoTemp temp, String id) {
new Geofences().doGeofenceStuff(temp, id, createGeofencePendingIntent(), geofencingClient);
}
private void getCurrentTemps() {
List<GeoTemp> currentGeofences = getUpdatedList();
currentGeofences.forEach(geoTemp -> {
refreshGeofence( geoTemp, id);
});
}
private PendingIntent createGeofencePendingIntent() {
Log.d(TAG, "createGeofencePendingIntent");
Intent intent = new Intent(this, LocationAlertIntentService.class);
return PendingIntent.getService(
this, GEOFENCE_REQ_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}
There is one more activity which uses Geofences.java to register geofences with the operating system.
Update:
I have found out that, if any other app (including mine) requests for location lock, geofence triggers fire. I need them to fire in the background.
I had similar issue when working with geofencing in android.
This happens due to background restrictions added in Android Oreo and later.
OS does not allow your app to start service when it is in background so you won't receive geofence trigger.
To handle this:
Add broadcast receiver to receive intent. (This receiver will get
geofence alert even when app is in background)
Replace service with JobIntentService. (This will use OS JobSchedular
and run even with background restrictions)
Get broadcast from pending intent instead of service.
Checkout this sample project for further clarifications.
I'm doing a Foreground service in my application, and when I'm calling the method Stopself inside the service it is calling my OnDestroy method but it's not killing my service. It still using memory, I check it through adb shell dumpsys meminfo.
I tried to call StopService too from my application but it's not working. I read a lot of posts from other people with the same problem, but they are using Handlers inside the Service. In my case I manage everything with a Singleton ThreadPool manager, that I already close with shutdown() method when app is closed.
It just happened when I close the app and my service still working. For example:
If I record a Fastmotion video and I wait until it is process, and later, I close my app. I don't have this memory lead. But, if I close the app then the service is processing this, It finish the processing, but I have a memory lead because Server is not killed.
So, hope that someone can see where it fails or what can I change to make this work. Here is my Service code:
/*
Base Service is a abstract class which implement the concurrent methods for the different services of the app
*/
public abstract class BaseService extends Service {
private static final String TAG = "BaseService";
private static final int NOTIFICATION_ID = 10;
private Notification mNotification;
private boolean mIsNotificationShow = false;
/**
* mIsRegistered boolean controls when the application is in background or not.
* Is set to true in {#link #ServiceConnection method}
* Is set to false in {#link #unbindMediaSaveService()}
*/
protected boolean mIsRegistered = false;
/**
* Count the number of request in the service to show the notification
* and hide it when all of them are over
*/
protected int mNotificationCount = 0;
protected synchronized void showNotification() {
mNotificationCount++;
// Notification already shown.
if (mIsNotificationShow)
return;
if (mNotification == null) {
Bitmap bigIcon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
mNotification = new Notification.Builder(this)
.setContentTitle(getString(R.string.app_name))
.setContentText(getResources().getString(R.string.string_processing_notification_service))
.setSmallIcon(R.drawable.ic_menu_savephoto)
.setLargeIcon(bigIcon).build();
}
startForeground(NOTIFICATION_ID, mNotification);
mIsNotificationShow = true;
}
protected synchronized void hideNotification() {
mNotificationCount--;
// Notification already hidden.
if (!mIsNotificationShow)
return;
if (mNotificationCount == 0) {
stopForeground(true);
mIsNotificationShow = false;
tryToCloseService();
}
}
/**
* Set IsRegistered boolean to true or false to check in the service when the application is in background or not
*
* #param register set the boolean value
*/
public void registerServiceClient(boolean register) {
mIsRegistered = register;
Log.i(TAG, "[registerServiceClient] Client registered: " + register);
if (!register) {
tryToCloseService();
}
}
/**
* Try to close the current service. It will be close if the application is in background{#link #mIsRegistered}
* and the service don't have current actions{#link #mNotificationCount}
*/
public void tryToCloseService() {
Log.i(TAG, "[tryToCloseService] Trying to close Service");
if (!mIsRegistered && mNotificationCount == 0) {
Log.i(TAG, "[tryToCloseService] Service stopped");
stopSelf();
} else {
Log.i(TAG, "[tryToCloseService] pending actions " + mNotificationCount);
}
}
}
I initialize a ServiceConnection and bind the service in my activity:
private ServiceConnection mMediaSaveConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className, IBinder b) {
mMediaSaveService = ((MediaSaveService.LocalBinder) b).getService();
m
MediaSaveService.registerServiceClient(true);
}
#Override
public void onServiceDisconnected(ComponentName className) {
if (mMediaSaveService != null) {
mMediaSaveService.setListener(null);
mMediaSaveService.setPhotoListener(null);
mMediaSaveService = null;
}
}
};
private void bindMediaSaveService() {
Intent intent = new Intent(this, MediaSaveService.class);
startService(intent);
if (mMediaSaveConnection != null) {
bindService(intent, mMediaSaveConnection, Context.BIND_AUTO_CREATE);
mMediaSaverIsBind = true;
}
}
private void unbindMediaSaveService() {
if (mMediaSaveService != null) {
mMediaSaveService.registerServiceClient(false);
}
if (mMediaSaveConnection != null && mMediaSaverIsBind) {
unbindService(mMediaSaveConnection);
mMediaSaverIsBind = false;
}
}
Finally I call this methods in my onStart / onStop of my activity. Also, if it can help, in the services where I extend my BaseService, I put a START_NOT_STICKY flag to don't recreate the service when it's killed.
Developing a music app. In my Music Service, I have written a custom broadcast receiver. It works with Intent.ACTION_HEADSET_PLUG but not with Intent.ACTION_MEDIA_BUTTON.
Please guide on how to control music controls from bluetooth devices (Play/Pause/Next/Previous).
Code for Intent.ACTION_HEADSET_PLUG is:
#Override
public void onReceive(Context context, Intent intent) {
// aux
if(intent.getAction().equals(Intent.ACTION_HEADSET_PLUG))
{
int state = intent.getIntExtra("state", -1);
if(state == 0)
{
// Headset is unplugged. PAUSE
pauseSong();
sendBroadcast();
}
else if(state == 1)
{
// headset is plugged
resumeSong();
sendBroadcast();
}
}
}
As explained in the Media playback the right way talk, you must be registered as the 'preferred media app'. This is much easier when you use MediaSessionCompat as explained in the MediaSessionCompat video:
ComponentName mediaButtonReceiver =
new ComponentName(context, YourBroadcastReceiver.class);
MediaSessionCompat mediaSession =
new MediaSessionCompat(context,
tag, // Debugging tag, any string
mediaButtonReceiver,
null);
mediaSession.setFlags(
MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mediaSession.setCallback(this); // a MediaSessionCompat.Callback
// This is what enables media buttons and should be called
// Immediately after getting audio focus
mediaSession.setActive(true);
The accepted answer doesn't seem to work
I achieved it the other way with ExoPlayer
step #1
added dependencies
implementation 'com.google.android.exoplayer:exoplayer:2.13.1'
implementation 'com.google.android.exoplayer:extension-mediasession:2.13.1'
step #2
mediaSession = MediaSessionCompat(this, "Vion")
val mediaSessionConnector = MediaSessionConnector(mediaSession!!)
mediaSessionConnector.setMediaButtonEventHandler(object: MediaSessionConnector.MediaButtonEventHandler{
override fun onMediaButtonEvent(player: Player, controlDispatcher: ControlDispatcher, mediaButtonEvent: Intent): Boolean {
val event: KeyEvent = mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT) ?: return false
if(event.action == KeyEvent.ACTION_UP) {
when(event.keyCode) {
KeyEvent.KEYCODE_MEDIA_PREVIOUS -> {
}
KeyEvent.KEYCODE_MEDIA_PAUSE -> {
}
KeyEvent.KEYCODE_MEDIA_PLAY -> {
}
KeyEvent.KEYCODE_MEDIA_NEXT -> {
}
}
}
return true
}
})
mediaSessionConnector.setPlayer(exoPlayer)
Is there any other way to send push notifications to android device from server without using GCM? I don't want to share my device data or anything with 3rd party like Google? So any other way?
You may try this code for simple push notification without using GCM or FCM.
Update the changes in onCreateView method..
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* ed1=(EditText)findViewById(R.id.editText);
ed2=(EditText)findViewById(R.id.editText2);
ed3=(EditText)findViewById(R.id.editText3);*/
Button b1=(Button)findViewById(R.id.button);
b1.setOnClickListener(new View.OnClickListener() {
public int mNotificationId;
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onClick(View v) {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.drawable.msg)
.setContentTitle("My notification")
.setContentText("Hello Preetam! How are you");
Intent resultIntent = new Intent(getApplicationContext(), Result_Activity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(getApplicationContext());
stackBuilder.addParentStack(Result_Activity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(mNotificationId, mBuilder.build());
Toast.makeText(getApplicationContext(),"Check your notification",Toast.LENGTH_SHORT).show();
}
});
And Put a button to generate the notification.And make one more Activity to be displayed on clicking the notification.
I use a ftp library to connect to my server. in my notification service, I scan a directory where I keep plain text files. Each one represents a notification. If a new text file is added, the service gets the date the file was added to the server. If it was today, it reads the file, returns the contents, and I put it into a notification.
Here is an example of a service that looks for a text file with today's date as the title. If it exists, it will parse the data and put it into a notification
public class NotifyService extends Service {
private WakeLock mWakeLock;
/**
* Simply return null, since our Service will not be communicating with
* any other components. It just does its work silently.
*/
#Override
public IBinder onBind(Intent intent) {
return null;
}
#SuppressWarnings("deprecation")
private void handleIntent() {
// obtain the wake lock
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Partial");
mWakeLock.acquire();
// check the global background data setting
ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
if (!cm.getBackgroundDataSetting()) {
stopSelf();
return;
}
// do the actual work, in a separate thread
new PollTask().execute();
}
private class PollTask extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... args) {
// do stuff!
String title = null;
Calendar c = Calendar.getInstance();
int month = c.get(Calendar.MONTH) + 1;
int day = c.get(Calendar.DAY_OF_MONTH);
int year = c.get(Calendar.YEAR);
String Month = (String.valueOf(month));
String Day = (String.valueOf(day));
String Year = (String.valueOf(year));
String todaysDate = (Month + "-" + Day + "-" + Year);
try {
// Create a URL for the desired page
URL updateURL = new URL("URL to your notification directory" + todaysDate + ".txt");
// Read all the text returned by the server
BufferedReader in = new BufferedReader(new InputStreamReader(updateURL.openStream()));
StringBuilder total = new StringBuilder();
String line;
while ((line = in.readLine()) != null) {
total.append(line).append("\n");
}
title = total.toString();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
return title;
}
/**
* In here you should interpret whatever you fetched in doInBackground
* and push any notifications you need to the status bar, using the
* NotificationManager. I will not cover this here, go check the docs on
* NotificationManager.
*
* What you HAVE to do is call stopSelf() after you've pushed your
* notification(s). This will:
* 1) Kill the service so it doesn't waste precious resources
* 2) Call onDestroy() which will release the wake lock, so the device
* can go to sleep again and save precious battery.
*/
#Override
protected void onPostExecute(String title) {
int mId = 420;
if (title == null) {
stopSelf();
}else{
Intent notificationIntent = new Intent(getApplicationContext(), MapActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(NotifyService.this, 0, notificationIntent, 0);
//Set up the notification
Notification noti = new NotificationCompat.Builder(getApplicationContext()).setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher))
.setSmallIcon(R.drawable.ic_launcher_small)
.setTicker("New Notification ...")
.setWhen(System.currentTimeMillis())
.setContentTitle("Your app name")
.setContentText(title)
.setContentIntent(contentIntent)
//At most three action buttons can be added
//.addAction(android.R.drawable.ic_menu_camera, "Action 1", contentIntent)
//.addAction(android.R.drawable.ic_menu_compass, "Action 2", contentIntent)
//.addAction(android.R.drawable.ic_menu_info_details, "Action 3", contentIntent)
.setAutoCancel(true).build();
//Show the notification
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(mId, noti);
// handle your data
stopSelf();
}
}
}
/**
* This is deprecated, but you have to implement it if you're planning on
* supporting devices with an API level lower than 5 (Android 2.0).
*/
#SuppressWarnings("deprecation")
#Override
public void onStart(Intent intent, int startId) {
handleIntent();
}
/**
* This is called on 2.0+ (API level 5 or higher). Returning
* START_NOT_STICKY tells the system to not restart the service if it is
* killed because of poor resource (memory/cpu) conditions.
*/
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
handleIntent();
return START_NOT_STICKY;
}
/**
* In onDestroy() we release our wake lock. This ensures that whenever the
* Service stops (killed for resources, stopSelf() called, etc.), the wake
* lock will be released.
*/
public void onDestroy() {
super.onDestroy();
mWakeLock.release();
}
}
If you mean by targeting devices but without direct connection there is no really other way. If its just a text you can send a simple sms message but if you want a clickable notification GCMS is the only way for now.