I keep getting the error syntax error expecting right parren befor public. -ide
public class FlashlightWidgetProvider extends AppWidgetProvider {
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
Intent receiver = new Intent(context, FlashlightWidgetReceiver.class);
receiver.setAction("COM_FLASHLIGHT");
receiver.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, receiver, 0);
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.widget_layout);
views.setOnClickPendingIntent(R.id.button, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, views);
}
}
Related
In my Xamarin Forms project I have:
[BroadcastReceiver(Permission = "RECEIVE_BOOT_COMPLETED",
Exported = true,
Enabled = true)]
[IntentFilter(new[] {Intent.ActionBootCompleted})]
public class GeofenceReceiver: BroadcastReceiver
I use it for GeofenceTransitionEnter and GeofenceTransitionExit events.
I also have ACCESS_FINE_LOCATION and ACCESS_BACKGROUND_LOCATION permissions.
But OnReceive method is not called on API 31. I have not this problem with lower APIs.
Android 12 targetSDKVersion 31 challenges (Broadcast Receiver, Pending Intent) Crash Issues - doesn't work for me
I have done a sample to test. And it worked well, the OnReceive method will call a few minutes after the device restarted.
The receiver:
[BroadcastReceiver(Permission = "RECEIVE_BOOT_COMPLETED",
Exported = true,
Enabled = true)]
[IntentFilter(new[] { Intent.ActionBootCompleted })]
public class GeofenceReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
//launch our activity
if (intent.Action == "android.intent.action.BOOT_COMPLETED")
{
Toast.MakeText(context,"Device Restart",ToastLength.Long).Show();
Intent intent1 = new Intent(context,typeof(ForegroundServiceDemo));
intent1.SetFlags(ActivityFlags.NewTask);
context.StartForegroundService(intent1);
}
}
}
The foreground service:
[Service]
public class ForegroundServiceDemo : Service
{
private string NOTIFICATION_CHANNEL_ID = "1000";
private int NOTIFICATION_ID = 1;
private string NOTIFICATION_CHANNEL_NAME = "notification";
private void startForegroundService()
{
var notifcationManager = GetSystemService(Context.NotificationService) as NotificationManager;
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
createNotificationChannel(notifcationManager);
}
var notification = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
notification.SetAutoCancel(false);
notification.SetOngoing(true);
notification.SetSmallIcon(Resource.Mipmap.icon);
notification.SetContentTitle("ForegroundService");
notification.SetContentText("Foreground Service is running");
StartForeground(NOTIFICATION_ID, notification.Build());
}
private void createNotificationChannel(NotificationManager notificationMnaManager)
{
var channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME,
NotificationImportance.Low);
notificationMnaManager.CreateNotificationChannel(channel);
}
public override IBinder OnBind(Intent intent)
{
return null;
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
startForegroundService();
return StartCommandResult.NotSticky;
}
}
The AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
I added the RECEIVE_BOOT_COMPLETED into the AndroidManifes.xml, because if I just added it in the [BroadcastReceiver], the receiver will not work. So you can also try to add it in the AndroidManifes.xml.
In addition, you can create a new project to test my code. It worked on Android 12.0 emulator when I tested it. Finally, if it still not work, could you please show the code in the OnReceive method? Maybe the OnReceive method was called, but the code in it can't run background such as start an activity.
I just added something like this into GepfencePendingIntent:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)
} else {
PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
I found it here: https://www.flybuy.com/android-12-pendingintent-mutability-and-geofences
I'm working in a xamarin forms app, and I'm trying to develop an Android notification with two buttons:
In the first one you can write text, and this text must be retrieve to one of the ViewModels.
The second one should open a view of the app.
I have no experience with intents nor Android, and so far I can show the notification with the two buttons:
notification example
The class in charge of showing the notification is LocalNotifications : ILocalNotifications class in the Android solution:
class LocalNotifications : ILocalNotifications
{
const string channelId = "default";
const string channelName = "Default";
const string channelDescription = "The default channel for notifications.";
...
bool channelInitialized = false;
int messageId = 0;
int replyPendingIntentId = 0;
int photoPendingIntentId = 0;
NotificationManager manager;
public event EventHandler NotificationReceived;
public static LocalNotifications Instance { get; private set; }
public LocalNotifications() => Initialize();
public void Initialize()
{
if (Instance == null)
{
CreateNotificationChannel();
Instance = this;
}
}
public void SendNotification(string title, string message)
{
if (!channelInitialized)
{
CreateNotificationChannel();
}
Show(title, message);
}
public void ReceiveNotification(string title, string message)
{
var args = new NotificationEventArgs()
{
Title = title,
Message = message,
};
NotificationReceived?.Invoke(null, args);
}
private static readonly string KEY_TEXT_REPLY = "key_text_reply";
AndroidX.Core.App.RemoteInput remoteEntryInput = new AndroidX.Core.App.RemoteInput.Builder(KEY_TEXT_REPLY)
.SetLabel("Escribir entrada")
.Build();
private Intent replyIntent;
private Intent photoIntent;
public void Show(string title, string message)
{
NotificationCompat.Builder builder = new NotificationCompat.Builder(AndroidApp.Context, channelId)
.SetContentTitle(title)
.SetContentText(message)
.SetLargeIcon(BitmapFactory.DecodeResource(AndroidApp.Context.Resources, Resource.Drawable.abc_ab_share_pack_mtrl_alpha))
.SetSmallIcon(Resource.Drawable.abc_ab_share_pack_mtrl_alpha)
.SetDefaults((int)NotificationDefaults.Sound | (int)NotificationDefaults.Vibrate);
NotificationCompat.Action reply = CreateReplyIntent(title, message);
builder.AddAction(reply);
NotificationCompat.Action image = CreateImageIntent();
builder.AddAction(image);
Notification notification = builder.Build();
manager.Notify(messageId++, notification);
}
NotificationCompat.Action CreateReplyIntent(string title, string message)
{
//replyIntent = new Intent(AndroidApp.Context, typeof(MainActivity));
replyIntent = new Intent();
replyIntent.PutExtra(TitleKey, title);
replyIntent.PutExtra(MessageKey, message);
// Build a PendingIntent for the reply action to trigger.
PendingIntent replyPendingIntent =
PendingIntent.GetBroadcast(AndroidApp.Context, replyPendingIntentId++, replyIntent, PendingIntentFlags.UpdateCurrent);
// Create the reply action and add the remote input.
return new NotificationCompat.Action.Builder(Resource.Drawable.abc_ab_share_pack_mtrl_alpha,
"Escribir entrada", replyPendingIntent)
.AddRemoteInput(remoteEntryInput)
.Build();
}
NotificationCompat.Action CreateImageIntent()
{
//photoIntent = new Intent("android.media.action.IMAGE_CAPTURE");
photoIntent = new Intent(AndroidApp.Context, typeof(MainActivity));
//photoIntent.SetFlags( ActivityFlags.LaunchAdjacent | Intent.FLAG_ACTIVITY_CLEAR_TASK);
// Build a PendingIntent for the reply action to trigger.
PendingIntent phtoPendingIntent = PendingIntent.GetBroadcast(AndroidApp.Context, photoPendingIntentId++, photoIntent, PendingIntentFlags.UpdateCurrent);
return new NotificationCompat.Action.Builder(Resource.Drawable.abc_ab_share_pack_mtrl_alpha,
"Sacar foto", phtoPendingIntent)
.Build();
}
void CreateNotificationChannel()
{
manager = (NotificationManager)AndroidApp.Context.GetSystemService(AndroidApp.NotificationService);
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
var channelNameJava = new Java.Lang.String(channelName);
var channel = new NotificationChannel(channelId, channelNameJava, NotificationImportance.Default)
{
Description = channelDescription
};
manager.CreateNotificationChannel(channel);
}
channelInitialized = true;
}
}
Which a don't get is how/where the app can react to those PendintIntents and how to pass the information from the android solution to the xamarin forms model.
I am trying to implement a feature where you choose a date and time and the notification pops up on your phone. so after writing some code its still not working but everything seems fine
Activity code
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onClick(View view) {
Calendar customCalendar = GregorianCalendar.getInstance();
DatePicker dp = findViewById(R.id.date_picker);
TimePicker picker = findViewById(R.id.time_picker);
customCalendar.set(
dp.getYear(), dp.getMonth(), dp.getDayOfMonth(), picker.getHour(), picker.getMinute(), 0);
long customTime = customCalendar.getTimeInMillis();
SimpleDateFormat sdf = new SimpleDateFormat(getString(R.string.notification_schedule_pattern), Locale.getDefault());
long currentTime = System.currentTimeMillis();
Log.d("time", "cistomTime " + customTime);
Log.d("time", "cistomTime " + currentTime);
if (customTime > currentTime) {
Data data = new Data.Builder().putInt(NOTIFICATION_ID, 0).build();
int delay = (int) (customTime - currentTime);
scheduleNotification(delay, data);
String titleNotificationSchedule = getString(R.string.notification_schedule_title);
Snackbar.make(
view,
titleNotificationSchedule + sdf
.format(customCalendar.getTime()),
LENGTH_LONG).show();
// Snackbar.make(coordinatorLayout, "Reminder set", LENGTH_LONG)
// .setAction("Action", null).show();
} else {
String errorNotificationSchedule = "Error occured";
Snackbar.make(coordinatorLayout, errorNotificationSchedule, LENGTH_LONG).show();
}
}
});
}
private void scheduleNotification(long delay, Data data) {
OneTimeWorkRequest notificationWork = new OneTimeWorkRequest.Builder(NotifyWork.class)
.setInitialDelay(delay, MILLISECONDS).setInputData(data).build();
WorkManager instanceWorkManager = WorkManager.getInstance(getApplicationContext());
instanceWorkManager.beginUniqueWork(NOTIFICATION_WORK, REPLACE, notificationWork).enqueue();
}
Worker class
public class NotifyWork extends Worker {
public static final String NOTIFICATION_ID = "notification_id";
public static final String NOTIFICATION_NAME = "Remember";
public static final String NOTIFICATION_CHANNEL = "Reminder_Channel";
public static final String NOTIFICATION_WORK = "Notification_Work";
public NotifyWork(#NonNull Context context, #NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
#NonNull
#Override
public Result doWork() {
int id = getInputData().getInt(NOTIFICATION_ID, 0);
sendNotification(id);
return Result.success();
}
private void sendNotification(int id) {
NotificationManager notificationManager = (NotificationManager) getApplicationContext()
.getSystemService(Context.NOTIFICATION_SERVICE);
Bitmap bitmap = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.ic_done_white_24dp);
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra(NOTIFICATION_ID, id);
String titleNotification = "Reminder";
String subtitleNotification = "Time To WakeUp";
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notification = new NotificationCompat.Builder(getApplicationContext(), NOTIFICATION_CHANNEL)
.setLargeIcon(bitmap).setContentTitle(titleNotification)
.setContentText(subtitleNotification).setDefaults(IMPORTANCE_DEFAULT).setSound(getDefaultUri(TYPE_NOTIFICATION))
.setContentIntent(pendingIntent).setAutoCancel(true);
notification.setPriority(IMPORTANCE_MAX);
notificationManager.notify(id, notification.build());
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
Uri ringtoneManager = getDefaultUri(TYPE_NOTIFICATION);
AudioAttributes audioAttributes = new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE)
.setContentType(CONTENT_TYPE_SONIFICATION).build();
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL, NOTIFICATION_NAME, NotificationManager.IMPORTANCE_DEFAULT);
channel.enableLights(true);
channel.setLightColor(RED);
channel.enableVibration(true);
channel.setSound(ringtoneManager, audioAttributes);
notificationManager.createNotificationChannel(channel);
}
}
I have a DatePicker and TimePicker, when you select date and time and click on the FAB button, you get notified at that particular time
somehow changing .setLargeIcon to .setSmallIcon and referencing the image directly without converting to bitmap eg .setSmallIcon(R.drawable.ic_done_white_24dp) solved the issue
how to get Notification with out using google cloud . i thought of running a thread in back ground service and update the Notification but how i can i do it.pls help me out thanks in advance
public class BackgroundThread implements Runnable {
#Override
public void run() {
List<InvoiceDetail> invoiceDetails = JsonReader.getInvoice();
if (invoiceDetails.size() > 0) {
NotificationManager nfman = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
int notifyID = 1;
NotificationCompat.Builder builder = new NotificationCompat.Builder(
LoginActivity.this).setContentTitle("WORK ASSIGNED")
.setContentText("You've received new messages.");
builder.setContentText("hai");
nfman.notify(1, builder.build());
}
}
}
public class Notifier extends BroadcastReceiver {
#SuppressWarnings("deprecation")
#Override
public void onReceive(Context context, Intent intent) {
SharedPreferences sPrefs = context.getSharedPreferences("loginData", 0);
String id = sPrefs.getString("id", "default value");
String userss = sPrefs.getString("user", "default value");
String pass = sPrefs.getString("pass", "default value");
if (id.trim().length() > 0) {
List<NotifierDetail> subjects = DataBase.notificationMethod(id);
if (subjects.size() > 0) {
User user = new User();
user.setUserName(userss);
user.setPassWord(pass);
User users = DataBase.login(user);
BaseConstants.user = users;
for (NotifierDetail sub : subjects) {
NotificationManager nm = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(
R.drawable.logo, " Notification Today",
System.currentTimeMillis());
notification.defaults=Notification.DEFAULT_SOUND;
notification.defaults=Notification.DEFAULT_VIBRATE;
DataBase.updateNotificationMethod(sub.getId());
notification.flags = Notification.FLAG_AUTO_CANCEL;
Intent in = new Intent(context, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(context, 0,
in, 0);
CharSequence name = "Notification";
CharSequence mess = name + " about " + sub.getSubject();
notification.setLatestEventInfo(context, name, mess, pi);
nm.notify(0, notification);
}
}
}
}
}
i want to generate a notification bar showing the progress via builder method but i dont know where i am going wrong.if anyone who can tell me where i am wrong and help me i will be thankful.....
public class DownloadReceiver extends ResultReceiver{
private final static String TAG = "DownloadReceiver";
public Context context;
public DownloadReceiver(Handler handler,Context context) {
super(handler);
this.context = context;
Log.d(TAG,handler.getLooper().getThread().getName());
}
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
Log.d(TAG,"in download receiver");
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Service.NOTIFICATION_SERVICE);
Intent notifyIntent = new Intent(android.content.Intent.ACTION_VIEW,Uri.parse("http://www.android.com"));
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notifyIntent, 0);
if(resultCode == DownloadService.COMPLETED){
Log.d(TAG,resultCode + "");
Builder notificationBuilder = new NotificationCompat.Builder(context)
.setProgress(100, 20, false)
.addAction(R.drawable.ic_action_search, "title", pendingIntent)
.setWhen(System.currentTimeMillis());
// notification.flags = Notification.FLAG_ONGOING_EVENT;
// notification.setLatestEventInfo(context, "contentTitle", "contentText", pendingIntent);
notificationManager.notify(50, notificationBuilder.build());
}else if(resultCode == DownloadService.ALLCOMPLETED){
}
}
}
I just had to deal with this just now, the solution for me was that you have to add a notification image
.setSmallIcon(R.drawable.launcher)
otherwise it won't show anything. The old notification method didn't require you to set this yourself, as it would default to the app's icon.