i am scheduling my customer through alarm manager to get notification on time that i set. Now everything is working fine i get local notification, but i am not able to cancel that specific notification its keep coming after every minute.
here is my viewmodel code PCL
for cancel :
void Switch_Toggled()
{
if (NotificationONOFF == false)
{
MessageText = string.Empty;
SelectedTime = DateTime.Now.TimeOfDay;
SelectedDate = DateTime.Today;
DependencyService.Get<ILocalNotificationService>().Cancel(Convert.ToInt32(Settings.Customerid));
}
}
for save alarm
DependencyService.Get<ILocalNotificationService>().LocalNotification("Local Notification", MessageText, Convert.ToInt32(Settings.Customerid) , selectedDateTime);
code in xamarin.android
for canel:
public void Cancel(int id)
{
var intent = CreateIntent(id);
var pendingIntent = PendingIntent.GetBroadcast(Application.Context, Convert.ToInt32(_randomNumber), intent, PendingIntentFlags.Immutable);
var alarmManager = GetAlarmManager();
alarmManager.Cancel(pendingIntent);
var notificationManager = NotificationManagerCompat.From(Application.Context);
notificationManager.CancelAll();
notificationManager.Cancel(id);
}
i am sending customer id to cancel but its not working.
According to your description, you have xamarin.forms sample, sending Local Notification With A Repeat Interval using Alarm Manager, like this sample:
https://www.c-sharpcorner.com/article/how-to-send-local-notification-with-repeat-interval-in-xamarin-forms/
There are two solution, but I don't know what you are.
Solution 1:
When you run project and set one alarm Manager to send local notification with a repeat interval, this app is background now.
When time is up, you go into this background app, you find switch is unselect, but alarm still exist. So you want to cancel this alarm when you go into this app, am I right?
If yes, I suggest you can call Switch_Toggled() event in LocalNotificationPageViewModel constructor.
public LocalNotificationPageViewModel(){
SaveCommand = new Command(() => SaveLocalNotification());
Switch_Toggled();
}
Solution 2:
If you run project and set one alarm Manager to send local notification with a repeat interval, and this app still active, now time is up, you can unselect switch to cancel this alarm, it works fine.
Related
I'm using Dialogs and waterfallstep to organize the dialog logic, and
I want a HeroCard with CardActions as a welcome message. It works fine just sending a HeroCard as a welcome message, but my problem is to direct to the right dialog using turnContext when the user click on one of the options in the CardAction.
Here's my code in Bots.WelcomeBot.cs where I'm stuck. These two methods are after OnMembersAddedAsync which works fine.
private static async Task MainMenuAsync(ITurnContext turnContext, CancellationToken cancellationToken)
{
var card = new HeroCard
{
Text = "Welcome! What can I help you with?",
Buttons = new List<CardAction>
{
new CardAction() { Title = "Contact", Type = ActionTypes.ImBack, Value = "Contact" },
new CardAction() { Title = "Newsletter", Type = ActionTypes.ImBack, Value = "Newsletter" },
new CardAction() { Title = "Products", Type = ActionTypes.ImBack, Value = "Products" },
},
};
var reply = MessageFactory.Attachment(card.ToAttachment());
await turnContext.SendActivityAsync(reply, cancellationToken);
await MainMenuChoisesAsync(turnContext, reply, cancellationToken);
}
private static async Task MainMenuChoisesAsync(ITurnContext turnContext, IMessageActivity reply, CancellationToken cancellationToken) {
string choice = reply.ToString().ToLowerInvariant();
switch (choice) {
case "contact":
{
//Direct to ContactDialog.cs
}
}
}
Originally this menu of options are in my MainDialog which is triggered when the user has written anything in the start of the chat. The next waterfallstep then redirect to the right Dialog.
If you’re using WebChat or directline, the bot’s ConversationUpdate is sent when the conversation is created and the user sides’ ConversationUpdate is sent when they first send a message. When ConversationUpdate is initially sent, there isn’t enough information in the message to construct the dialog stack. The reason that this appears to work in the emulator, is that the emulator simulates a sort of pseudo DirectLine, but both conversationUpdates are resolved at the same time in the emulator, and this is not the case for how the actual service performs.
(source: How to properly send a greeting message and common issues from customers)
Currently it is not possible to use the conversationUpdate event for the scenario you describe. You can solve this by sending a custom event when the WebChat is fully loaded, however you can’t use the default iframe provided by the Bot Service.
Have a look at implementing the Web Chat v4.
Have a look at a sample which shows how to implement a welcome activity when the bot first starts:
WebChat v4 (recommended)
WebChat v3
I m using MediaRecorder to record video. while third-party screen recorder is running at time media recorder through illegal state exception.
Everything works as expected if I kill the screen recorder app. Is there an elegant solution to allow my app to access the MediaRecorder even if another app is already using it?
Only one app at a time can access the microphone.
while screen recorder app is running and can access Microphone at the time I have tried to record video using inbuild native camera but can't record video due to microphone busy with another app.
Also, there is no standard way to inform another app that you want access to the microphone (so that they release the resources and let you access it).I would recommend you to simply inform the user that the microphone is currently not available because you can't do anything else or we can record video without audio.
Using below code, I have recorded video without audio.
private boolean prepareVideoRecorder() {
mCamera = Camera.open(findBackFacingCamera());
mediaRecorder = new MediaRecorder();
// store the quality profile required
windowwidth = getWindowManager().getDefaultDisplay().getWidth();
CamcorderProfile profile;
if (windowwidth > 2000) {
profile= CamcorderProfile.get(camid, CamcorderProfile.QUALITY_HIGH);
} else {
profile= CamcorderProfile.get(camid, CamcorderProfile.QUALITY_480P);
}
// Step 1: Unlock and set camera to MediaRecorder
mCamera.unlock();
mediaRecorder.setCamera(mCamera);
// Step 2: Set sources value i.e. CAMERA,SURFACE, or DEFAULT
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 3: Set all other values contained in profile except audio settings
mediaRecorder.setOutputFormat(profile.fileFormat);
mediaRecorder.setVideoEncoder(profile.videoCodec);
mediaRecorder.setVideoEncodingBitRate(profile.videoBitRate);
mediaRecorder.setVideoFrameRate(profile.videoFrameRate);
mediaRecorder.setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);
// Step 4: Seting output file
// mediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());
File videoStorageDir = Const.getFileDirectory(MainActivity.this);
mediaRecorder.setOutputFile(videoStorageDir.getPath()+ File.separator + "/videofile.mp4");
// Step 5: Set the preview output
mediaRecorder.setPreviewDisplay(mvPreview.getHolder().getSurface());
mediaRecorder.setMaxDuration(42000); // for 40 second (you can set video recording limit here)
// Step 6: Prepare configured MediaRecorder
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
return false;
}
return true;
}
After getting app invite, invitee clicks on link.
Based on app already installed or not, he will be directed to app store and finally come to Actiity which handles AppInite link.
My deep link look like this:
http://example.com/app-invite/
Where user_id is id of registed user (in my backend server). I am able to get the correct id of the user.
This is the code for handling deep link.
private void processReferralIntent(Intent intent) {
String invitationId = AppInviteReferral.getInvitationId(intent);
String deepLink = AppInviteReferral.getDeepLink(intent);
String userId = deepLink.substring(deepLink.lastIndexOf("/") + 1);
Utility.displayToast("userid " + userId);
// Handle the deep link. For example, open the linked
// content, or apply promotional credit to the user's
// account.
Log.d(TAG, "Found Referral: " + invitationId + ":" + deepLink);
((TextView) findViewById(R.id.deep_link_text))
.setText(getString(R.string.deep_link_fmt, deepLink));
((TextView) findViewById(R.id.invitation_id_text))
.setText(getString(R.string.invitation_id_fmt, invitationId));
}
Now if this is the first time invitee is installing the app, on clicking on app invite link, i want to give some promotion credits to both invitee and inviter.
How can i know this is the first time? Beacuse even app is installed alredy processReferralIntent() will be called.
I have an activity indicator on xaml page. Initially its IsVisible property is false. I have a button on page. When user click on button it calls a web service to get data. I change the value of IsVisible property to true before calling the service so that activity indicator starts to display on page and after successful calling of service I change its value to again false so that it doesn't show any more on page.
But it is not working. I know the actual problem. When we call the web service the UI thread gets block and it doesn't show the activity indicator.
How I can enable the UI thread when web service gets called so that activity indicator can show on page until we get the data?
Try making your webservice call into an async and await it.
Depending on how you've structured things you may have to use a TaskCompletionSource as the following example demonstrates.
In this example when the button is clicked, the button is made invisible, and the ActivityIndicator is set to IsRunning=True to show it.
It then executes your long running task / webservice in the function ExecuteSomeLongTask using a TaskCompletionSource.
The reason for this is that in our button click code, we have the final lines:-
objActivityIndicator1.IsRunning = false;
objButton1.IsVisible = true;
That stop the ActivityIndicator from running and showing, and also set the button back to a visible state.
If we did not use a TaskCompletionSource these lines would execute immediately after calling the ExecuteSomeLongTask if it was a normal async method / function, and would result in the ActivityIndicator not running and the button still being visible.
Example:-
Grid objGrid = new Grid()
{
};
ActivityIndicator objActivityIndicator1 = new ActivityIndicator();
objGrid.Children.Add(objActivityIndicator1);
Button objButton1 = new Button();
objButton1.Text = "Execute webservice call.";
objButton1.Clicked += (async (o2, e2) =>
{
objButton1.IsVisible = false;
objActivityIndicator1.IsRunning = true;
//
bool blnResult = await ExecuteSomeLongTask();
//
objActivityIndicator1.IsRunning = false;
objButton1.IsVisible = true;
});
objGrid.Children.Add(objButton1);
return objGrid;
Supporting function:-
private Task<bool> ExecuteSomeLongTask()
{
TaskCompletionSource<bool> objTaskCompletionSource1 = new TaskCompletionSource<bool>();
//
Xamarin.Forms.Device.StartTimer(new TimeSpan(0, 0, 5), new Func<bool>(() =>
{
objTaskCompletionSource1.SetResult(true);
//
return false;
}));
//
return objTaskCompletionSource1.Task;
}
You need to do your work in an asynchronous way. Or in other words: Use Asnyc & Await to ensure, that you UI works well during the call.
You can find more informations in the Xamarin Docs.
async and await are new C# language features that work in conjunction
with the Task Parallel Library to make it easy to write threaded code
to perform long-running tasks without blocking the main thread of your
application.
If you need further asistance, please update your question and post your code or what you have tried so far.
We are trying to load and resume workflows which have a delay. I have seen the Microsoft sample of Absolute Delay for this using store.WaitForEvents and LoadRunnableInstance to load the workflow. However here the workflow is already known.
In our case we want to have an event waiting for the store.WaitForEvents after every say 5 seconds to check if there is a runnable instance and if so only load and run that /those particular instances. Is there a way I could know which workflow instance is ready.
We are maintaing the workflow id and the xaml associated to it in our database, so if we could know the workflow instance id we could get the xaml mapped to it, create the workflow and then do a LOadRunnableInstance on it.
Any help would be greatly appreciated.
Microsoft sample (Absolute Delay)
public void Run(){
wfHostTypeName = XName.Get("Version" + Guid.NewGuid().ToString(),
typeof(WorkflowWithDelay).FullName);
this.instanceStore = SetupSqlpersistenceStore();
this.instanceHandle =
CreateInstanceStoreOwnerHandle(instanceStore, wfHostTypeName);
WorkflowApplication wfApp = CreateWorkflowApp();
wfApp.Run();
while (true)
{
this.waitHandler.WaitOne();
if (completed)
{
break;
}
WaitForRunnableInstance(this.instanceHandle);
wfApp = CreateWorkflowApp();
try
{
wfApp.LoadRunnableInstance();
waitHandler.Reset();
wfApp.Run();
}
catch (InstanceNotReadyException)
{
Console.WriteLine("Handled expected InstanceNotReadyException, retrying...");
}
}
Console.WriteLine("workflow completed.");
}
public void WaitForRunnableInstance(InstanceHandle handle)
{
var events=instanceStore.WaitForEvents(handle, TimeSpan.MaxValue);
bool foundRunnable = false;
foreach (var persistenceEvent in events)
{
if (persistenceEvent.Equals(HasRunnableWorkflowEvent.Value))
{
foundRunnable = true;
break;
}
}
if (!foundRunnable) {
Console.WriteLine("no runnable instance");
}
}
Thanks
Anamika
I had a similar problem with durable delay activities and WorkflowApplicationHost. Ended up creating my own 'Delay' activity that worked essentially the same way as the one out of the box, (takes an arg that describes when to resume the workflow, and then bookmarks itself). Instead of saving delay info in the SqlInstanceStore though, my Delay Activity created a record in a seperate db. (similar to the one you are using to track the Workflow Ids and Xaml). I then wrote a simple service that polled that DB for expired delays and initiated a resume of the necessary workflow.
Oh, and the Delay activity deleted it's record from that DB on bookmark resume.
HTH
I'd suggest having a separate SqlPersistenceStore for each workflow definition you're hosting.