0
votes

Xamarin pourquoi il est suspendu aux autorisations permettant à?

J'ai fait cela selon la documentation de Xamarin, il suffit de copier-coller un code.

Donc, dans App.xaml.cs j'ai un code comme celui-ci: P>

bool result = false;
this.isCompleted = false;
MainThread.BeginInvokeOnMainThread(
    async () => {
        result = await performCheckPermisions();
        this.isCompleted = true;
        }
    );

int counter = 0;
while (!this.isCompleted)
{
    Thread.Sleep(330);
    counter++;
    if ((counter % 10) == 0)
        this.Context.ToLogger(EAppLogLevel.Info, string.Format("   . CheckPermisions: still waiting (#{0})...", counter));
    if (counter > 100)
    {
        AbortApp(99, "Permissions were not comfirmed within specified timeout!");
        return false;
    }
}


6 commentaires

Parce que vous appelez .result sur votre tâche et causant une liaison morte.


Comment faire alors s'il n'utilise pas .result?


l'attend? Tout comme vous faites avec une autre tâche.


Je viens d'ajouter à ma quertention 3 exemples de tentatives que j'ai faites - comme vous pouvez tous les voir ne fonctionnent pas. Autorisations.Requestasync <> () L'appel se bloque toujours malgré des actions de mon côté (y compris l'attente, etc.).


Pourriez-vous essayer de déplacer la logique en ONAPPARING Méthode de Mainpage ? Je suppose qu'il existe des limitations sur Onstart méthode.


Oui, j'ai essayé - rien n'a changé. Il est toujours suspendu. Je fais même des checkpermissions d'appel dans RunonUthread () - le même effet, il est toujours suspendu. :-(


3 Réponses :


-1
votes

Comme Cheesebaron mentionné, vous souhaitez toujours utiliser attendre code> lorsque vous traitez avec une tâche code>. Vous pouvez modifier votre exemple comme SO:

public partial class App : Application
{
    public App()
    {
        InitializeComponent();

        MainPage = new NavigationPage(new MainPage());
    }

    protected override async void OnStart()
    {
        bool result = await CheckPermisions()
        if (!result)
        {
            AbortApp(3, "Missing required permissions!");
            return ;
        }
    }

    //[...]

    public async Task<bool> CheckPermisions()
    {
        bool v = await performCheckPermisions();
        if (v)
            initAppFolders();
        return v;
    }

    protected async Task<bool> performCheckPermisions()
    {
        // storage read
        PermissionStatus status = await Xamarin.Essentials.Permissions.CheckStatusAsync<Permissions.StorageRead>();
        if (status == PermissionStatus.Denied)
        {
            this.Context.ToLogger(EAppLogLevel.Warning, string.Format(" ! StorageRead: requesting..."));
            status = await Permissions.RequestAsync<Permissions.StorageRead>();
        }
        if (status == PermissionStatus.Denied)
            return false;
        // storage write
        status = await Xamarin.Essentials.Permissions.CheckStatusAsync<Permissions.StorageWrite>();
        if (status == PermissionStatus.Denied)
        {
            this.Context.ToLogger(EAppLogLevel.Warning, string.Format(" ! StorageWrite: requesting..."));
            status = await Permissions.RequestAsync<Permissions.StorageWrite>();
        }
        if (status == PermissionStatus.Denied)
            return false;

        return true; // Task.FromResult(true);
    }
}


3 commentaires

Ce n'est pas du tout une solution! Parce que le déplacement asynchreux / attendre davantage dans une hiérarchie d'appel n'a aucun sens! Donc, si j'appelle checkperm1 -> attendre checkperm2 -> attendre la checkerm3 -> etc ou moins - ne fait aucune différence car elle sera suspendue à un niveau sur une hiérarchie d'appel.


@DMITRY_BOND Je peux vous assurer que l'utilisation de attendre via toute la hiérarchie des appels est le moyen préféré d'utiliser des tâches. Lisez n'importe quel article sur async / attendre et vous entendrez exactement la même suggestion. link


Désolé, le code que vous avez posté ici n'est évidemment pas correspondre à mes conditions. Il est nécessaire d'ajouter un spécificité "async" aux checkpermisions () mais cela signifie exactement ce que j'ai mentionné précédemment - nous déplacons un "problème de suspension" un niveau supérieur dans une hiérarchie d'appel! Donc, il accrochera pas la méthode de la checkpermismismisions () mais au lieu de cela, il sera pendu à l'intérieur d'une guise qui appelle les checkpermisions (). Donc, c'est exactement le même problème qu'avant.



2
votes
  • ci-dessous est le code édité. Si vous avez vu une version antérieure, vous l'avez vu avoir des problèmes. Première entrée, donc je suis nouveau à cela. * li>

    J'ai essayé beaucoup de choses pour obtenir les autorisations, mais elle a toujours suspendu l'application, même avec les Awaits. P>

    Je voulais mettre les demandes d'autorisation aussi près de l'emplacement de l'utilisateur (comme recommandé) et pas abandonner l'application. C'est ce que j'ai finalement proposé: P>

    1. Création d'une interface d'autorisation dans le projet Xamarin Forms LI>
    2. Création d'une mise en œuvre Android des autorisations dans le projet Android Xamarin Forms Li>
    3. autorisation enregistrée en tant que service de dépendance dans l'activité Android avant de charger l'application Formulaires LI>
    4. Dans ma page de contenu WiFi, j'ai créé une méthode asynchrone qui vérifie la permission en appelant le service de dépendance enregistré li>
    5. Lorsque je clique sur le bouton de numérisation de la page WIFI, il appelle la méthode ASYNC pour voir si l'utilisateur doit donner la permission avant de continuer LI> ol>

      fonctionne comme un charme. p>

      La seule mise en garde est que si l'utilisateur sélectionne "Ne pas demander à nouveau" il devra définir les services de localisation manuellement. Je ne sais pas comment je peux dire à l'utilisateur depuis que les autorisations ne renvoient toujours que le statut refusé. Il obtiendra un dialogue l'informant d'autorisations insuffisantes, mais aucun dialogue OS ne lui permettra de demander des autorisations (DUH, car il a dit qu'il ne voulait pas les voir) p>

      l'interface des autorisations dans le Xamarin Forms Project em> P>

          private void btnDiscover_Clicked(object sender, EventArgs e) {
          Device.BeginInvokeOnMainThread(async () => {
              if (await this.ChkWifiPermissions()) {
                  this.btnSelect.IsVisible = false;
                  this.ResetWifiList(new List<WifiNetworkInfo>());
                  this.activity.IsRunning = true;
                  App.Wrapper.WifiDiscoverAsync();
              }
              else {
                  this.OnErr("Insufficient permissions to continue");
              }
          });
      }
      


0 commentaires

0
votes

Juste pour ajouter une variance à mes autorisations WiFi Vérifiez sur le bouton de numérisation WiFi, voici une variance qui aborde sur l'application Démarrer. Cela fonctionne mais je préfère celui qui demande plus près de l'utilisation de la permission.

Cela fonctionne et ne pend pas l'application. Toujours le problème si l'utilisateur a demandé de ne pas être demandé à nouveau. P>

Commencez par déclarant des interfaces de service dans le projet Xamarin Forms pour fermer l'application, et une autre pour vérifier et demander des autorisations em> p> xxx pré>

puis ajoutez des implications du système d'exploitation Android dans le projet Android Xamarin Forms em> P>

protected override void OnStart() {
    // This will abort the app at the start if the WIFI permissions are not given
    Device.BeginInvokeOnMainThread(async () => {
        if (!await this.CheckPermissions()) {
            ICloseApplication closeApp = DependencyService.Get<ICloseApplication>();
            await Application.Current.MainPage.DisplayAlert(
                App.GetText(MsgCode.Error),
                "Insufficient permissions",
                App.GetText(MsgCode.Ok));
            closeApp.CloseApp();
        }
    });
}


private async Task<bool> CheckPermissions() {
    ILocationWhileInUsePermission wifiPermissions = 
        DependencyService.Get<ILocationWhileInUsePermission>();
    PermissionStatus status = await wifiPermissions.CheckStatusAsync();
    if (status != PermissionStatus.Granted) {
        status = await wifiPermissions.RequestAsync();
    }
    return status == PermissionStatus.Granted;
}


0 commentaires