I'm working on a Xamarin.Form App (Android and iOs) which need to get AAID and IDFA.
I started with Android part, I implemented AdvertisingIdClient.GetAdvertisingIdInfo but this function return Timeout error (about after 10s)
I use DependencyService from Form to get AAID from Android project and I compile with Android 11.0
I followed internet examples to achieve it but I'm quite sure I missed something or did something wrong, but what?
What I did :
Added nuget Xamarin.GooglePlayServices.Ads (120.3.0.3) and Xamarin.GooglePlayServices.Basement (117.6.0.4), should be latest compliant with Android 11
Created Interface for dependency service and Created cs in Android project
In Form I call my Dependencyservice function using Task.Run to run i in background (not sure it's the rigth way, but function run, otherwise function raise an error)
IDeviceAdIdentifier service = DependencyService.Get<IDeviceAdIdentifier>();
var tadid = Task.Run(() =>
{
var t = service.GetAdvertisingIdentifier();
t.Wait();
return t.Result;
});
tadid.Wait();
Idfa = tadid.Result;
In Android I save Context from MainActivity
In Android Service I have :
[assembly: Dependency(typeof(TestAdId.Droid.Services.DeviceAdIdentifier))]
namespace TestAdId.Droid.Services
{
public class DeviceAdIdentifier : TestAdId.Services.IDeviceAdIdentifier
{
public async Task<string> GetAdvertisingIdentifier()
{
if (MainActivity.Context == null) return "";
string id = "";
try
{
AdvertisingIdClient.SetShouldSkipGmsCoreVersionCheck(true);
var adinfo = AdvertisingIdClient.GetAdvertisingIdInfo(MainActivity.Instance); // Also tested with MainActivity.Context which is Application context saved during init
if (adinfo != null)
return adinfo.Id;
}
catch (IOException ioerr)
{
return ioerr.Message;
}
catch (Exception err)
{
return err.Message;
}
return "";
}
}
}
In my manifest :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.testadid" android:installLocation="auto">
<uses-sdk android:minSdkVersion="25" android:targetSdkVersion="30" />
<application android:label="TestAdId.Android" android:theme="#style/MainTheme" android:icon="#drawable/xamarin_logo">
<meta-data android:name="com.google.android.gms.ads.AD_MANAGER_APP" android:value="true" />
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
The error raised on my Samsung Galaxy A71 is :
Message : java.util.concurrent.TimeoutException: Timed out waiting for the service connection
StackTrace :
at Java.Interop.JniPeerMembers+JniStaticMethods.InvokeObjectMethod (System.String encodedMember, Java.Interop.JniArgumentValue* parameters) [0x00018] in <1921523bc22e407fa9a0855bdae29335>:0
at Google.Ads.Identifier.AdvertisingIdClient.GetAdvertisingIdInfo (Android.Content.Context context) [0x00027] in /Users/runner/work/1/s/generated/com.google.android.gms.play-services-ads-identifier/obj/Release/monoandroid90/generated/src/Google.Ads.Identifier.AdvertisingIdClient.cs:171
at TestAdId.Droid.Services.DeviceAdIdentifier.GetAdvertisingIdentifier () [0x00032] in C:\Working\Digital\Sources\TestAdId\TestAdId\TestAdId.Android\Services\DeviceAdIdentifier.cs:30
--- End of managed Java.IO.IOException stack trace ---
java.io.IOException: java.util.concurrent.TimeoutException: Timed out waiting for the service connection
at com.google.android.gms.ads.identifier.AdvertisingIdClient.zzb(com.google.android.gms:play-services-ads-identifier##17.0.1:16)
at com.google.android.gms.ads.identifier.AdvertisingIdClient.getAdvertisingIdInfo(com.google.android.gms:play-services-ads-identifier##17.0.1:3)
Caused by: java.util.concurrent.TimeoutException: Timed out waiting for the service connection
at com.google.android.gms.common.BlockingServiceConnection.getServiceWithTimeout(com.google.android.gms:play-services-basement##17.6.0:4)
at com.google.android.gms.ads.identifier.AdvertisingIdClient.zzb(com.google.android.gms:play-services-ads-identifier##17.0.1:14)
... 1 more
I tested an application to retrieve AAID and it works on my phone.
So if someone can help me it will be great. Tell me if you need more information/code
Thanks
Hervé
It's just a POC so nothing really special in MainActivity. I created a standard xamarin.Forms project and put my code in about page in a button
Android MainActivity.cs
using System;
using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.OS;
using Android.Content;
namespace TestAdId.Droid
{
[Activity(Label = "TestAdId", Icon = "#mipmap/icon", Theme = "#style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize )]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
public static Context Context =null;
public static MainActivity Instance = null;
protected override void OnCreate(Bundle savedInstanceState)
{
Instance = this;
base.OnCreate(savedInstanceState);
Context = Android.App.Application.Context;
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
The About Screen xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TestAdId.Views.AboutPage"
xmlns:vm="clr-namespace:TestAdId.ViewModels"
Title="{Binding Title}">
<ContentPage.BindingContext>
<vm:AboutViewModel />
</ContentPage.BindingContext>
<ContentPage.Resources>
<ResourceDictionary>
<Color x:Key="Accent">#96d1ff</Color>
</ResourceDictionary>
</ContentPage.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackLayout BackgroundColor="{StaticResource Accent}" VerticalOptions="FillAndExpand" HorizontalOptions="Fill">
<StackLayout Orientation="Horizontal" HorizontalOptions="Center" VerticalOptions="Center">
<ContentView Padding="0,40,0,40" VerticalOptions="FillAndExpand">
<Image Source="xamarin_logo.png" VerticalOptions="Center" HeightRequest="64" />
</ContentView>
</StackLayout>
</StackLayout>
<ScrollView Grid.Row="1">
<StackLayout Orientation="Vertical" Padding="30,24,30,24" Spacing="10">
<Label Text="Start developing now" FontSize="Title"/>
<Label Text="Make changes to your XAML file and save to see your UI update in the running app with XAML Hot Reload. Give it a try!" FontSize="16" Padding="0,0,0,0"/>
<Label FontSize="16" Padding="0,24,0,0">
<Label.FormattedText>
<FormattedString>
<FormattedString.Spans>
<Span Text="Learn more at "/>
<Span Text="https://aka.ms/xamarin-quickstart" FontAttributes="Bold"/>
</FormattedString.Spans>
</FormattedString>
</Label.FormattedText>
</Label>
<Label x:Name="IdfaLabel" Text="Unknown" TextColor="Black" FontSize="16" ></Label>
<Button Margin="0,10,0,0" Text="Get IDFA"
Clicked="Button_Clicked"
BackgroundColor="{StaticResource Primary}"
TextColor="White" />
</StackLayout>
</ScrollView>
</Grid>
</ContentPage>
The About Form Code
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using TestAdId.Services;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Net;
namespace TestAdId.Views
{
public partial class AboutPage : ContentPage
{
public string Idfa = "";
public AboutPage()
{
InitializeComponent();
}
private void Button_Clicked(object sender, EventArgs e)
{
IdfaLabel.Text = "Getting IDFA...";
IDeviceAdIdentifier service = DependencyService.Get<IDeviceAdIdentifier>();
var tadid = Task.Run(() =>
{
var t = service.GetAdvertisingIdentifier();
t.Wait();
return t.Result;
});
tadid.Wait();
Idfa = tadid.Result;
IdfaLabel.Text = Idfa;
}
}
}```
Tell me if you need another thing. This is a really simple sample just to try to making AAID working
Thanks
Regards
Hervé
Related
I created a simple program with MAUI to load 2 images, specified as Embedded Resources.
This is the MainPage:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Surprise.MainPage">
<ScrollView>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="550"/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<VerticalStackLayout x:Name="ImageContainer"
Grid.Row="0"
HeightRequest="500"
VerticalOptions="Center"
HorizontalOptions="Center" />
<Grid Grid.Row="1"
HorizontalOptions="Center"
HeightRequest="40">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Text="Image1"
Grid.Column="0"
Clicked="OnImage1ButtonClicked" />
<Button Text="Image2"
Grid.Column="2"
Clicked="OnImage2ButtonClicked" />
</Grid>
</Grid>
</ScrollView>
</ContentPage>
and this is its code behind:
public partial class MainPage : ContentPage
{
private readonly Image _image1;
private readonly Image _image2;
public MainPage()
{
InitializeComponent();
_image1 = new Image()
{
Source = ImageSource.FromResource("Surprise.Resources.Images.image1.jpeg"),
VerticalOptions = LayoutOptions.Center,
HeightRequest = 500
};
_image2 = new Image()
{
Source = ImageSource.FromResource("Surprise.Resources.Images.image2.jpg"),
VerticalOptions = LayoutOptions.Center,
HeightRequest = 500
};
}
private void OnImage1ButtonClicked(object sender, EventArgs e)
{
ImageContainer.Children.Clear();
ImageContainer.Children.Add(_image1);
}
private void OnImage2ButtonClicked(object sender, EventArgs e)
{
ImageContainer.Children.Clear();
ImageContainer.Children.Add(_image2);
}
}
On Windows it works correctly.
On Android sometimes the images are loaded in wrong order or even the same image is loaded when I press each button.
Is it a MAUI bug or I'm missing something?
Thanks in advance.
Well, there are some changes that were made with Maui projects, we now have Maui-specific build actions that you can use to specify to your project/solution what the type of a certain file is.
In your Scenario, you should use the MauiImage build action then just uses the name of the file as shown here: https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/image#load-a-local-image should be enough to fix your issue
I am using ZXing.Net.Mobile in a Xamarin.Forms project. It works fine on iOS, but on Android, the first time I use the scanner, I get the camera permissions popup, and grant them.
There is no image from the camera immediately after the permissions. If I quit the app and re-launch, the camera works fine from that point forward. How can I get it to work right away? Even if I close my view, dispose and re-initialize it, it still doesn't work until the app restarts.
Here is relevant code:
public partial class CEUScanModalPage : ContentPage, INotifyPropertyChanged {
private bool _isScanning;
public CEUScanModalPage() {
InitializeComponent();
IsScanning = false;
BindingContext = this;
Indicator.Start();
}
public bool IsScanning {
get {
return _isScanning;
}
set {
_isScanning = value;
OnPropertyChanged();
}
}
private async void OnCloseButtonClicked(object sender, EventArgs args) {
await Navigation.PopModalAsync();
}
protected override void OnAppearing() {
base.OnAppearing();
IsScanning = true;
}
protected override void OnDisappearing() {
base.OnDisappearing();
_scanView.OnScanResult -= Handle_OnScanResult;
_scanView.IsAnalyzing = false;
_scanView.IsScanning = false;
ParentGrid.Children.Remove(_scanView);
_scanView = null;
}
public async void Handle_OnScanResult(Result result) {
IsScanning = false;
}
}
XAML:
<?xml version="1.0" encoding="UTF-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:BehaviorLive" xmlns:grial="clr-namespace:UXDivers.Grial;assembly=UXDivers.Grial" xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms" xmlns:fftransformations="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Transformations" xmlns:zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms"
x:Class="BehaviorLive.Views.CEUScanModalPage"
NavigationPage.HasNavigationBar="False"
Style="{ StaticResource MainMenuOrModalBackgroundStyle }">
<ContentPage.Resources>
<ResourceDictionary
Source="/Styles/TabControl/SimpleTabResources.xaml" />
</ContentPage.Resources>
<ContentPage.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition
Height="145" />
<RowDefinition
Height="*" />
</Grid.RowDefinitions>
<Grid
RowSpacing="0"
ColumnSpacing="0"
Margin="0,0,0,10"
VerticalOptions="EndAndExpand">
<Grid.RowDefinitions>
<RowDefinition
Height="10" />
<RowDefinition
Height="Auto" />
<RowDefinition
Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition
Width="120" />
<ColumnDefinition
Width="*" />
</Grid.ColumnDefinitions>
<!-- LOGO -->
<Label
Grid.Row="0"
Grid.RowSpan="3"
Margin="20,0"
TextColor="{ DynamicResource InverseTextColor }"
FontSize="74"
FontFamily="{StaticResource FontAwesomeSolid}"
Text="{ x:Static local:FontawesomeSolidFont.Qrcode }"
Style="{ StaticResource FontIcon }"
HorizontalOptions="Start"
VerticalTextAlignment="Center" />
<!-- WELCOME -->
<Label
Grid.Row="1"
Grid.Column="1"
Text="CEU Checkin"
FontSize="22"
TextColor="{ DynamicResource InverseTextColor }"
Style="{ StaticResource LabelBoldStyle }"
VerticalOptions="End"
HorizontalOptions="Start" />
<!-- SUB -->
<Label
Grid.Row="2"
Grid.Column="1"
Text="Scan QR Code to check in/out of your event"
FontSize="16"
TextColor="{ DynamicResource InverseTextColor }"
VerticalOptions="Start"
HorizontalOptions="Start" />
</Grid>
<Grid
Grid.Row="1"
BackgroundColor="{ DynamicResource MainWrapperBackgroundColor }"
grial:Effects.ApplyIOSSafeAreaAsPadding="Bottom" x:Name="ParentGrid">
<!-- TAB -->
<StackLayout x:Name="LoadingIndicator" Grid.Row="0" VerticalOptions="CenterAndExpand">
<local:CustomActivityIndicator
Grid.Row="0"
x:Name="Indicator"
HorizontalOptions="Center"
VerticalOptions="Start" />
<Label
Grid.Row="1"
FontSize="Large"
HorizontalTextAlignment="Center"
Text="{ grial:Translate StringLoading }" />
</StackLayout>
<zxing:ZXingScannerView Grid.Row="0" Grid.RowSpan="2" x:Name="_scanView" OnScanResult="Handle_OnScanResult" IsScanning="{Binding IsScanning}"
WidthRequest="200" HeightRequest="200" />
</Grid>
<!-- CLOSE ICON -->
<Label
Style="{StaticResource IconCloseLabelStyle}">
<Label.GestureRecognizers>
<TapGestureRecognizer
Tapped="OnCloseButtonClicked" />
</Label.GestureRecognizers>
</Label>
</Grid>
</ContentPage.Content>
</ContentPage>
MainActivity.cs
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults) {
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
The best way to fix the issue would be to handle the permission part yourself
A generic permission helper:
using System.Threading.Tasks;
using Xamarin.Essentials;
using static Xamarin.Essentials.Permissions;
public static async Task<PermissionStatus> CheckAndRequestPermissionAsync<TPermission>()
where TPermission : BasePermission, new()
{
TPermission permission = new TPermission();
var status = await permission.CheckStatusAsync();
if (status != PermissionStatus.Granted)
{
status = await permission.RequestAsync();
}
return status;
}
Then use it like
var status = await PermissionsHelper.CheckAndRequestPermissionAsync<Permissions.Camera>();
if(status != PermissionStatus.Granted)
{
return;
}
I've been trying to record a video from Xamarin CommunityToolkit.
When the app it's in portraid mode video it's saved like it's in landscape mode and it's rotated at 90.
I have seen that many people using images can rotate them 90 degrees by controlling the orientation of the phone. But how can I do this with videos?
This is Camera XAML:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MYAPP.Views.CameraPage"
xmlns:vm="clr-MYAPP.ViewModels"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
xmlns:local="clr-namespace:MYAPP.Views;assembly=CustomView"
Title="{Binding Title}">
<AbsoluteLayout>
<StackLayout Orientation="Vertical" Spacing="0" AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0,0,1,1">
<local:CameraPreview Camera="Rear"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand" />
<xct:CameraView
Grid.Column="0"
x:Name="cameraView"
CaptureMode="Photo"
FlashMode="Off"
MediaCaptured="CameraView_MediaCaptured"
OnAvailable="CameraView_OnAvailable"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand" />
</StackLayout>
<Button
HorizontalOptions="CenterAndExpand"
VerticalOptions="End"
WidthRequest="500"
HeightRequest="70"
CornerRadius="15"
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds="0.5,1,AutoSize,AutoSize"
Margin="0, 0, 0, 30"
x:Name="doCameraThings"
Clicked="DoCameraThings_Clicked"
IsEnabled="False"
Text="Registra" />
</AbsoluteLayout>
</ContentPage>
This is CameraContentPage:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Xamarin.Essentials;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Xamarin.Forms.PlatformConfiguration;
using MYAPP.Services;
using Xamarin.CommunityToolkit.UI.Views;
using Xamarin.CommunityToolkit.Core;
namespace MYAPP.Views
{
public partial class CameraPage : ContentPage
{
public CameraPage()
{
InitializeComponent();
Title = "Camera";
cameraView.CaptureMode = CameraCaptureMode.Video;
cameraView.VideoStabilization = true;
}
void DoCameraThings_Clicked(object sender, EventArgs e)
{
cameraView.Shutter();
doCameraThings.Text = cameraView.CaptureMode == CameraCaptureMode.Video
? "Stop Recording"
: "Snap Picture";
}
void CameraView_OnAvailable(object sender, bool e)
{
doCameraThings.IsEnabled = e;
}
void CameraView_MediaCaptured(object sender, MediaCapturedEventArgs e)
{
switch (cameraView.CaptureMode)
{
default:
case CameraCaptureMode.Default:
case CameraCaptureMode.Photo:
break;
case CameraCaptureMode.Video:
FileMediaSource file = e.Video.File;
DependencyService.Get<IStorage>().exportFileMediaSource(file, "asd.mp4");
doCameraThings.Text = "Registra";
DependencyService.Get<IToast>().ShortAlert("Video salvato");
break;
}
}
}
}
I'm using Xamarin.CommunityToolkit ver 1.2.0. How can rotate video when saved ?
MediaCapturedEventArgs Rotarion property it's readonly and return 0.
API Level 29
I'm making an app with Xamarin Form that should work both on iOS and Android, I have a carousel view with an image inside, so I have tried making a carousel with a cell using this nugget: URL
while working fine on iOS on android the cell keeps crashing so I've changed with a cell containing only one image with a binding on the URL
now everything working but the are sono images sporadically missing inside the carousel.
Am I missing something? is there a nugget package for xamarin form for caching displaying correctly all the images?
thanks
making FFImage.Loading working on Android with no success
android cell
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:ffimage="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
xmlns:local="clr-namespace:CTSApp.Utility"
x:Class="CTSApp.Celle.cella_volantino_android">
<ContentView.Content>
<ScrollView>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand">
<local:PinchToZoomContainer>
<local:PinchToZoomContainer.Content>
<Image Source="{Binding url}" HorizontalOptions = "FillAndExpand"
VerticalOptions = "FillAndExpand" />
</local:PinchToZoomContainer.Content>
</local:PinchToZoomContainer>
</StackLayout>
</ScrollView>
</ContentView.Content>
</ContentView>
iOS cell
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:ffimage="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
xmlns:fftransf="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Transformations"
xmlns:local="clr-namespace:CTSApp.Utility" x:Class="CTSApp.Celle.cella_volantino">
<ContentView.Content>
<ScrollView>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand">
<local:PinchToZoomContainer>
<local:PinchToZoomContainer.Content>
<ffimage:CachedImage Grid.RowSpan="2" Aspect="AspectFill"
Source="{Binding url}"
DownsampleToViewSize="false"
LoadingPlaceholder="placeholder.png"
ErrorPlaceholder="placeholder.png"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<ffimage:CachedImage.CacheDuration>
<x:TimeSpan>0,0,15,0</x:TimeSpan>
</ffimage:CachedImage.CacheDuration>
</ffimage:CachedImage>
</local:PinchToZoomContainer.Content>
</local:PinchToZoomContainer>
</StackLayout>
</ScrollView>
</ContentView.Content>
</ContentView>
thanks for help.
EDIT
Here is my main activity:
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Plugin.FirebasePushNotification;
using Firebase;
using Plugin.CurrentActivity;
using Plugin.Permissions;
using Xamarin;
using Xamarin.Forms;
using Android.Content.Res;
using SegmentedControl.FormsPlugin.Android;
using ZXing.Mobile;
namespace CTSApp.Droid
{
[Activity(Label = "CTSApp", Icon = "#drawable/ic_launcher", Theme = "#style/MyTheme.Splash", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
MobileBarcodeScanner.Initialize(Application);
Rg.Plugins.Popup.Popup.Init(this, bundle);
ZXing.Net.Mobile.Forms.Android.Platform.Init();
FFImageLoading.Forms.Droid.CachedImageRenderer.Init(enableFastRenderer: true);
Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity = this;
CrossCurrentActivity.Current.Init(this, bundle);
SegmentedControlRenderer.Init();
FirebasePushNotificationManager.ProcessIntent(Intent);
LoadApplication(new App());
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
Plugin.Permissions.PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
global::ZXing.Net.Mobile.Forms.Android.PermissionsHandler.OnRequestPermissionsResult (requestCode, permissions, grantResults);
}
}
}
FFImageLoader version 2.4.3.840
Xamarin form version 2.50
EDIT 2
Maybe I've found the problem, here is the new definitive cell I'm using
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:ffimage="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
xmlns:local="clr-namespace:CTSApp.Utility"
x:Class="CTSApp.Celle.cella_volantino_android">
<ContentView.Content>
<ScrollView>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand">
<local:PinchToZoomContainer>
<local:PinchToZoomContainer.Content>
<Image Source="{Binding url}" HorizontalOptions = "FillAndExpand"
VerticalOptions = "FillAndExpand" >
<Image.Source>
<UriImageSource Uri="{Binding url}"
CacheValidity="14"
CachingEnabled="true"/>
</Image.Source>
</Image>
</local:PinchToZoomContainer.Content>
</local:PinchToZoomContainer>
</StackLayout>
</ScrollView>
</ContentView.Content>
</ContentView>
Now I'm using the standard image with caching , now on iOS everything works fine , on android I'm getting error from some pages
ImageLoaderSourceHandler: Could not retrieve image or image data was invalid: Uri:
that obviously does not load, I've followed the tutorial here
https://doumer.me/resolve-image-loading-error-in-xamarin-forms/
Still no luck, but if I turn the phone horizontally the image load correctly, I really have no clue
video here:
https://streamable.com/rk1rv
Here is a sample with CarouselView to show image.All can work in IOS and Android.If want to use ffimage:CachedImage ,replacing Image with it.
Here is Xaml code:
<StackLayout>
<CarouselView x:Name="carousel" ItemsSource="{Binding uris}">
<CarouselView.ItemTemplate>
<DataTemplate>
<Image
x:Name="PlantPicture"
Source="{Binding uri}"
HorizontalOptions="Center"
VerticalOptions="Center"
WidthRequest="150"
HeightRequest="150">
</Image>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</StackLayout>
Model code :
public class FloraData
{
public class StringData
{
public string uri { get; set; }
}
public List<StringData> uris { get; set; }
public FloraData()
{
uris = new List<StringData>() { new StringData() { uri = "https://static.inaturalist.org/photos/504134/medium.jpg?1379628103" },
new StringData() { uri = "https://static.inaturalist.org/photos/8784478/small.jpg?1499006293" },
new StringData() { uri = "https://api.idigbio.org/v2/media/23cbb9eb2750e80848ac95b5d2919323?size=thumbnail" },
new StringData() { uri = "https://api.idigbio.org/v2/media/c085496285be91ace0768eb517cc704b?size=thumbnail" },
new StringData() { uri = "http://swbiodiversity.org/imglib/arizona/IND/IND-0049/IND-0049216_1491615930_tn.jpg" }};
}
}
Finally , ContentPage.cs BindingContext :
FloraData floraData = new FloraData();
carousel.BindingContext = floraData;
I've created a rendered picker's to center center in the middle of the control but at the moment of entering the page, it shows the following error: System.ArgumentException.
I attach the code to see if you can help me.
In project new class...
using Xamarin.Forms;
namespace MaterialFUR
{
public class PickerCentrat : Picker
{
}
}
In Android ...
using MaterialFUR;
using MaterialFUR.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(PickerCentrat), typeof(RendererPicker))]
namespace MaterialFUR.Droid
{
public class RendererPicker : EntryRenderer
{
public RendererPicker(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.Gravity = GravityFlags.CenterHorizontal;
}
}
}
}
In XAML page...
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MaterialFUR.AgafarMaterialPage"
xmlns:local="clr-namespace:MaterialFUR"
Title="Agafar Material">
<ContentPage.Content>
<StackLayout HorizontalOptions="Center" VerticalOptions="Center" Spacing="25">
<Button x:Name="btnScan" Clicked="btnScan_Clicked" BackgroundColor="Gray" TextColor="White" Text="Llegir codi de barres" FontSize="30" FontAttributes="Bold" BorderRadius="30"/>
<Entry x:Name="entCodi" TextColor="Black" FontSize="30" FontAttributes="Bold" Keyboard="Default" Placeholder="Codi" HorizontalTextAlignment="Center"/>
<Entry x:Name="entQtat" TextColor="Black" FontSize="30" FontAttributes="Bold" Keyboard="Numeric" Placeholder="Quantitat" HorizontalTextAlignment="Center"/>
<local:PickerCentrat x:Name="pckUbicacio" Title="Ubicació" TextColor="Black" FontSize="30" FontAttributes="Bold">
<Picker.Items>
<x:String>SATMOBIL-1</x:String>
<x:String>SATMOBIL-2</x:String>
<x:String>SATMOBIL-3</x:String>
<x:String>SATMOBIL-4</x:String>
<x:String>SATMOBIL-5</x:String>
<x:String>SATMOBIL-6</x:String>
<x:String>SATMOBIL-7</x:String>
<x:String>SATMOBIL-8</x:String>
<x:String>SATMOBIL-9</x:String>
<x:String>TALLER</x:String>
</Picker.Items>
</local:PickerCentrat>
<StackLayout Orientation="Horizontal" Margin="0,100">
<Button x:Name="btnConfirmar" Clicked="BtnConfirmar_Clicked" BackgroundColor="SteelBlue" TextColor="White" Text="Confirmar" FontSize="30" FontAttributes="Bold" BorderRadius="30"/>
<Button x:Name="btnCancelar" Clicked="BtnCancelar_Clicked" BackgroundColor="Gray" TextColor="White" Text="Cancelar" FontSize="30" FontAttributes="Bold" BorderRadius="30"/>
</StackLayout>
</StackLayout>
</ContentPage.Content>
Error displayed.
I appreciate your help, thanks!
Your class needs to Inherit from PickerRenderer
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(PickerCentrat), typeof(RendererPicker))]
namespace MaterialFUR.Droid
{
public class RendererPicker : PickerRenderer
{
public RendererPicker(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.Gravity = GravityFlags.CenterHorizontal;
}
}
}
}
When in doubt about which class you need to Inherit from for your CustomRenderer, you can always check on the Xamarin.Forms source code here (for Android).
Hope this helps.