Im trying to create project with Bluetooth connection. But when i'm trying to select item in list there are no message: "Do you want to connect to this device?"
enter image description here
I manually added the BMW X5 device, but when I click on it, no windows with messages appear
It it my DevicesList_OnItemSelected event:
private async void DevicesList_OnItemSelected(object sender, SelectedItemChangedEventArgs e)
{
if (DevicesList.SelectedItem == null)
{
await DisplayAlert("Error", "Please select a device from the list first.", "OK");
return;
}
CurDevice = DevicesList.SelectedItem as IDevice;
if (CurDevice != null)
{
if (CurDevice.State == DeviceState.Disconnected)
{
var result = await DisplayAlert("Message", "Do you want to connect to this device?", "Connect", "Cancel");
if (result)
{
try
{
await Adapter.ConnectToDeviceAsync(CurDevice);
await DisplayAlert("Message", "Connected to device with Id: " + CurDevice.Id, "OK");
}
catch (DeviceConnectionException ex)
{
await DisplayAlert("Error", ex.Message, "OK");
}
}
}
else
{
await DisplayAlert("Error", "Device is already connected or being connected", "OK");
}
}
}
`
Related
We are using bot-framework version 4.x
"botbuilder": "4.11.0",
"botbuilder-ai": "4.11.0",
"botbuilder-applicationinsights": "4.11.0",
"botbuilder-azure": "4.11.0",
"botbuilder-dialogs": "4.11.0",
"botbuilder-lg": "4.11.0",
"botbuilder-testing": "4.11.0",
"botframework-config": "4.11.0",
"botframework-connector": "4.11.0"
Case
We need to start a Dialog in Virtual Assistant and cancel any ongoing Skill dialog (If any)
Example
LiveChat - part of Virtual Assistant
CreateIncidentDialog - part of skill
Suppose we are in the middle of CreateIncidentDialog and the user wants to start LiveChat. We are supposed to start LiveChat and cancel current CreateIncidentDialog.
Sample Code
MainDialog.ts in Virtual Assistant
If current Dialog is a part of skill, we are starting a dialog with activity.type as EVENT for skill.
switch (gIntent) {
case 'Escalate': {
// Checking if current Dialog is a part of Skill
if (isSkill) {
const activity: Activity = innerDc.context.activity;
if ((activity.value === null || activity.value === undefined)) {
activity.value = { userState: userProfile };
};
activity.type = ActivityTypes.Event;
activity.name = "liveChat";
const skillDialogArgs: BeginSkillDialogOptions = {
activity: activity as Activity
};
await innerDc.beginDialog(EvaConfig.LUIS_DEFAULT_INTENT, skillDialogArgs);
} else {
await innerDc.cancelAllDialogs();
}
// code for starting LiveChat goes here
// .....
// .....
// .....
}
MainDialog.ts in Skill
If activity.type is EVENT and name is 'liveChat', cancel dialogs.
protected async onContinueDialog(innerDc: DialogContext): Promise<DialogTurnResult> {
try {
let activity = innerDc.context.activity;
if (innerDc.context.activity.type === ActivityTypes.Message) {
// .....
// .....
// .....
} else if (activity.type === ActivityTypes.Event) {
const ev = activity;
if (ev.name !== undefined && ev.name.trim().length > 0) {
switch (ev.name) {
case 'liveChat': {
await innerDc.cancelAllDialogs(true);
return await innerDc.endDialog();
}
}
}
}
return await super.onContinueDialog(innerDc);
} catch (e) {
console.log(`Error onContinueDialog ---> ${e} `);
return await this.hanldeException(innerDc);
}
}
Issue
The above code is not able to cancel the skill's dialog correctly. If we try to start a new dialog after the cancellation of skill dialog, it again sends an activity with activity.type as EVENT to routeStep method of MainDilaog.ts in Skill. Please find the sample code below for the same.
routeStep method of MainDialog.ts in Skill
protected async routeStep(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {
console.log('skill routeStep');
if (activity.type === ActivityTypes.Message && activity.text !== undefined && activity.text.trim().length > 0) {
// .....
// .....
// .....
} else if (activity.type === ActivityTypes.Event) {
const ev = activity;
if (ev.name !== undefined && ev.name.trim().length > 0) {
switch (ev.name) {
case 'SampleAction': {
// .....
// .....
// .....
}
}
} else {
// If we try to start a new dialog, control comes here
await stepContext.context.sendActivity({
type: ActivityTypes.Trace,
text: 'An event with no name was received but not processed.'
});
}
}
} else {
await this.responder.replyWith(stepContext.context, MainResponses.responseIds.dontHavePermissionServiceNow);
await this.complete(stepContext);
}
return await stepContext.next();
}
Step to Reproduce
Step 1. Start a Dialog in Skill
Step 2. End the Dialog in the Skill and start a Dialog in VA
Step 3. Start a new Dialog
Thanks.
Edward
I want to set the background color of an image when take an image from the gallery because if i take transparency image it set automatically black background behind image.
But if i keep transparency image in Resources-->drawable folder then it show
given red background
<Grid Grid.Column="1" BackgroundColor=">
<Image x:Name="RestaurantImage" Source="trans.png" BackgroundColor="Red"/>
</Grid
This is my take image code :
private async void ImageTapped(object sender, EventArgs e)
{
string action = await UserDialogs.Instance.ActionSheetAsync("PickPhoto", "Cancel", null, null, "Take Photo", "Pick From Gallery");
MediaFile file = null;
if (action == "Take Photo")
{
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
UserDialogs.Instance.Alert("No Camera", ":( No camera avaialble.", "OK");
return;
}
file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Medium,
Directory = "Sample",
Name = "test.png"
});
}
else if (action == "Pick From Gallery")
{
if (!CrossMedia.Current.IsPickPhotoSupported)
{
UserDialogs.Instance.Alert("PhotosNotSupported", "PermissionNotGrantedToPhotos.", "OK");
return;
}
else
{
file = await CrossMedia.Current.PickPhotoAsync(new PickMediaOptions
{
PhotoSize = PhotoSize.Medium
});
}
}
else
{
return;
}
if (file == null)
return;
Stream s = file.GetStream();
RestaurantImage.Source = ImageSource.FromStream(() =>
{
file.Dispose();
return s;
});
}
You can see if the effect is what you want
1.create a CustomImage.cs :
public class CustomImage:Image
{
}
2.create a CustomImageRenderer in Droid project:
[assembly: ExportRenderer(typeof(CustomImage), typeof(CustomImageRenderer))]
namespace App18.Droid
{
class CustomImageRenderer:ImageRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
{
base.OnElementChanged(e);
if (Control != null)
{
ImageView image = Control as ImageView;
image.SetColorFilter(Android.Graphics.Color.Red, Android.Graphics.PorterDuff.Mode.DstOver);
}
}
}
}
finally use CustomImage load image
#saamer and #leo thanks for help me :)
I resolved my issue "set background color when take transparency image from gallery", when i used PhotoSize = PhotoSize.Medium then it's set black background behind transparent image but if i used PhotoSize = PhotoSize.Full it's set transparency background behind transparent image.
this is my get image from gallery code :
private async void ImageTapped(object sender, EventArgs e)
{
string action = await UserDialogs.Instance.ActionSheetAsync("PickPhoto", "Cancel", null, null, "Take Photo", "Pick From Gallery");
MediaFile file = null;
if (action == "Take Photo")
{
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
UserDialogs.Instance.Alert("No Camera", ":( No camera avaialble.", "OK");
return;
}
file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Medium,
Directory = "Sample",
Name = "test.png"
});
}
else if (action == "Pick From Gallery")
{
if (!CrossMedia.Current.IsPickPhotoSupported)
{
UserDialogs.Instance.Alert("PhotosNotSupported", "PermissionNotGrantedToPhotos.", "OK");
return;
}
else
{
file = await CrossMedia.Current.PickPhotoAsync(new PickMediaOptions
{
PhotoSize = PhotoSize.Full
});
}
}
else
{
return;
}
if (file == null)
return;
Stream s = file.GetStream();
s.Position = 0;
RestaurantImage.Source = ImageSource.FromStream(() =>
{
file.Dispose();
return s;
});
}
first time application asking permission for the camera, if we deny the permission it won't ask again if we allow its working fine ??
var scanPage = new ZXingScannerPage();
var cameraStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Camera);
if (cameraStatus != PermissionStatus.Granted)
{
var results = await CrossPermissions.Current.RequestPermissionsAsync(new[] { Permission.Camera });
cameraStatus = results[Permission.Camera];
if (cameraStatus == PermissionStatus.Granted)
{
// Navigate to our scanner page
await Navigation.PushAsync(scanPage);
scanPage.OnScanResult += (result) =>
{
Device.BeginInvokeOnMainThread(async () =>
{
await Navigation.PopAsync();
txtbarcode.Text = result.Text;
});
};
}
else if (cameraStatus == PermissionStatus.Unknown)
{
await Navigation.PushAsync(scanPage);
scanPage.OnScanResult += (result) =>
{
Device.BeginInvokeOnMainThread(async () =>
{
await Navigation.PopAsync();
txtbarcode.Text = result.Text;
});
};
}
If we deny the camera permission, again its asks while opening camera until we allow the permission.
I wrote a demo about this.
https://github.com/851265601/CheckPermissionDemo
This a GIF of this demo.
Did you check the permission every time when you use the camera function? In this demo, when i click the button ,it will check the permission, then give the result to users, if not give the permission, it will still ask the persmission like the following code.
async void ButtonPermission_OnClicked(object sender, EventArgs e)
{
if (busy)
return;
busy = true;
((Button)sender).IsEnabled = false;
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Camera);
await DisplayAlert("Pre - Results", status.ToString(), "OK");
if (status != PermissionStatus.Granted)
{
status = await Utils.CheckPermissions(Permission.Camera);
await DisplayAlert("Results", status.ToString(), "OK");
}
busy = false;
((Button)sender).IsEnabled = true;
}
}
When DisplayAlert was appear, it are used MainApplication for different life cycle
namespace CheckPermissionDemo.Droid
{
//You can specify additional application information in this attribute
[Application]
public class MainApplication : Application, Application.IActivityLifecycleCallbacks
{
public MainApplication(IntPtr handle, JniHandleOwnership transer)
: base(handle, transer)
{
}
public override void OnCreate()
{
base.OnCreate();
RegisterActivityLifecycleCallbacks(this);
//A great place to initialize Xamarin.Insights and Dependency Services!
}
public override void OnTerminate()
{
base.OnTerminate();
UnregisterActivityLifecycleCallbacks(this);
}
public void OnActivityCreated(Activity activity, Bundle savedInstanceState)
{
CrossCurrentActivity.Current.Activity = activity;
}
public void OnActivityDestroyed(Activity activity)
{
}
public void OnActivityPaused(Activity activity)
{
}
public void OnActivityResumed(Activity activity)
{
CrossCurrentActivity.Current.Activity = activity;
}
public void OnActivitySaveInstanceState(Activity activity, Bundle outState)
{
}
public void OnActivityStarted(Activity activity)
{
CrossCurrentActivity.Current.Activity = activity;
}
public void OnActivityStopped(Activity activity)
{
}
}
}
I'm trying to implement error trapping functionality from the view model to the view controler, so if there is an error, a message is displayed.
Here is the code i'm using:
ItemsPage View Model
async Task ExecuteCommand()
{
...
try
{
}
catch (Exception ex)
{
Debug.WriteLine(ex);
MessagingCenter.Send(new MessagingCenterAlert
{
Title = "Error",
Message = "Unable to load services.",
Cancel = "OK"
}, "message");
}
finally
{
IsBusy = false;
}
ItemsPage.XAML.cs File
In the constructor for the page..
...
public ItemsPage()
{
InitializeComponent();
MessagingCenter.Subscribe<ItemsViewModel, MessagingCenterAlert>
(this, "message", (sender, arg) => {
var argu = arg;
DisplayAlert("Problem","message body" + argu.Message, "OK");
});
Not sure if this is the correct way to do this, but it is not displaying the alert if there is an error.
Try wrapping it in a call to Device.BeginInvokeOnMainThread like:
MessagingCenter.Subscribe<ItemsViewModel, MessagingCenterAlert>
(this, "message", (sender, arg) => {
var argu = arg;
Device.BeginInvokeOnMainThread (() => {
DisplayAlert("Problem","message body" + argu.Message, "OK");
});
});
I am stuck at one point in Xamarin.Forms application
On Back button press simply I want to ask user to confirm whether he really wants to exit or not,
"OnBackButtonPressed" I want to show Alert dialog and proceed as user response.
But "OnBackButtonPressed" is not Async I cannot write await DisplayAlert...
Please direct me how should i implement this feature?
I am using ContentPage as my root Page of NavigationPage
public class frmHome : ContentPage
Here is the code :
protected override bool OnBackButtonPressed()
{
var result = await this.DisplayAlert("Alert!", "Do you really want to exit?", "Yes", "No");
if (result)
{
//user wants to exit
//Terminate application
}
else
{
//Dont do anything
}
}
protected override bool OnBackButtonPressed()
{
Device.BeginInvokeOnMainThread(async() => {
var result = await this.DisplayAlert("Alert!", "Do you really want to exit?", "Yes", "No");
if (result) await this.Navigation.PopAsync(); // or anything else
});
return true;
}
Here's the code that worked for me
protected override bool OnBackButtonPressed()
{
Device.BeginInvokeOnMainThread(async () =>
{
var result = await this.DisplayAlert("Alert!", "Do you really want to exit?", "Yes", "No");
if (result)
{
System.Diagnostics.Process.GetCurrentProcess().CloseMainWindow(); // Or anything else
}
});
return true;
}
Easy way to override hardware back button and show a confirmation dialog box to user
protected override bool OnBackButtonPressed()
{
Device.BeginInvokeOnMainThread(async () =>
{
if (await DisplayAlert("Alert", "Are you sure you want to go back ?", "Yes", "No"))
{
base.OnBackButtonPressed();
await Navigation.PopAsync();
}
});
return true;
}
If you are on Mainpage and want to exit your app then this code will help you.
In your UI (PCL)
protected override bool OnBackButtonPressed()
{
Device.BeginInvokeOnMainThread(new Action(async () => {
var result = await this.DisplayAlert("Alert!", "Do you really want to exit?", "Yes", "No");
if (result)
{
if (Device.RuntimePlatform == Device.Android)
DependencyService.Get<IAndroidMethods>().CloseApp();
}
}));
return true;
}
Also create an Interface (in your UI PCL):
public interface IAndroidMethods
{
void CloseApp();
}
Now implement the Android-specific logic in your Android project:
[assembly: Xamarin.Forms.Dependency(typeof(AndroidMethods))]
namespace Your.Namespace
{
public class AndroidMethods : IAndroidMethods
{
public void CloseApp()
{
var activity = (Activity)Forms.Context;
activity.FinishAffinity();
}
}
}
public override void OnBackPressed()
{
RunOnUiThread(
async () =>
{
var isCloseApp = await AlertAsync(this, "NameOfApp", "Do you want to close this app?", "Yes", "No");
if (isCloseApp)
{
var activity = (Activity)Forms.Context;
activity.FinishAffinity();
}
});
}
public Task<bool> AlertAsync(Context context, string title, string message, string positiveButton, string negativeButton)
{
var tcs = new TaskCompletionSource<bool>();
using (var db = new AlertDialog.Builder(context))
{
db.SetTitle(title);
db.SetMessage(message);
db.SetPositiveButton(positiveButton, (sender, args) => { tcs.TrySetResult(true); });
db.SetNegativeButton(negativeButton, (sender, args) => { tcs.TrySetResult(false); });
db.Show();
}
return tcs.Task;
}
Xamarin.Android await AlertDialog.Builder
I am done like this
protected override bool OnBackButtonPressed()
{
var result = await this.DisplayAlert("Alert!", "Do you really want to exit?", "Yes", "No");
if (result)
{
Process.GetCurrentProcess().CloseMainWindow();
Process.GetCurrentProcess().Close();
}
else
{
//Dont do anything
}
}
private async void OnDelete(object sender, EventArgs e)
{
var result = await this.DisplayAlert("Alert!", "Do you really want to exit?", "Yes", "No");
if (result)
{
var menuitem = sender as MenuItem;
string name = menuitem.BindingContext as string;
lielements.Remove(name);
}
else
{
}
}