Enable speaker during Linphone call in Xamarin forms - xamarin

I was trying to enable speaker for my VoIP call using Linphone in Xamarin forms. I'm using the following code
public void PlayUsingEarSpeaker()
{
AudioManager mAudioManager = (AudioManager)Android.App.Application.Context.GetSystemService(Context.AudioService);
mAudioManager.Mode = Mode.InCall;
mAudioManager.SpeakerphoneOn = true;
mAudioManager.SetStreamVolume(Stream.VoiceCall, mAudioManager.GetStreamMaxVolume(Stream.VoiceCall), VolumeNotificationFlags.ShowUi);
}
I have also added the permission for modifying the audio settings.
protected override void OnResume()
{
base.OnResume();
//RegisterReceiver(receiver, new IntentFilter("org.linphone.core.action.PUSH_RECEIVED"));
System.Console.WriteLine("MyBroadcastReceiver registered");
if (Int32.Parse(global::Android.OS.Build.VERSION.Sdk) >= 23)
{
List<string> Permissions = new List<string>();
if (this.CheckSelfPermission(Manifest.Permission.Camera) != Permission.Granted)
{
Permissions.Add(Manifest.Permission.Camera);
}
if (this.CheckSelfPermission(Manifest.Permission.RecordAudio) != Permission.Granted)
{
Permissions.Add(Manifest.Permission.RecordAudio);
}
if (this.CheckSelfPermission(Manifest.Permission.ModifyAudioSettings) != Permission.Granted)
{
Permissions.Add(Manifest.Permission.ModifyAudioSettings);
}
if (Permissions.Count > 0)
{
this.RequestPermissions(Permissions.ToArray(), PERMISSIONS_REQUEST);
}
}
and in Android Manifest
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
I even tried to set the stream type to music but still my audio doesn't come from the phone speaker. I have no clue how to fix this. Any suggestions?

Related

Xamarin enabled GPS android / IOS

Good afternoon,
How do I turn on GPS in android and IOS project after giving consent?
The consent code works seamlessly:
public MainPage()
{
InitializeComponent();
CrossConnectivity.Current.ConnectivityChanged += Current_ConnectivityChanged;
CheckPermissions();
}
private async void CheckPermissions()
{
var status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
if(status == PermissionStatus.Granted)
{
return;
}
else
{
await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
}
}
How do I turn on the GPS automatically after giving consent?

Custom renderer for LibVLCSharp VideoView in Mac and UWP (Xamarin.Forms)

I'm trying to use VideoView from LibVLCSharp for Mac to create a custom renderer in Xamarin.Forms to play a video in Xamarin.Forms mac application. So far I only get audio but no video.
this is my VideoPlayerRenderer for mac implementation
[assembly: ExportRenderer(typeof(Player.VideoPlayer), typeof(Player.Mac.VideoPlayerRenderer))]
namespace Player.Mac {
public class VideoPlayerRenderer : ViewRenderer<VideoPlayer, LibVLCSharp.Platforms.Mac.VideoView> {
LibVLCSharp.Platforms.Mac.VideoView video_view;
public VideoPlayerRenderer() {
}
protected override void OnElementChanged (ElementChangedEventArgs<VideoPlayer> e) {
base.OnElementChanged (e);
if(e.OldElement != null) {
}
if(e.NewElement != null) {
if(Control == null) {
video_view = new LibVLCSharp.Platforms.Mac.VideoView();
video_view.MediaPlayer = e.NewElement.get_media_player();
SetNativeControl(video_view);
}
}
}
}
}
and the VideoPlayer Xamarin.Forms View
public class VideoPlayer : View {
LibVLC lib_vlc;
MediaPlayer media_player;
public VideoPlayer() {
}
public void init(LibVLC lib_vlc, MediaPlayer media_player) {
this.lib_vlc = lib_vlc;
this.media_player = media_player;
}
public void play() {
this.media_player.Play();
}
public MediaPlayer get_media_player() {
return this.media_player;
}
}
I've tried the same method on UWP and there i get no audio nor video. So i'm wondering if this is going in the wrong direction, and if so, how are you supposed to go about using LibVLCSharp for mac/uwp?
You don't have to create your own renderer since there is already one.
From the LibVLCSharp.Forms documentation :
This package also contains the views for the following platforms:
Android
iOS
Mac
The UWP support for Xamarin.Forms currently has blockers that we expect to get solved by the LVS 4/ libvlc 4 release. See this issue for a detailed explanation.

Xamarin Essentials Permissions failing to grant permission

I'm currently writing a Xamarin Forms app which requires use of the camera, in the code below I am requesting the permission using the Xamarin Essentials Permissions which comes back as "Granted"; immediately following that I am requesting use of the camera to take a photo, which throws the following error.
ex = {Plugin.Media.Abstractions.MediaPermissionException: Camera permission(s) are required.
The permission code
public static async Task<bool> GetPermission<TPermission>() where TPermission : BasePermission, new()
{
var hasPermission = await Permissions.CheckStatusAsync<TPermission>();
if (hasPermission == PermissionStatus.Granted)
return true;
else if (hasPermission == PermissionStatus.Disabled)
return false;
var result = await Permissions.RequestAsync<TPermission>();
if (result != PermissionStatus.Granted)
return false;
return true;
}
The photo manager code
if(!await PermissionHelpers.GetPermission<Permissions.Camera>())
{
await new ErrorAlert().Show("App can't take a picture without permission to use the camera");
return string.Empty;
}
var photo = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
PhotoSize = PhotoSize.Small,
SaveToAlbum = false
});
As previously said, the GetPermission method returns true, but still the error is thrown.
I'm currently running this on Android.
My AndroidManifest.xml has these permission in it.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
I have now made a sample project to showcase my issue
GitHub Repo for the issue
don't forget
Android
protected override void OnCreate(Bundle savedInstanceState) {
//...
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState); // add this line to your code, it may also be called: bundle
//...
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
Documentation
First of all, I notice you use Xam.Plugin.Media, this plugin need WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE and android.permission.CAMERA in Android, You should request these permission at runtime.
You can use following code in the MainActivity
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.Camera) != (int)Permission.Granted)
{
RequestPermissions(new string[] { Manifest.Permission.Camera, Manifest.Permission.WriteExternalStorage, Manifest.Permission.ReadExternalStorage }, 0);
}
}
Here is running gif.
Update
If you use this CrossMedia, you need grant Storage and Camera permission.Please open your PhotoManager.cs Add the request storage code like following code.
public class PhotoManager
{
public async Task<string> TakeNewPhoto()
{
try
{
if (!CrossMedia.IsSupported || !CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
return string.Empty;
}
if (!await PermissionHelpers.GetPermission<Permissions.Camera>())
{
return string.Empty;
}
//=====================================add above line==================================================
if (!await PermissionHelpers.GetPermission<Permissions.StorageWrite>())
{
return string.Empty;
}
var photo = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
PhotoSize = PhotoSize.Small,
SaveToAlbum = false
});
if (photo != null)
{
return "photo taken successfully";
}
return string.Empty;
}
catch (Exception ex)
{
return ex.Message;
}
}
}
Here is your issueProjects' running GIF.
thank you for all of your time gone into helping me to resolve this issue.
It turned out that if you are using Xamarin essentials version 1.5.0 you need to install the CurrentActivity NuGet plugin to your android project.
Or, a better solution is update to 1.5.1 which resolves the issue entirely.
You must add permissions for camera to your Android Manifest file!
In Visual Studio right click your android project.
Go to Options -> Build -> Android Application and tick the box in required permissions that says camera.
NB: If you are going to be recording you may also want to enable microphone and audio permissions.
You must also add:
<uses-feature android:name="android.hardware.camera" />
To your android manifest.

How to send OnActivityResult To a specific page in xamarin forms

I am using a custom button renderer for google sign In in xamarin forms page its working fine I get the signin resultin MainActivity Now i want to send this data from MainActivity and AppDelegate to the Particular page in Xamarin Forms.
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (requestCode == 9001)
{
Utilities.Configuration.UpdateConfigValue(Utilities.Constants.loggedInflag,string.Empty);
GoogleSignInResult result = Android.Gms.Auth.Api.Auth.GoogleSignInApi.GetSignInResultFromIntent(data);
if (result.IsSuccess)
{
GoogleSignInAccount acct = result.SignInAccount;
var token = acct.IdToken;
//I wan to send the 'accnt' to a Page in xamarin forms
}
else
{
//Signin Failure send response to Page in xamarin forms
}
}
}
Xamarin.Forms runs only in one Activity on Android. So if your url request comes out in a different Activity, you have to switch back to the MainActivity before you can use the normal XF navigation.
I do this when a user opens a file associated with my app.
[Activity(Label = "LaunchFileActivity")]
public class LaunchFileActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
if (Intent.Data != null)
{
var uri = Intent.Data;
if (uri != null)
{
Intent i = new Intent(this, typeof(MainActivity));
i.AddFlags(ActivityFlags.ReorderToFront);
i.PutExtra("fileName", uri.Path);
this.StartActivity(i);
}
}
this.FinishActivity(0);
}
}
And in MainActivity:
protected override void OnNewIntent(Intent intent)
{
base.OnNewIntent(intent);
Intent = intent;
}
protected override void OnPostResume()
{
base.OnPostResume();
if (Intent.Extras != null)
{
string fileName = Intent.Extras.GetString("fileName");
if (!string.IsNullOrEmpty(fileName))
{
// do something with fileName
}
Intent.RemoveExtra("fileName");
}
}
Xamarin forms runs on one activity, which is most like your main activity.
There are two sample projects that show you how to communicate between native and form parts of the code, which can be found here
https://github.com/xamarin/xamarin-forms-samples/tree/master/Forms2Native
https://github.com/xamarin/xamarin-forms-samples/tree/master/Native2Forms
However, to answer your question, you would do something like the following
private const int MyRequestCode = 101;
//Start activity for result
var contactPickerIntent = new Intent(Intent.ActionPick, Android.Provider.ContactsContract.Contacts.ContentUri);
context.StartActivityForResult(contactPickerIntent, MyRequestCode);
and then in your main activity (the activity that initializes your xamarin forms application (using global::Xamarin.Forms.Forms.Init(this, bundle);)
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
if (requestCode == MyRequestCode && resultCode == Result.Ok)
{
}
}

Problems accessing SkyDrive from Windows Phone 7

We are using the Live Connect SDK 5.0 to retrieve pictures from SkyDrive from our Windows Phone 7.5 application.
The application code (simplified) below used to work until a few days ago. Now when we try to access the imageStream (or any other information captured in a callback) we get a System.Argument exception (HResult = -2147024809, "Value does not fall within the expected range", but as usual the offending value is not mentioned). We checked our code base and there were no code changes in this area of the product recently.
Were there any API changes? Is there a way (Fiddler, but for applications not IE) to inspect the network traffic in the hope that more information is transmitted from the server? Are there any local values that are being cached that might interfere?
Here's the relevant code:
public partial class OptionsPage : PhoneApplicationPage
{
private LiveConnectClient _liveClient = null;
public OptionsPage()
{
InitializeComponent();
}
private void OnSessionChanged(Object sender, LiveConnectSessionChangedEventArgs args)
{
if (args != null && args.Session != null && args.Session.Status == LiveConnectSessionStatus.Connected)
{
this._liveClient = new LiveConnectClient(args.Session);
this.GetUserPicture();
}
}
private void GetUserPicture()
{
var memoryStream = new MemoryStream();
_liveClient.DownloadCompleted += new EventHandler<LiveOperationCompletedEventArgs>(this.GetUserPictureCallback);
_liveClient.DownloadAsync("/me/picture?return_ssl_resources=true", memoryStream, memoryStream);
}
private void GetUserPictureCallback(object sender, LiveOperationCompletedEventArgs e)
{
_liveClient.DownloadCompleted -= this.GetUserPictureCallback;
try
{
if (e.Error == null)
{
MemoryStream imageStream = e.UserState as MemoryStream;
BitmapImage b = new BitmapImage();
b.SetSource(imageStream);
}
else
{
MessageBox.Show(e.Error.Message, "Windows Live Error", MessageBoxButton.OK);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "SkyDrive Exception", MessageBoxButton.OK);
}
}
}
And the SignInButton is defined as follows:
<live:SignInButton Content="Button" Height="65" HorizontalAlignment="Left" Margin="110,41,0,0"
Name="signInButton1" VerticalAlignment="Top" Width="215" ClientId="[REAL_CLIENT_ID]"
Scopes="wl.offline_access wl.signin wl.basic wl.skydrive wl.skydrive_update"
RedirectUri="https://oauth.live.com/desktop"
Branding="Skydrive"
TextType="SignIn"
Background="Red"
SessionChanged="OnSessionChanged" />
It appears that I was using the Beta version of the Live Connect SDK 5.0. Once I upgraded to the RTM version (and made the code changes required) it started working again.

Resources