Wake up screen on notification recieved - java

So when the user receives a notification while the lockscreen is on the screen should light up.
private void unlockScreen() {
Window window = this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
I have this to unlock the screen. Then I'm using this to call it
private void updateNotification(int notificationCode)
{
switch(notificationCode)
{
case NotificationService.InterceptedNotificationCode.FACEBOOK_CODE:
shapeRoundButton.setImageResource(R.drawable.toggle_on);
unlockScreen();
break;
case NotificationService.InterceptedNotificationCode.OTHER_NOTIFICATIONS_CODE:
shapeRectangleButton.setImageResource(R.drawable.toggle_on);
break;
}
}
The shapeRoundButton.setImageResource(R.drawable.toggle_on) works perfectly fine, but the unlockScreen(); doesn't. The notification is being received.
Anyone know why the screen isn't being unlocked or how I can unlock the screen? Cheers!

see this
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
boolean isScreenOn = pm.isScreenOn();
Log.e("screen on.................................", ""+isScreenOn);
if(isScreenOn==false)
{
WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |PowerManager.ACQUIRE_CAUSES_WAKEUP |PowerManager.ON_AFTER_RELEASE,"MyLock");
wl.acquire(10000);
WakeLock wl_cpu = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"MyCpuLock");
wl_cpu.acquire(10000);
}

Try using an IntentService. Replace your intent target with your intent service:
Intent yepIntent = new Intent(context, MyIntentService.class);
yepIntent.putExtra("foo", true);
yepIntent.putExtra("bar", "more info");
PendingIntent yepPendingIntent = PendingIntent.getService(context, notificationId, yepIntent, PendingIntent.FLAG_CANCEL_CURRENT);
notificationBuilder.addAction(R.drawable.icon_of_choice, "My Action", yepPendingIntent);
Register your service in the Manifest:
<service
android:name="app.great.mypackage.MyIntentService"
android:exported="false"/>
Your Service could look like this:
public class MyIntentSerice extends IntentService {
#Override
protected void onHandleIntent(Intent intent) {
Log.d("myapp", "I got this awesome intent and will now do stuff in the background!");
// .... do what you like
}
}
UPDATE with feedback from Name
The trick seems to be to
Use a service
Add the intent not as an action or a contentIntent, but with the RemoteViews method.
Combined it will be:
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setOngoing(true)
.setSmallIcon(R.drawable.abc_ic_menu_share_mtrl_alpha)
.setContentTitle("My notification")
.setContentText("Hello World!");
int notificationId = 1;
Intent yepIntent = new Intent(this, MyIntentService.class);
yepIntent.setAction("test");
yepIntent.putExtra("foo", true);
yepIntent.putExtra("bar", "more info");
PendingIntent yepPendingIntent = PendingIntent.getService(this,
notificationId, yepIntent, PendingIntent.FLAG_CANCEL_CURRENT);
// doesn't show up on my lock-screen
//builder.addAction(R.drawable.abc_ic_menu_share_mtrl_alpha, "My Action",
yepPendingIntent);
// asks for unlock code for some reason
//builder.setContentIntent(yepPendingIntent);
// Bingo
RemoteViews view = new RemoteViews(getPackageName(), R.layout.notification);
view.setOnClickPendingIntent(R.id.notification_closebtn_ib, yepPendingIntent);
builder.setContent(view);

Related

Android Notification Action not opening app when tapped

I am trying to show an incoming call notification using a full screen intent which I've managed to do.
The problem when tapping on the Accept action button I'm unable to open the app if it's closed, or bring to the front, etc ...
The weird thing is that clicking on the background of the notification will do exactly what I want, but that's not what I'm after. I want the user to be able to reject without having to open the app.
I've tried starting the MainActivity from a service and also a BroadcastReceiver.
Neither of those two options seem to work.
This is how I'm building the notification - everything works as expected here ...
public class IncomingCallNotificationService extends Service {
#TargetApi(Build.VERSION_CODES.O)
private Notification buildNotification(
String title,
String text,
PendingIntent pendingIntent,
Bundle extras,
int notificationId,
String channelId
) {
Log.d(TAG, "buildNotification: " + extras.get(Constants.CALL_ID).toString());
String callId = extras.get(Constants.CALL_ID).toString();
Intent rejectIntent = new Intent(getApplicationContext(), IncomingCallNotificationService.class);
rejectIntent.setAction(Constants.ACTION_REJECT);
rejectIntent.putExtra(Constants.NOTIFICATION_ID, notificationId);
PendingIntent pendingIntentReject = PendingIntent.getService(getApplicationContext(), notificationId, rejectIntent, getPendingIntentFlag());
Intent acceptIntent = new Intent(getApplicationContext(), IncomingCallNotificationService.class);
acceptIntent.setAction(Constants.ACTION_ACCEPT);
acceptIntent.putExtra(Constants.NOTIFICATION_ID, notificationId);
acceptIntent.putExtra(Constants.CALL_ID, callId);
PendingIntent pendingIntentAccept = PendingIntent.getService(getApplicationContext(), notificationId, acceptIntent, getPendingIntentFlag());
long[] mVibratePattern = new long[]{0, 400, 400, 400, 400, 400, 400, 400};
Notification.Builder builder =
new Notification.Builder(getApplicationContext(), channelId)
.setSmallIcon(R.drawable.ic_call_end_white_24dp)
.setContentTitle(title)
.setContentText(text)
.setPriority(Notification.PRIORITY_MAX)
.setCategory(Notification.CATEGORY_CALL)
.setFullScreenIntent(pendingIntent, true)
.setContentIntent(pendingIntent)
.setExtras(extras)
.setVibrate(mVibratePattern)
.setAutoCancel(true)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.addAction(android.R.drawable.ic_menu_delete, getString(R.string.decline), pendingIntentReject)
.addAction(android.R.drawable.ic_menu_call, getString(R.string.answer), pendingIntentAccept);
return builder.build();
}
}
This is what eventually gets called when tapping the accept button:
private void accept(String callId) {
Log.d(TAG, "accepting call: " + callId);
endForeground();
SoundPoolManager.getInstance(this).stopRinging();
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra(Constants.CALL_ID, callId);
startActivity(intent);
}

Why does foreground service stop working when device go into sleep mode

I want to create an app that is constantly checking for location change and put the current location in the firebase (e.g. an app for runners).
Unfortunately the foregroundservice is being stopped or paused every time the device go into sleep mode.
For starters I wanted to create a foreground service that is continuously writing information to the base (that would be a time stamp or a simple string) every second.
After some time it just stops writing to firebase without calling stopself().
The service is working fine on the emulator (even if put to sleep), but stops when tested on a real device – in my case Huawei, Android 8.1.0.
What should I do to force service to run in every state of the device?
My MainActivity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent intent = new Intent(this, MyService.class);
intent.putExtra("action", "start");
startForegroundService(intent);
}
else {
Intent intent = new Intent(this, MyService.class);
intent.putExtra("action", "start");
startService(intent);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent intent = new Intent(this, MyService.class);
intent.putExtra("action", "stop");
startForegroundService(intent);
}
else {
Intent intent = new Intent(this, MyService.class);
intent.putExtra("action", "stop");
startService(intent);
}
}
}
MyService:
public class MyService extends Service {
int i =0;
private String CHANNEL_ID = "2345";
#Override
public void onCreate() {
super.onCreate();
}
public MyService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground(1000, createNotification());
String action = intent.getExtras().getString("action");
switch (action){
case "start":
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
myfunction();
handler.postDelayed(this, 1000);
}
};
break;
case "stop":
stopfunction();
break;
}
handler.postDelayed(runnable, 1000);
return START_NOT_STICKY;
}
private void stopfunction() {
stopSelf();
}
private void myfunction() {
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("locations");
myRef.child("location").setValue(i);
i++;
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return null;
}
#RequiresApi(Build.VERSION_CODES.O)
private void createChannel(){
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, getString(R.string.infoTxt),
NotificationManager.IMPORTANCE_HIGH);
channel.setShowBadge(false);
channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
notificationManager.createNotificationChannel(channel);
}
private Notification createNotification(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
createChannel();
}
Intent notificationItent = new Intent(this, MainActivity.class);
notificationItent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(this, 0, notificationItent, 0);
return new NotificationCompat.Builder(this, CHANNEL_ID)
.setColor(ContextCompat.getColor(this, android.R.color.background_dark))
.setContentIntent(intent)
.setSmallIcon(R.drawable.ic_launcher_background)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setOnlyAlertOnce(true)
.setContentTitle("GPS Location")
.build();
}
}
I've tried everything: service, foreground service, broadcast receiver, jobSheduler, WorkerManager – nothing helped. Then I found it’s a new HUAWEI feature called “power-intensive app monitor “. It kills every app that runs in the background for a long time unless user gives special permissions to it.
The path to do this:
Settings -> Security & privacy -> Location services -> recent location requests: YOUR APP NAME -> Battery -> uncheck Power-intensive prompt, App launch: Manage manually: check all three positions: Auto-launch, secondary launch, run in background.
I don’t know is there a way to do this programmatically. I think the best way is to create a sort of help activity and explain the user what to do if application won’t work.
Foreground services generally should be used for task which require user attention such as visual processes.
use Background service instead

From the notificationbar, to call the working Class

I'm developing an online radio application. The application works in the background. When I click the NotificationManager, radioclass starts working again. I want to call the radioclass that are running. How can I do?
player = MediaPlayer.create(this, Uri.parse("http://...../playlist.m3u8"));
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer player) {
}
});
player.start();
final int notificationID = 1234;
String msg = "mesajjj";
Log.d(TAG, "Preparing to update notification...: " + msg);
NotificationManager mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, RadioClass.class);
//Here RadioClass running again. But RadioClass already running. I should call RadioClass that is running.
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.logotam)
.setContentTitle("Test FM")
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(pendingIntent);
mNotificationManager.notify(notificationID, mBuilder.build());
If you want to go back to the same activity you are currently running, you can do it like this:
Add the following tag on your AndroidManifest.xml:
<activity
........
android:launchMode="singleTop" >
........
</activity>
Modify your PendingIntent like this:
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
With this modifications, you ensure that your activity will only have one instance at any given time. On your activity class, you can also override the onNewIntent method:
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
}
This method will handle all of the additional calls to your activity.

Notification PendingIntent hard bug (or really simple one)

I'm trying to debug this for ages now and I just can't seem to find the problem:
I have a broadcast receiver, which receives the broadcast successfully.
The notification has two actions ("buttons"):
firstIntent = null;
secondIntent = null;
firstPendingIntent = null; //first "button" to join with the first intent
secondPendingIntent = null; //second "button" to join with the second intent
if(boolean){
//relevant
firstIntent = new Intent(getBaseContext(), NotificationFunctions.class).putExtra("action", "do_this");
secondIntent = new Intent(getBaseContext(), NotificationFunctions.class).putExtra("action", "do_that");
}else{
firstIntent = new Intent(getBaseContext(), NotificationFunctions.class).putExtra("action", "do_another_this");
secondIntent = new Intent(getBaseContext(), NotificationFunctions.class).putExtra("action", "do_another_that");
}
firstPendingIntent = PendingIntent.getBroadcast(getBaseContext(), 0, firstIntent, PendingIntent.FLAG_UPDATE_CURRENT);
secondPendingIntent = PendingIntent.getBroadcast(getBaseContext(), 0, secondIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notification = new NotificationCompat.Builder(getApplicationContext())
.setContentTitle(notification_title)
.setContentText(notification_text)
.setTicker("Notification!")
.setWhen(System.currentTimeMillis())
.setDefaults(Notification.DEFAULT_SOUND)
.addAction(R.drawable.abc_cab_background_top_holo_light, first_option, firstPendingIntent)
.addAction(R.drawable.abc_cab_background_top_holo_dark, second_option, secondPendingIntent)
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_stat_name)
.build();
Whenever I debug in the broadcastReceiver, for some reason, action from extras always logs "do_that", even if I click the first or second button of the notification. Any reason for this? I cant really seem to understand why.
public class NotificationFunctions extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
boolean feedback;
String action = intent.getExtras().getString("action");
Log.wtf("...", action); //logs do_that
}}
Any reason for this?
Because firstPendingIntent == secondPendingIntent.
If there already is a PendingIntent matching your request, getBroadcast() returns the existing PendingIntent. FLAG_UPDATE_CURRENT says to replace the extras in the Intent wrapped inside the PendingIntent.
In one of your two getBroadcast() calls, replace 0 with some other number, to get distinct PendingIntent objects.
Also, I recommend that you replace getBaseContext() and getApplicationContext() with this. Only use getBaseContext() and getApplicationContext() when you know precisely why you are using them.

Cancel notification not working

I want to cancel/delete the notification after I click the addAction.
However it's not working. The notification is still there after the click.
I'm pretty sure this worked in an other project.
Can anyone see a stupid error I made, why its not working?
Actual code:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1) {
showNotification(context);
}
private void showNotification(Context context){
String onderwerp = ("Medicatietijd");
String name = ("Het is tijd om je medicitie in te nemen.");
// Geluid notificatie
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
// Notificatie trigger
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, Test.class), 0);
// De notificatie
Notification mNotification = new Notification.Builder(context)
.setContentTitle(onderwerp)
.setContentText(name)
.setSmallIcon(R.drawable.ninja)
.setSound(soundUri)
.addAction(R.drawable.ja, "Ja, ik heb ze ingenomen.", contentIntent)
.setAutoCancel(true)
.build();
NotificationManager notificationManager
= (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotification.vibrate = new long[]{100, 200, 100, 500};
mNotification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, mNotification);
}
Solution:
In test activity OnCreate added this:
NotificationManager notificationManager
= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(0);
If you decided to use Test activity to receive the intent of your addAction call, then you must cancel notification when you receive the intent in the activity.
I also recommend that you add requestCode for the intent.
Here is the code :
to set the requestCode modify this :
static final int REQ_CODE = 101; // some number
// Notificatie trigger
PendingIntent contentIntent = PendingIntent.getActivity(context, REQ_CODE,
new Intent(context, Test.class), 0);
to Handle intent in activity and dismiss the notification, in Test activity class :
#Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
if (requestCode == REQ_CODE) {
// dismiss notification
notificationManager.cancel(0);
// handle your action
// ...
}
}
Hope that helps

Categories