When I click a button, I create a notification in Status Bar.
By being clicked, this notification creates an activity.
In the layout of this activity, there is a button.
When I click this button, the notification that created the activity where the button is, must be canceled.
The problem comes because I can create more than one notifications, giving to them different IDs.
But when I open the Status Bar, I see al the notifications, I select one, the activity is created and I click the button to cancel the activity.
What happens is that the notification canceled is always the last created instead of being the one I selected.
This is the code from the main activity, where notifications are created:
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.ButtonBarLayout;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class NotifMenuActiv extends AppCompatActivity {
private Button but_notif, but_cancel;
private NotificationManager mNotificationManager;
private Notification.Builder mBuilder;
private EditText id;
private Intent resultIntent;
private PendingIntent pIntent;
private int req_code = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notif_menu);
mNotificationManager = (NotificationManager)getSystemService(Context
.NOTIFICATION_SERVICE);
mBuilder = new Notification.Builder(this);
mBuilder.setSmallIcon(R.drawable.joda);
resultIntent = new Intent(this, NotifActiv.class);
id = (EditText)findViewById(R.id.id);
but_notif = (Button)findViewById(R.id.but_notif);
but_notif.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
resultIntent.putExtra("id", Integer.valueOf(id.getText().
toString()));
pIntent = PendingIntent.getActivity(getApplicationContext(),
req_code++, resultIntent, PendingIntent
.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(pIntent);
mBuilder.setContentTitle(id.getText().toString());
mNotificationManager.notify(Integer.valueOf(id.getText().
toString()),mBuilder.build());
mBuilder.setContentText(Integer.valueOf(mNotificationManager
.getActiveNotifications().length).toString());
mNotificationManager.notify(Integer.valueOf(id.getText().
toString()),mBuilder.build());
}
}
});
but_cancel = (Button)findViewById(R.id.but_cancel1);
but_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mNotificationManager.cancel(Integer.valueOf(id.getText().
toString()));
}
});
}
}
And this is the onCreate method from the activity created when I click on a notification:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notif);
Intent intent = getIntent();
id = intent.getIntExtra("id",id);
mNotificationManager = (NotificationManager)getSystemService(Context
.NOTIFICATION_SERVICE);
but_exit = (Button)findViewById(R.id.but_exit);
but_exit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
// This is the button that must cancel the notification that created
// the activity
but_cancel = (Button)findViewById(R.id.but_cancel2);
but_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mNotificationManager.cancel(id);
}
});
}
Thank you very much.
SOLVED!!! the solution is to give a different requestCode to each PedingIntent.
Instead of this:
PendingIntent pIntent = PendingIntent.getActivity(getApplicationContext(),0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Do this:
PendingIntent pIntent = PendingIntent.getActivity(getApplicationContext(),req_code++, resultIntent,PendingIntent.FLAG_UPDATE_CURRENT);
Related
Why is deleteIntent(PendingIntent) not called when notification is canceled?
I am doing this android tutorial on Notifications and in the 'extra challenge', am using deleteIntent.
However it is not invoked at all. Running in the emulator on API 27.
When I swipe the notification to cancel, the cancelNotification() method is not called.
In the docs, I see the watermark 'deprecated' on the page but it's not in the text.
Not sure if it's actually deprecated or if I am using deleteIntent() wrongly.
https://codelabs.developers.google.com/codelabs/android-training-notifications/#6
In the NotifyMe app, there is one use case in which the state of your
buttons does not match the state of the app: when a user dismisses a
notification by swiping it away or clearing the whole notification
drawer. In this case, your app has no way of knowing that the
notification was canceled and that the button state must be changed.
Create another pending intent to let the app know that the user has
dismissed the notification, and toggle the button states accordingly.
Hint: Check out the NotificationCompat.Builder class for a method that
delivers an Intent if the user dismisses the notification.
package com.notifyme;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private static final String PRIMARY_CHANNEL_ID = "primary_notification_channel";
private NotificationManager mNotifyManager;
private static final int NOTIFICATION_ID = 0;
private static final String ACTION_UPDATE_NOTIFICATION =
"com.example.android.notifyme.ACTION_UPDATE_NOTIFICATION";
private static final String ACTION_CANCEL_NOTIFICATION =
"com.example.android.notifyme.ACTION_CANCEL_NOTIFICATION";
private NotificationReceiver mReceiver = new NotificationReceiver();
public class NotificationReceiver extends BroadcastReceiver {
public NotificationReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case ACTION_UPDATE_NOTIFICATION:
updateNotification();;
break;
case ACTION_CANCEL_NOTIFICATION:
cancelNotification();
break;
}
}
}
public void createNotificationChannel() {
mNotifyManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >=
android.os.Build.VERSION_CODES.O) {
// Create a NotificationChannel
NotificationChannel notificationChannel = new NotificationChannel(PRIMARY_CHANNEL_ID,
"Mascot Notification", NotificationManager
.IMPORTANCE_HIGH);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.enableVibration(true);
notificationChannel.setDescription("Notification from Mascot");
mNotifyManager.createNotificationChannel(notificationChannel);
}
}
private Button button_notify;
private Button button_cancel;
private Button button_update;
public void sendNotification() {
Intent updateIntent = new Intent(ACTION_UPDATE_NOTIFICATION);
PendingIntent updatePendingIntent = PendingIntent.getBroadcast
(this, NOTIFICATION_ID, updateIntent, PendingIntent.FLAG_ONE_SHOT);
Intent cancelIntent = new Intent(ACTION_CANCEL_NOTIFICATION);
PendingIntent cancelPendingIntent = PendingIntent.getBroadcast
(this, NOTIFICATION_ID, cancelIntent, PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notifyBuilder = getNotificationBuilder();
notifyBuilder.addAction(R.drawable.ic_update, "Update Notification", updatePendingIntent);
notifyBuilder.setDeleteIntent(cancelPendingIntent);
mNotifyManager.notify(NOTIFICATION_ID, notifyBuilder.build());
setNotificationButtonState(false, true, true);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button_notify = findViewById(R.id.notify);
button_notify.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendNotification();
}
});
createNotificationChannel();
button_update = findViewById(R.id.update);
button_update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Update the notification
updateNotification();
}
});
button_cancel = findViewById(R.id.cancel);
button_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Cancel the notification
cancelNotification();
}
});
registerReceiver(mReceiver,new IntentFilter(ACTION_UPDATE_NOTIFICATION));
setNotificationButtonState(true, false, false);
}
#Override
protected void onDestroy() {
unregisterReceiver(mReceiver);
super.onDestroy();
}
public void updateNotification() {
Bitmap androidImage = BitmapFactory
.decodeResource(getResources(),R.drawable.mascot_1);
NotificationCompat.Builder notifyBuilder = getNotificationBuilder();
notifyBuilder.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(androidImage)
.setBigContentTitle("Notification Updated!"));
mNotifyManager.notify(NOTIFICATION_ID, notifyBuilder.build());
setNotificationButtonState(false, false, true);
}
public void cancelNotification() {
mNotifyManager.cancel(NOTIFICATION_ID);
setNotificationButtonState(true, false, false);
}
private NotificationCompat.Builder getNotificationBuilder(){
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent notificationPendingIntent = PendingIntent.getActivity(this,
NOTIFICATION_ID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notifyBuilder = new NotificationCompat.Builder(this, PRIMARY_CHANNEL_ID)
.setContentTitle("You've been notified!")
.setContentText("This is your notification text.")
.setSmallIcon(R.drawable.ic_android)
.setContentIntent(notificationPendingIntent)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setAutoCancel(true);
return notifyBuilder;
}
void setNotificationButtonState(Boolean isNotifyEnabled,
Boolean isUpdateEnabled,
Boolean isCancelEnabled) {
button_notify.setEnabled(isNotifyEnabled);
button_update.setEnabled(isUpdateEnabled);
button_cancel.setEnabled(isCancelEnabled);
}
}
Update: From CommonsWare's helpful answer below, I corrected the registration of the receiver to use multiple Actions for the same IntentFilter. However it still failed even though I tried all the different flags for the PendingIntent.
When you press the Update button in the notification and then swipe right, the buttons in the Activity do not reset their states because the PendingIntent is not firing.
Here is my updated code.
package com.onedropaflame.notifyme;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private static final String PRIMARY_CHANNEL_ID = "primary_notification_channel";
private NotificationManager mNotifyManager;
private static final int NOTIFICATION_ID = 0;
private static final String ACTION_UPDATE_NOTIFICATION =
"com.example.android.notifyme.ACTION_UPDATE_NOTIFICATION";
private static final String ACTION_CANCEL_NOTIFICATION =
"com.example.android.notifyme.ACTION_CANCEL_NOTIFICATION";
private NotificationReceiver mReceiver = new NotificationReceiver();
public class NotificationReceiver extends BroadcastReceiver {
public NotificationReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case ACTION_UPDATE_NOTIFICATION:
updateNotification();;
break;
case ACTION_CANCEL_NOTIFICATION:
cancelNotification();
break;
}
}
}
public void createNotificationChannel() {
mNotifyManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >=
android.os.Build.VERSION_CODES.O) {
// Create a NotificationChannel
NotificationChannel notificationChannel = new NotificationChannel(PRIMARY_CHANNEL_ID,
"Mascot Notification", NotificationManager
.IMPORTANCE_HIGH);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.enableVibration(true);
notificationChannel.setDescription("Notification from Mascot");
mNotifyManager.createNotificationChannel(notificationChannel);
}
}
private Button button_notify;
private Button button_cancel;
private Button button_update;
public void sendNotification() {
Intent updateIntent = new Intent(ACTION_UPDATE_NOTIFICATION);
PendingIntent updatePendingIntent = PendingIntent.getBroadcast
(this, NOTIFICATION_ID, updateIntent, PendingIntent.FLAG_ONE_SHOT);
Intent cancelIntent = new Intent(ACTION_CANCEL_NOTIFICATION);
PendingIntent cancelPendingIntent = PendingIntent.getBroadcast
(this, NOTIFICATION_ID, cancelIntent, PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notifyBuilder = getNotificationBuilder();
notifyBuilder.addAction(R.drawable.ic_update, "Update Notification", updatePendingIntent);
notifyBuilder.setDeleteIntent(cancelPendingIntent);
mNotifyManager.notify(NOTIFICATION_ID, notifyBuilder.build());
setNotificationButtonState(false, true, true);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button_notify = findViewById(R.id.notify);
button_notify.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendNotification();
}
});
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_CANCEL_NOTIFICATION);
intentFilter.addAction(ACTION_UPDATE_NOTIFICATION);
createNotificationChannel();
registerReceiver(mReceiver,intentFilter);
button_update = findViewById(R.id.update);
button_update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Update the notification
updateNotification();
}
});
button_cancel = findViewById(R.id.cancel);
button_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Cancel the notification
cancelNotification();
}
});
setNotificationButtonState(true, false, false);
}
#Override
protected void onDestroy() {
unregisterReceiver(mReceiver);
super.onDestroy();
}
public void updateNotification() {
Bitmap androidImage = BitmapFactory
.decodeResource(getResources(),R.drawable.mascot_1);
NotificationCompat.Builder notifyBuilder = getNotificationBuilder();
notifyBuilder.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(androidImage)
.setBigContentTitle("Notification Updated!"));
mNotifyManager.notify(NOTIFICATION_ID, notifyBuilder.build());
setNotificationButtonState(false, false, true);
}
public void cancelNotification() {
mNotifyManager.cancel(NOTIFICATION_ID);
setNotificationButtonState(true, false, false);
}
private NotificationCompat.Builder getNotificationBuilder(){
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent notificationPendingIntent = PendingIntent.getActivity(this,
NOTIFICATION_ID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notifyBuilder = new NotificationCompat.Builder(this, PRIMARY_CHANNEL_ID)
.setContentTitle("You've been notified!")
.setContentText("This is your notification text.")
.setSmallIcon(R.drawable.ic_android)
.setContentIntent(notificationPendingIntent)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setAutoCancel(true);
return notifyBuilder;
}
void setNotificationButtonState(Boolean isNotifyEnabled,
Boolean isUpdateEnabled,
Boolean isCancelEnabled) {
button_notify.setEnabled(isNotifyEnabled);
button_update.setEnabled(isUpdateEnabled);
button_cancel.setEnabled(isCancelEnabled);
}
}
It appears as though you are not registering a receiver for ACTION_CANCEL_NOTIFICATION, just ACTION_UPDATE_NOTIFICATION.
Commonsware posted the correct answer about both actions needing to be registered.
However that was not sufficient. I corrected the registration of the receiver to use multiple Actions for the same IntentFilter. However it still failed even though I tried all the different flags for the PendingIntent. When you press the Update button in the notification and then swipe right, the buttons in the Activity do not reset their states because the PendingIntent is not firing.
Solution: I found that I had to set the cancelPendingIntent again during the updateNotification(). I do not know the reason why it is lost.
public void updateNotification() {
Bitmap androidImage = BitmapFactory
.decodeResource(getResources(),R.drawable.mascot_1);
NotificationCompat.Builder notifyBuilder = getNotificationBuilder();
notifyBuilder.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(androidImage)
.setBigContentTitle("Notification Updated!"));
// >>>>> SET AGAIN! >>>>>>>>>
Intent cancelIntent = new Intent(ACTION_CANCEL_NOTIFICATION);
PendingIntent cancelPendingIntent = PendingIntent.getBroadcast
(this, NOTIFICATION_ID, cancelIntent, PendingIntent.FLAG_ONE_SHOT);
notifyBuilder.setDeleteIntent(cancelPendingIntent);
// >>>>>>>>>>>>>>
mNotifyManager.notify(NOTIFICATION_ID, notifyBuilder.build());
setNotificationButtonState(false, false, true);
}
I am using this library for download
it works well but i want download my file in background i don't want use AsyncTask because it has so much code and my project is long .
so help me to download in background with this lib
this is my code :
Ion.with(getApplicationContext())
.load("http://example.com/pdf.zip") // file address
.progress(new ProgressCallback() {
#Override
public void onProgress(long downloaded, long total) {
progressBar.setProgress((int) downloaded);
progressBar.setMax((int) total);
}
})
.write(new File(direct + File.separator + "signal.zip")) //saving location
.setCallback(new FutureCallback<File>() {
#Override
public void onCompleted(Exception e, File result) {
btn24.setText("show");
btn24.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Card.this, Show.class);
startActivity(intent);
}
});
}
});
and this is my activity code :
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.preference.PreferenceManager;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import com.bumptech.glide.Glide;
import com.koushikdutta.async.future.FutureCallback;
import com.koushikdutta.ion.Ion;
import com.koushikdutta.ion.ProgressCallback;
import org.zeroturnaround.zip.ZipUtil;
import java.io.File;
import java.net.URL;
import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper;
public class Card extends AppCompatActivity {
private Button btn1;
private ProgressBar progresBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_card);
//getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
//toolbar.setNavigationIcon(R.drawable.toolbar_back_ltr);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
progressBar = (ProgressBar) findViewById(R.id.bar);
btn1 = (Button) findViewById(R.id.button);
if (Build.VERSION.SDK_INT >= 23) {
if (ContextCompat.checkSelfPermission(Card.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(Card.this, android.Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(Card.this,
new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.READ_EXTERNAL_STORAGE},
1);
} else {
//do something
}
} else {
//do something
}
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
direct = new File(Environment.getExternalStorageDirectory() + "/S/A");
if (!direct.exists()) {
direct.mkdirs();
}
btn1.setText("Downloading . . .");
Ion.with(getApplicationContext())
.load("http://example.com/pdf.zip") // file address
.progress(new ProgressCallback() {
#Override
public void onProgress(long downloaded, long total) {
progressBar.setProgress((int) downloaded);
progressBar.setMax((int) total);
}
})
.write(new File(direct + File.separator + "AmarVAEhtemal.zip")) // saving location
.setCallback(new FutureCallback<File>() {
#Override
public void onCompleted(Exception e, File result) {
btn1.setText("show");
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Card.this, Show.class);
startActivity(intent);
}
});
}
});
}
});
}
}
Use foreground service to protect your progress being killed.
use startService to start service
use startForeground(NOTIFICATION_ID, notification); to prevent from desctroying.
use your lib.
PROFIT!
start service:
Intent intent = new Intent(this, HelloService.class);
startService(intent);
service class:
public class ExampleService extends Service {
#Override
public void onCreate() {
// The service is being created
showForegroundNotification("some service");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// The service is starting, due to a call to startService()
return mStartMode;
}
#Override
public IBinder onBind(Intent intent) {
// A client is binding to the service with bindService()
return mBinder;
}
#Override
#Override
public void onDestroy() {
// The service is no longer used and is being destroyed
}
private static final int NOTIFICATION_ID = 1;
private void showForegroundNotification(String contentText) {
// Create intent that will bring our app to the front, as if it was tapped in the app
// launcher
Intent showTaskIntent = new Intent(getApplicationContext(), MyMainActivity.class);
showTaskIntent.setAction(Intent.ACTION_MAIN);
showTaskIntent.addCategory(Intent.CATEGORY_LAUNCHER);
showTaskIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(
getApplicationContext(),
0,
showTaskIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new Notification.Builder(getApplicationContext())
.setContentTitle(getString(R.string.app_name))
.setContentText(contentText)
.setSmallIcon(R.drawable.ic_notification)
.setWhen(System.currentTimeMillis())
.setContentIntent(contentIntent)
.build();
startForeground(NOTIFICATION_ID, notification);
}
}
start foreground example
https://gist.github.com/kristopherjohnson/6211176
androidManifest.xml
<service android:name=".ExampleService" . . . >
</service>
put pass extrad data use with:
Intent intent = new Intent(this, HelloService.class);
intent.putExtra("MYPARAMNAME","MYURL");
startService(intent);
to retrieve use this:
onStartCommand(Intent intent, ...
Bundle extras = intent.getExtras();
filename = extras.getString("MYPARAMNAME");
My goal is to
push a button btnAktivieren,
then after some time (defined by random) a notification is shown.
I tap this notification, which leads me to an alertdialog.
After this AlertDialog's choice was made, it goes back to 2.
So far, I only got to 3 even though the code should work the whole way through
What I tried
MainActivity.java
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
boolean aktiviert = false;
public EditText minutenVon = null;
public EditText minutenBis = null;
public Context con = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
con = this;
final Button btnAktivieren = (Button)findViewById(R.id.btnAktivieren);
btnAktivieren.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
minutenBis = (EditText)findViewById(R.id.etBis);
minutenVon = (EditText)findViewById(R.id.etVon);
EditText etAktuelleAufgabe = (EditText)findViewById(R.id.etAktuelleAufgabe);
if (aktiviert) {
btnAktivieren.setText("Aktivieren");
aktiviert = false;
}
else
{
btnAktivieren.setText("Deaktivieren");
Random random = new Random();
int w = (int) (random.nextDouble() * (Double.parseDouble(minutenBis.getText().toString()) - Double.parseDouble(minutenVon.getText().toString())) + Double.parseDouble(minutenVon.getText().toString()));
int interval = w * 60000;
int interval_in_sekunden = w * 60;
aktiviert = true;
String aufgabe = "";
if (etAktuelleAufgabe.getText().toString() == "")
aufgabe = "Diese Information";
else
aufgabe = etAktuelleAufgabe.getText().toString();
PendingIntent pendingIntent;
Intent intent;
intent = new Intent(con, Kommt.class);
intent.putExtra("aufgabe", aufgabe);
intent.putExtra("minutenVon", minutenVon.getText().toString());
intent.putExtra("minutenBis", minutenBis.getText().toString());
pendingIntent = PendingIntent.getBroadcast(con, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notificationBuilder = new Notification.Builder(con)
.setContentTitle(aufgabe)
.setContentText("Test")
.setSmallIcon(R.mipmap.ic_launcher)
.setWhen((System.currentTimeMillis()/1000)+interval_in_sekunden)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService (Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder);
}
}
});
}
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.test.test">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
<application
android:allowBackup="true"
android:launchMode="singleTop"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
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>
<receiver android:name=".Kommt" />
</application>
</manifest>
Kommt.java
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;
import java.util.Random;
public class Kommt extends BroadcastReceiver {
public Context con;
String aufgabe = "";
String minutenVon = "";
String minutenBis = "";
private Context mContext;
public void onReceive(Context context, Intent intent) {
con = context;
aufgabe = intent.getStringExtra("aufgabe");
minutenVon = intent.getStringExtra("minutenVon");
minutenBis = intent.getStringExtra("minutenBis");
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setIcon(R.mipmap.ic_launcher);
builder.setTitle(aufgabe)
.setMessage("Test");
builder.setPositiveButton("Ja", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
neu();
}
});
builder.setNegativeButton("Nein", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
AlertDialog.Builder builder = new AlertDialog.Builder(con);
builder.setIcon(R.mipmap.ic_launcher);
builder.setTitle("Test")
.setMessage("Test2");
builder.setPositiveButton("Gut", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
neu();
}
});
builder.create().show();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
public void neu()
{
Random random = new Random();
int w = (int) (random.nextDouble() * (Double.parseDouble(minutenBis.toString()) - Double.parseDouble(minutenVon.toString())) + Double.parseDouble(minutenVon.toString()));
int interval = w * 60000;
int interval_in_sekunden = w * 60;
String aufgabe = "";
if (aufgabe == "")
aufgabe = "Test";
PendingIntent pendingIntent;
Intent intent;
intent = new Intent(con, Kommt.class);
intent.putExtra("aufgabe", aufgabe);
pendingIntent = PendingIntent.getBroadcast(con, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notificationBuilder = new Notification.Builder(con)
.setContentTitle(aufgabe)
.setContentText("Testtest3")
.setSmallIcon(R.mipmap.ic_launcher)
.setWhen((System.currentTimeMillis()/1000)+interval_in_sekunden)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build();
NotificationManager notificationManager = (NotificationManager) con.getSystemService (Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder);
}
}
You are trying to open AlertDialog from BroadcastReceiver that is not able to find context(context you) .Do one thing redirect user to from broadcastreceiver and from there show alertdialog in onCreate.
Problem One : You have to pass theme in Alert Dialog
AlertDialog.Builder builder = new
AlertDialog.Builder(context,
R.style.AppTheme);
Secondly you can't show dialog from Broadcastreceiver its not getting context as a developer hope you know how to redirect user from Broadcastreceiver to activity .
Error you must be getting crash for this
java.lang.RuntimeException: Unable to start receiver
com.stackoverflow.Kommit:
android.view.WindowManager$BadTokenException: Unable to add window --
token null is not for an application
So redirect user to MainActivity instead of showing alertDialog and in onCreate of MainActivity show alert dialog where you will have context on MainActivity
UPDATED Kommit.java(onReceive)
Intent i = new Intent(context, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); Bundle b = new Bundle();
b.putInt("notify", 1);
i.putExtras(b); //Put your id to your next Intent
context.startActivity(i);
In MainActivity OnCreate()
Bundle b = getIntent().getExtras(); int value = 0; // or other values
if(b != null)
value = b.getInt("notify");
if(value !=0)
{
//show alertdialog
}
EDIT by P. Dee: Corrected your notify.
try to change the id for different notifications:
notificationManager.notify(0, notificationBuilder);
here change 0 to some dynamic number
Normally a dialog needs an Activity context, or make the dialog type a system alert dialog
alert.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
This needs the android.permission.SYSTEM_ALERT_WINDOW to be declared in manifest.
For my opinion , onReceive can only survive for 10 seconds. So if your random time is longer than 10 seconds,the notification object is destroied which is newed in onReceive. So my advice is that do this in a new thread in Service instead of Broadcast Receiver.
Hi I'd like to put notify to user to execute the application when application on background after 5 minutes.
So, I use onWindowFocusChanged to check my app is background or not. Please help me what should I do.This is my code. Please answer me with full code.
And I'd like to notify them with popup menu.
MainActivity.java
package com.myapp;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
.............//import is too long
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.myapp.R;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btnA = (Button)findViewById(R.id.btngetA);
btnA.setOnClickListener(new Button.OnClickListener(){
#Override
public void onClick(View v){
//TODO Auto-generated method stub
Intent intentA = new Intent(getApplicationContext(), gotoAActivity.class);
startActivity(intentA);
}
});
#Override
public void onWindowFocusChanged(boolean hasFocus) {
if (!hasFocus) {
new CountDownTimer(1000, 1) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
//timer finished
}
}.start();
}
super.onWindowFocusChanged(hasFocus);
}
this is notification. but I don't know where this codes should added..
public static void createService(Context context, CharSequence tickerMessage, CharSequence title,
CharSequence message, int icon, int id, Intent intent, long[] pattern, Boolean autoCancel) {
PendingIntent p = PendingIntent.getService(context, 0, intent, 0);
Notification n;
title="notice";
message="execute your app!!";
int apiLevel = Build.VERSION.SDK_INT;
if (apiLevel >= 11) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setContentTitle(title)
.setTicker(tickerMessage)
.setContentText(message)
.setSmallIcon(icon)
.setContentIntent(p)
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
if (pattern.length > 0) {
builder.setVibrate(pattern);
}
if (autoCancel != null) {
builder.setAutoCancel(autoCancel);
}
if (apiLevel >= 17) {
// Android 4.2+
n = builder.build();
}
else {
// Android 3.x
n = builder.getNotification();
}
}
else {
// Android 2.2+
n = new Notification(icon, tickerMessage, System.currentTimeMillis());
// Data
n.setLatestEventInfo(context, title, message, p);
}
NotificationManager nm = (NotificationManager)
context.getSystemService(Activity.NOTIFICATION_SERVICE);
nm.notify(id, n);
}
You should send the notification in onFinish() method but to be honest this code doesn't work at all. If your activity is in background can be killed by OS at anytime. What you could do is to set an alarm of 5 minutes in the onStop() callback of your activity and delete it in the onStart() callback. In this way if the activity is not started after 5 minutes you can do some work depending on what you want to do when the timer expires.
I am writing a simple service application, below is the code of Activity and Service..,when I am calling startService(), and stopService() its working fine for the one time,in my case it has to give notification..from next time onwards if call again startService(), and stopService() its not giving desired results...
---------- this is my activity class -------------
package com.mypack.serviceex;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class serviceex extends Activity implements Button.OnClickListener{
/** Called when the activity is first created. */
Button bt1,bt2;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
bt1 = (Button) findViewById(R.id.Button01);
bt2 = (Button) findViewById(R.id.Button02);
bt1.setOnClickListener(this);
bt2.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if( v == bt1)
{
Intent i = new Intent(serviceex.this,myservice.class);
Log.i("err","onClick(View v....");
startService(i);
}
else if(v == bt2)
{
Intent i = new Intent(serviceex.this,myservice.class);
Log.i("err","else if(v == bt2)........");
stopService(i);
}
}
}
--------- this is my service -------------
package com.mypack.serviceex;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class myservice extends Service
{
private NotificationManager nmgr;
public void onCreate()
{
super.onCreate();
nmgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Log.i("err","onCreate..........");
Thread th = new Thread(null,new incls(),"service...");
}
public void onStart(Intent intent,int sid)
{
super.onStart(intent, sid);
Log.i("err","onStart........");
}
public void onDestroy()
{
super.onDestroy();
Log.i("err","onDestroy..........");
displayMessage("Stopping Service");
}
public void displayMessage(String str)
{
Log.i("err.","displayMessage.....");
Notification nf = new Notification(R.drawable.icon,str,System.currentTimeMillis());
PendingIntent pi = PendingIntent.getActivity(this, 0, new Intent(this,myservice.class), 0);
nf.setLatestEventInfo(this, "Service...", str, pi);
nmgr.notify(R.string.uid, nf);
}
private class incls implements Runnable
{
public void run()
{
Log.i("err","public void run()..........");
System.out.println("In Runnn");
}
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
None of your methods are #Overrideing the class methods. You have to annote them with #Override. Also, on 2.1 you should use onStartCommand() instead of onStart(). And also note that calling startService() multiple times will only call onCreate() once