AlarmManager didn't work in oreo and later - alarmmanager

I used lots of method from alarmManager like
setRepeating, setInexactRepeating(),setExactAndAllowWhileIdle(),
also this too
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { manager.setAlarmClock(AlarmManager.AlarmClockInfo(c.timeInMillis , null),intentAlarm) }
everything is working well when app is running or in recent, but when i close the app it didn't do anything
I also give manifest permission
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
I look into this stackoverflow question and it didn't work for me
and also from this github project
Please help me i stuck for 3 days and didn't get solution that trigger my alarm when app is closed
here is my full code of implemantation
fun setAlarm(c: Calendar, context: Context, tick:Long, dayChoosen:ArrayList<String>) {
val manager = context.getSystemService(ALARM_SERVICE) as AlarmManager
//Notification Broadcast intent
val intentAlarm = Intent(context, MyReceiver::class.java).let {
it.putExtra("daysChoosenArrayList", dayChoosen)
it.putExtra("id", dayChoosen)
PendingIntent.getBroadcast(context, tick.toInt(), it, PendingIntent.FLAG_ONE_SHOT)
}
//alarm fire next day if this condition is not statisfied
if (c.before(Calendar.getInstance())) {
c.add(Calendar.DATE, 1)
}
//set alarm
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, c.timeInMillis, 24*60*60*1000,intentAlarm)
}
and broadcast receiver
class MyReceiver: BroadcastReceiver() {
override fun onReceive(p0: Context?, p1: Intent?) {
notification(p0!!,"nono")
}
}
notifcation()
fun notification(context: Context, text:String ){
// pendingIntent is an intent for future use i.e after
// the notification is clicked, this intent will come into action
val intent = Intent(context, MainActivity::class.java)
// FLAG_UPDATE_CURRENT specifies that if a previous
// PendingIntent already exists, then the current one
// will update it with the latest intent
// 0 is the request code, using it later with the
// same method again will get back the same pending
// intent for future reference
// intent passed here is to our afterNotification class
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
// checking if android version is greater than oreo(API 26) or not
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notificationChannel = NotificationChannel(channelId, description, NotificationManager.IMPORTANCE_HIGH)
notificationChannel.enableLights(true)
notificationChannel.lightColor = Color.GREEN
notificationChannel.enableVibration(false)
notificationManager.createNotificationChannel(notificationChannel)
builder = Notification.Builder(context, channelId)
.setContentText(text)
.setSmallIcon(R.drawable.ic_launcher_background)
.setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.ic_launcher_background))
.setContentIntent(pendingIntent)
} else {
builder = Notification.Builder(context)
.setContentText("heheh")
.setSmallIcon(R.drawable.ic_launcher_background)
.setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.ic_launcher_background))
.setContentIntent(pendingIntent)
}
notificationManager.notify(1234, builder.build())
}

Related

Can someone please explain the proper usage of Timers and Triggers in Apache Beam?

I'm looking for some examples of usage of Triggers and Timers in Apache beam, I wanted to use Processing-time timers for listening my data from pub sub in every 5 minutes and using Processing time triggers processing the above data collected in an hour altogether in python.
Please take a look at the following resources: Stateful processing with Apache Beam and Timely (and Stateful) Processing with Apache Beam
The first blog post is more general in how to handle states for context, and the second has some examples on buffering and triggering after a certain period of time, which seems similar to what you are trying to do.
A full example was requested. Here is what I was able to come up with:
PCollection<String> records =
pipeline.apply(
"ReadPubsub",
PubsubIO.readStrings()
.fromSubscription(
"projects/{project}/subscriptions/{subscription}"));
TupleTag<Iterable<String>> every5MinTag = new TupleTag<>();
TupleTag<Iterable<String>> everyHourTag = new TupleTag<>();
PCollectionTuple timersTuple =
records
.apply("WithKeys", WithKeys.of(1)) // A KV<> is required to use state. Keying by data is more appropriate than hardcode.
.apply(
"Batch",
ParDo.of(
new DoFn<KV<Integer, String>, Iterable<String>>() {
#StateId("buffer5Min")
private final StateSpec<BagState<String>> bufferedEvents5Min =
StateSpecs.bag();
#StateId("count5Min")
private final StateSpec<ValueState<Integer>> countState5Min =
StateSpecs.value();
#TimerId("every5Min")
private final TimerSpec every5MinSpec =
TimerSpecs.timer(TimeDomain.PROCESSING_TIME);
#StateId("bufferHour")
private final StateSpec<BagState<String>> bufferedEventsHour =
StateSpecs.bag();
#StateId("countHour")
private final StateSpec<ValueState<Integer>> countStateHour =
StateSpecs.value();
#TimerId("everyHour")
private final TimerSpec everyHourSpec =
TimerSpecs.timer(TimeDomain.PROCESSING_TIME);
#ProcessElement
public void process(
#Element KV<Integer, String> record,
#StateId("count5Min") ValueState<Integer> count5MinState,
#StateId("countHour") ValueState<Integer> countHourState,
#StateId("buffer5Min") BagState<String> buffer5Min,
#StateId("bufferHour") BagState<String> bufferHour,
#TimerId("every5Min") Timer every5MinTimer,
#TimerId("everyHour") Timer everyHourTimer) {
if (Objects.firstNonNull(count5MinState.read(), 0) == 0) {
every5MinTimer
.offset(Duration.standardMinutes(1))
.align(Duration.standardMinutes(1))
.setRelative();
}
buffer5Min.add(record.getValue());
if (Objects.firstNonNull(countHourState.read(), 0) == 0) {
everyHourTimer
.offset(Duration.standardMinutes(60))
.align(Duration.standardMinutes(60))
.setRelative();
}
bufferHour.add(record.getValue());
}
#OnTimer("every5Min")
public void onTimerEvery5Min(
OnTimerContext context,
#StateId("buffer5Min") BagState<String> bufferState,
#StateId("count5Min") ValueState<Integer> countState) {
if (!bufferState.isEmpty().read()) {
context.output(every5MinTag, bufferState.read());
bufferState.clear();
countState.clear();
}
}
#OnTimer("everyHour")
public void onTimerEveryHour(
OnTimerContext context,
#StateId("bufferHour") BagState<String> bufferState,
#StateId("countHour") ValueState<Integer> countState) {
if (!bufferState.isEmpty().read()) {
context.output(everyHourTag, bufferState.read());
bufferState.clear();
countState.clear();
}
}
})
.withOutputTags(every5MinTag, TupleTagList.of(everyHourTag)));
timersTuple
.get(every5MinTag)
.setCoder(IterableCoder.of(StringUtf8Coder.of()))
.apply(<<do something every 5 min>>);
timersTuple
.get(everyHourTag)
.setCoder(IterableCoder.of(StringUtf8Coder.of()))
.apply(<< do something every hour>>);
pipeline.run().waitUntilFinish();

Alarm Manager stops trigger PendingIntent after few moments

I try to create reminder app. My aim is to trigger notification every hour. I have used Alarm Manager to achieve it. Everything works correctly for first 2-3 hours. After that time notifications stop being deliveried. If I reopen app I get missing notification imediatelly.
Alarm Manager:
val intent = Intent(context, AlarmReceiver::class.java).apply {
action = context.getString(R.string.alarm_pending_action)
}
val alarmIntent = PendingIntent.getBroadcast(context, 0, intent, FLAG_UPDATE_CURRENT)
val datetimeToAlarm = Calendar.getInstance()
.apply {
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}
alarmManager.setRepeating(
AlarmManager.RTC_WAKEUP,
datetimeToAlarm.timeInMillis,
60 * 60 * 1000,
alarmIntent
)
AlarmReceiver:
override fun onReceive(context: Context, intent: Intent) {
if (intent.action != null) {
if (intent.action!!.equals(context.getString(R.string.alarm_pending_action), ignoreCase = true)) {
NotificationHelper.createNotification(context)
}
}
}
AndroidManifest
<receiver android:name=".alert.AlarmReceiver"/>
Thank you for your help
I solved my problem. Solution is to replace setRepeating by setAlarmClock and it works well.

How to create a ReplaySubject with RxCpp?

In my c++ project, I need to create Subjects having an initial value, that may be updated. On each subscription/update, subscribers may trigger then data processing... In a previous Angular (RxJS) project, this kind of behavior was handled with ReplaySubject(1).
I'm not able to reproduce this using c++ rxcpp lib.
I've looked up for documentation, snippets, tutorials, but without success.
Expected pseudocode (typescript):
private dataSub: ReplaySubject<Data> = new ReplaySubject<Data>(1);
private init = false;
// public Observable, immediatly share last published value
get currentData$(): Observable<Data> {
if (!this.init) {
return this.initData().pipe(switchMap(
() => this.dataSub.asObservable()
));
}
return this.dataSub.asObservable();
}
I think you are looking for rxcpp::subjects::replay.
Please try this:
auto coordination = rxcpp::observe_on_new_thread();
rxcpp::subjects::replay<int, decltype(coordination)> test(1, coordination);
// to emit data
test.get_observer().on_next(1);
test.get_observer().on_next(2);
test.get_observer().on_next(3);
// to subscribe
test.get_observable().subscribe([](auto && v)
printf("%d\n", v); // this will print '3'
});

Glass Mapper V4 Language Item Fallback, how to make it work with Autofac?

I am using Glass Mapper v4 with Autofac and cant figure out how to make it work with the Language Item Fall back module. There are examples of creating a class that implements IObjectConstructionTask (see below)
public class FallbackCheckTask : IObjectConstructionTask
{
public void Execute(ObjectConstructionArgs args)
{
if (args.Result == null)
{
var scContext = args.AbstractTypeCreationContext as SitecoreTypeCreationContext;
// if the item itself is null, regardless of version, abort
if (scContext.Item == null)
{
args.AbortPipeline();
return;
}
// we could be trying to convert rendering parameters to a glass model, and if so, just return.
if (String.Compare(scContext.Item.Paths.FullPath, "[orphan]/renderingParameters", true) == 0)
{
return;
}
// the default glassmapper code would simply abort pipeline if the context items version count for the current langauge was 0
// but this does not take item fallback into account
// added here a check on the fallback extension method GetFallbackItem, recursively (for chained fallback)
// and then if that fallback item is null or it's version count is 0 (and only then) would you go ahead and abort the pipeline
if (scContext.Item.Versions.Count == 0)
{
var fallBackItem = CheckRecursivelyForFallbackItem(scContext.Item);
if (fallBackItem == null)
args.AbortPipeline();
else if (fallBackItem.Versions.Count == 0)
args.AbortPipeline();
return;
}
}
}
// in the case of chained fallback, eg fr-CA -> en-CA -> en
// could be that the middle languages don't have versions either, but DO have a fallback item
// therefore, must check back further until either a version is found, or there are no more fallback items
private Item CheckRecursivelyForFallbackItem(Item thisItem)
{
var fallBackItem = thisItem.GetFallbackItem();
if (fallBackItem != null)
{
if (fallBackItem.Versions.Count == 0)
fallBackItem = CheckRecursivelyForFallbackItem(fallBackItem);
}
return fallBackItem;
}
}
Then you register (with Castle Windsor)
public static void CastleConfig(IWindsorContainer container){
var config = new Config();
container.Register(
Component.For<IObjectConstructionTask>().ImplementedBy<FallbackCheckTask>().LifestylePerWebRequest()
);
// config.EnableCaching = false;
container.Install(new SitecoreInstaller(config));
}
I am using Autofac and do not know how to perform the same action as above and assure it happens in the right order. I am registering my types the typical way (See below) but it doesn't seem to be hooking my FallbackCheckTask class.
public static void Register()
{
var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
// register our types
builder.RegisterType<FallbackCheckTask>().As<IObjectConstructionTask>().InstancePerLifetimeScope();
// build and set the resolver
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
I also have the Language Item Fallback wired up and working as expected if glass is not involved in fetching the items values. I understand why Glass is not mapping the data out of the box, I just cant seem to get the fix working. Any thoughts?
EDIT 2015-05-21 19:00
I edited GlassMapperScCustom.cs as follows:
public static IDependencyResolver CreateResolver(){
var config = new Glass.Mapper.Sc.Config();
var resolver = new DependencyResolver(config);
resolver.ObjectConstructionFactory.Add(() => new FallbackCheckTask());
return resolver;
}
And now its calling the Execute method of the the FallbackCheckTask only if there is a version of the item, if there is no version its not calling the method. Also, no matter what I do if I enable this Task my test query items always come back as NULL:
var test = SitecoreContext.QuerySingle<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}");
var test1 = SitecoreContext.Query<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}").ToList();
var test2 = SitecoreContext.GetCurrentItem<Item>();
var test3 = SitecoreContext.GetItem<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}");
So to sum it up, I am a little better off now then I was before but when the task class is registered queries come back as null for all items no matter if they have a version or not. As mentioned before, any help is appreciated.
I know you mentioned that you were using the VersionCountDisabler but does it look like this:
using(new VersionCountDisabler()){
var test = SitecoreContext.QuerySingle<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}");
var test1 = SitecoreContext.Query<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}").ToList();
var test2 = SitecoreContext.GetCurrentItem<Item>();
var test3 = SitecoreContext.GetItem<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}");
}
Or are you disabling it in some other manner?
I also notice that your fallback code doesn't seem to update the scContent.Item property. I think you need to update it to the following:
public class FallbackCheckTask : IObjectConstructionTask
{
public void Execute(ObjectConstructionArgs args)
{
if (args.Result == null)
{
var scContext = args.AbstractTypeCreationContext as SitecoreTypeCreationContext;
// if the item itself is null, regardless of version, abort
if (scContext.Item == null)
{
args.AbortPipeline();
return;
}
// we could be trying to convert rendering parameters to a glass model, and if so, just return.
if (String.Compare(scContext.Item.Paths.FullPath, "[orphan]/renderingParameters", true) == 0)
{
return;
}
// the default glassmapper code would simply abort pipeline if the context items version count for the current langauge was 0
// but this does not take item fallback into account
// added here a check on the fallback extension method GetFallbackItem, recursively (for chained fallback)
// and then if that fallback item is null or it's version count is 0 (and only then) would you go ahead and abort the pipeline
if (scContext.Item.Versions.Count == 0)
{
var fallBackItem = CheckRecursivelyForFallbackItem(scContext.Item);
if (fallBackItem == null)
args.AbortPipeline();
else if (fallBackItem.Versions.Count == 0)
args.AbortPipeline();
//don't just return but update the scContext.Item to the fallback item
scContext.Item = fallbackItem;
}
}
}
// in the case of chained fallback, eg fr-CA -> en-CA -> en
// could be that the middle languages don't have versions either, but DO have a fallback item
// therefore, must check back further until either a version is found, or there are no more fallback items
private Item CheckRecursivelyForFallbackItem(Item thisItem)
{
var fallBackItem = thisItem.GetFallbackItem();
if (fallBackItem != null)
{
if (fallBackItem.Versions.Count == 0)
fallBackItem = CheckRecursivelyForFallbackItem(fallBackItem);
}
return fallBackItem;
}
}

flex 3 getting webserice call to wait for result

i have a function which retrieves values from a webservice , then loops through the returned values and for each returned value does another webservice lookup.
Im having a problem however that when i make the second webservice call within the for loop that the function does not wait for the reuslt and just keeps processing and in turn giving me no value
the code looks like this;
private function getResult(e:ResultEvent):void{
var lengthOfResult:int = e.result.length;
var arrayCollResults:ArrayCollection = new ArrayCollection();
var resultArray:Array = new Array(e.result);
for(var i:int = 0 ; i < lengthOfResult; i++){
var currentName:String = e.result[i].toString();
arrayCollResults.addItem(e.result[i] + ws.getMatches(currentName));
}
acu.dataProvider = arrayCollResults;
}
what can i do to insure that the value of ws.getMatches(currentName) actually returns a value before moving to next line?
The documentation here indicates that you do not call the Web service directly, you need to set up an event listener and handle the response on completed delivery.
From the section "Calling web services in ActionScript":
<?xml version="1.0"?>
<!-- fds\rpc\WebServiceInAS.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.rpc.soap.WebService;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
private var ws:WebService;
public function useWebService(intArg:int, strArg:String):void {
ws = new WebService();
ws.destination = "echoArgService";
ws.echoArgs.addEventListener("result", echoResultHandler);
ws.addEventListener("fault", faultHandler);
ws.loadWSDL();
ws.echoArgs(intArg, strArg);
}
public function echoResultHandler(event:ResultEvent):void {
var retStr:String = event.result.echoStr;
var retInt:int = event.result.echoInt;
//Do something.
}
public function faultHandler(event:FaultEvent):void {
//deal with event.fault.faultString, etc
}
]]>
</mx:Script>
</mx:Application>
Put the "arrayCollResults.addItem(...)" segment in the result handler for your ws.getMatches() event.
As far as I know flex/as3 cannot do a blocking wait for the result - you have to add a listener and wait to be notified.