[GO] J'ai essayé de faire une activité qui définit collectivement les informations de position

Contexte

Il y a deux choses principales à faire lors de l'utilisation des informations de localisation sur Android.

  1. Activer l'autorisation
  2. Activez le paramètre des informations de localisation du terminal

Il existe plusieurs façons d'activer les deux ci-dessus, mais il existe maintenant un mécanisme qui vous permet d'exécuter le processus uniquement à l'intérieur de l'application.

Cependant, la méthode est un peu gênante ... ou plutôt, c'est un peu gênant pour les raisons suivantes même si je veux tout mettre ensemble. .. ..

--L'activité d'appel est interrompue lorsque la boîte de dialogue d'autorisation à définir est utilisée. --Activité requise pour recevoir un rappel (méthode d'activité requise)

Par conséquent, cette fois, nous avons créé une "activité dédiée qui active à la fois les paramètres d'autorisation et d'informations de localisation" afin qu'elle puisse être utilisée de n'importe où.

Chose que tu veux faire

En gros, créez une activité qui traite avec le flux suivant.

  1. Activité d'appel
  2. Vérifiez d'abord l'autorisation
  1. Ensuite, vérifiez le paramètre des informations de localisation --Non défini: effectuer une demande de réglage (affichage de la boîte de dialogue) --Déjà défini: renvoie le résultat à l'appelant

Le livrable réel est ici

Le code réel est décrit ci-dessous.

1. Activité d'appel

(Veuillez vérifier l'échantillon du livrable ici)

2. Vérifiez d'abord l'autorisation

Tout d'abord, parlons un peu de la permission.

Avec l'introduction du mécanisme d'autorisation d'exécution à partir du système d'exploitation 6.0 et supérieur, les deux autorisations suivantes (désignation dangereuse) nécessitent une autorisation pendant que l'application s'exécute en tant qu'informations d'emplacement.

(Pour plus de détails sur l'autorisation elle-même, voir Référence officielle etc.)

permission Contenu
ACCESS_COARSE_LOCATION Accès basé sur le réseau aux informations de localisation approximatives
ACCESS_FINE_LOCATION Accès à des informations de localisation spécifiques telles que le GPS

Par conséquent, tout d'abord, dans onCreate of Activity, vérifiez si l'autorisation ci-dessus est autorisée (dans le cas de OS 6.0 ou supérieur) et procédez comme suit.

private static final int REQUEST_CODE_LOCATION_PERMISSION = 1;
private static final String[] PERMISSIONS = {
        Manifest.permission.ACCESS_COARSE_LOCATION,
        Manifest.permission.ACCESS_FINE_LOCATION
};

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    if (isPermissionGranted()) {
        // (6.Moins de 0 ou déjà autorisé)
        //Comme cela est autorisé, définissez les informations de localisation du terminal
        requestLocationSetting();
        return;
    }
    // (6.0 ou plus)
    //Demander des autorisations
    ActivityCompat.requestPermissions(this, PERMISSIONS, REQUEST_CODE_LOCATION_PERMISSION);
}

private boolean isPermissionGranted() {
    for (String permission : PERMISSIONS) {
        if (PermissionChecker.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
            return false;
        }
    }
    return true;
}

Lorsqu'une demande d'autorisation est effectuée, la boîte de dialogue suivante s'affiche.

permission_dialog.png

Ensuite, vous recevrez un rappel de la boîte de dialogue, mais si l'autorisation est réussie, passez au paramètre d'informations de localisation et, si vous refusez, mettez-y fin.

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if (permissions.length != grantResults.length) {
        setResultCode(Locset.ResultCode.PERMISSION_FAILURE);
        return;
    }
    for (int i = 0; i < grantResults.length; i++) {
        if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
            //Rejeté
            //  1.Si vous transmettez une autorisation que vous n'avez jamais demandée, false est renvoyé
            //  2.Si l'autorisation demandée est rejetée avec une coche «Ne plus afficher», false est renvoyé.
            //  3.Renvoie true si l'autorisation demandée a été refusée et n'est pas cochée pour se cacher à nouveau
            //Note) Notez que 1 et 2 ne peuvent pas être distingués.
            if (ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])) {
                //Renvoyer le résultat à l'appelant (échec)
                finishForResult(Locset.ResultCode.PERMISSION_FAILURE);
            } else {
                //Renvoyer le résultat à l'appelant (échec)
                finishForResult(Locset.ResultCode.PERMISSION_FAILURE_DO_NOT_ASK_AGAIN);
            }
            return;
        }
    }
    //Comme cela est autorisé, définissez les informations de localisation du terminal
    requestLocationSetting();
}

private void finishForResult(@Locset.ResultCode int resultCode) {
    setResult(resultCode);
    finish();
}

C'est la fin du traitement des autorisations.

3. Ensuite, vérifiez le paramètre des informations de localisation

Vous pouvez également définir les informations de localisation directement à partir de l'écran de configuration du terminal ou de la zone de notification, mais en utilisant la fonction de Services Google Play, vous pouvez les définir directement depuis l'application. Peut être mis en place.

Pour l'instant, ajoutez play-services-location à build.gradle.

implementation 'com.google.android.gms:play-services-location:11.8.0'

À propos, la mise en œuvre est légèrement différente selon la version des services Google Play. Pour être clair, les versions 11 et supérieures sont beaucoup plus faciles à implémenter.

version Méthode de mise en œuvre
11.Moins de 0 Nécessite le client Google Api
LocationServices.Utiliser l'API des paramètres
référence
11.0 ou plus Utiliser le client de paramètres
référence

De plus, le réglage des informations de localisation peut prendre en considération la précision des informations souhaitées et la consommation de la batterie. Fondamentalement, vous pouvez spécifier les quatre priorités suivantes.

public final class LocationRequest extends zzbfm implements ReflectedParcelable {
    public static final int PRIORITY_HIGH_ACCURACY = 100;
    public static final int PRIORITY_BALANCED_POWER_ACCURACY = 102;
    public static final int PRIORITY_LOW_POWER = 104;
    public static final int PRIORITY_NO_POWER = 105;

Sous Android, les éléments de réglage des informations de localisation sont légèrement différents en fonction de la version du système d'exploitation (peut être par modèle), mais l'utilisation de ces services GooglePlay a l'avantage de le définir sur la priorité ci-dessus.

inférieur à v11.0

S'il est inférieur à la version 11, vous devez d'abord connecter le client Google Api.

private void requestLocationSetting() {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                @Override
                public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
                    finishForResult(Locset.ResultCode.GOOGLE_API_FAILURE);
                }
            })
            .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
                @Override
                public void onConnected(Bundle bundle) {
                    //Commencer l'acquisition des paramètres d'informations de localisation après la connexion
                    requestLocationSettingGoogleApi();
                }

                @Override
                public void onConnectionSuspended(int i) {
                    finishForResult(Locset.ResultCode.GOOGLE_API_FAILURE);
                }
            }).build();
    mGoogleApiClient.connect();
}

Une fois connecté à GoogleApiClient, il vérifie en fait les paramètres des informations de localisation du terminal et les processus pour afficher la boîte de dialogue de configuration. (En complément, ce processus de paramétrage est possible sans autorisation)

locationsetting.png

private static final int REQUEST_CODE_LOCATION_SETTING = 2;

private void requestLocationSettingGoogleApi() {
    final LocationSettingsRequest request = new LocationSettingsRequest.Builder()
            .setAlwaysShow(true) //Si vous ne le faites pas, vous ne pourrez pas appeler le suivant si vous ne le modifiez pas
            .addLocationRequest(LocationRequest.create().setPriority(mPriority))
            .build();

    final PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(
            mGoogleApiClient,
            request);

    result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
        @Override
        public void onResult(@NonNull LocationSettingsResult locationSettingsResult) {
            final Status status = locationSettingsResult.getStatus();
            switch (status.getStatusCode()) {
                case LocationSettingsStatusCodes.SUCCESS:
                    //Les informations de localisation de la priorité spécifiée peuvent être utilisées
                    finishForResult(Locset.ResultCode.SUCCESS);
                    return;
                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                    try {
                        //Afficher une boîte de dialogue permettant à l'utilisateur de modifier les paramètres des informations de localisation
                        status.startResolutionForResult(LocsetActivity.this, REQUEST_CODE_LOCATION_SETTING);
                        return;
                    } catch (IntentSender.SendIntentException e) {
                        // failure
                    }
                    break;
                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    //Appelé lorsque les informations de localisation ne peuvent pas être obtenues et qu'il est difficile de récupérer à partir de cet état
                    break;
            }
            finishForResult(Locset.ResultCode.LOCATION_SETTING_FAILURE);
        }
    });
}

Enfin, onActivityResult reçoit le rappel du résultat du paramètre.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    //Recevoir un rappel de la boîte de dialogue de configuration des informations de localisation
    if (requestCode == REQUEST_CODE_LOCATION_SETTING) {
        if (resultCode == Activity.RESULT_OK) {
            finishForResult(Locset.ResultCode.SUCCESS);
        } else {
            finishForResult(Locset.ResultCode.LOCATION_SETTING_FAILURE);
        }
    }
}

v11.0 ou supérieure

Dans la version 11 et supérieure, GoogleApiClient n'est plus nécessaire et s'effectue à l'aide d'une classe appelée SettingsClient. Il n'y a pas de changement particulier dans la façon dont vous recevez vos rappels.

private void requestLocationSetting() {
    final LocationSettingsRequest request = new LocationSettingsRequest.Builder()
            .setAlwaysShow(true)
            .addLocationRequest(LocationRequest.create().setPriority(mPriority))
            .build();
            
    final Task<LocationSettingsResponse> result = LocationServices.getSettingsClient(this)
            .checkLocationSettings(request);

    result.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() {
        @Override
        public void onComplete(@NonNull Task<LocationSettingsResponse> task) {
            try {
                task.getResult(ApiException.class);
                //Déjà prêt
                finishForResult(Locset.ResultCode.SUCCESS);
            } catch (ApiException exception) {
                switch (exception.getStatusCode()) {
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        try {
                            //Afficher une boîte de dialogue permettant à l'utilisateur de modifier les paramètres des informations de localisation
                            resolvable.startResolutionForResult(LocsetActivity.this, REQUEST_CODE_LOCATION_SETTING);
                            return;
                        } catch (IntentSender.SendIntentException e) {
                            // Ignore the error.
                        } catch (ClassCastException e) {
                            // Ignore, should be an impossible error.
                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        //Appelé lorsque les informations de localisation ne peuvent pas être obtenues et qu'il est difficile de récupérer à partir de cet état
                        break;
                }
                finishForResult(Locset.ResultCode.LOCATION_SETTING_FAILURE);
            }
        }
    });
}

finalement

C'est pourquoi le résultat est ici.

Recommended Posts

J'ai essayé de faire une activité qui définit collectivement les informations de position
J'ai essayé de créer une application OCR avec PySimpleGUI
J'ai essayé d'obtenir les informations de localisation du bus Odakyu
[Python] J'ai essayé de faire une application qui calcule le salaire en fonction des heures de travail avec tkinter
J'ai essayé de créer un système qui ne récupère que les tweets supprimés
J'ai essayé de faire 5 modèles de base d'analyse en 3 ans
[Python] Japonais simple ⇒ J'ai essayé de créer un outil de traduction en anglais
J'ai essayé de créer une fonction de similitude d'image avec Python + OpenCV
J'ai essayé de créer un site qui permet de voir facilement les informations mises à jour d'Azure
Je veux faire un programme d'automatisation!
J'ai créé une API Web
J'ai essayé de créer un langage original "PPAP Script" qui imagé PPAP (Pen Pineapple Appo Pen) avec Python
J'ai créé un capteur d'ouverture / fermeture (lien Twitter) avec TWE-Lite-2525A
J'ai essayé d'obtenir une image en grattant
J'ai essayé de faire de l'IA pour Smash Bra
J'ai essayé de détecter un objet avec M2Det!
J'ai créé un jeu ○ ✕ avec TensorFlow
[Python] J'ai essayé de créer une IA Shiritori qui améliore le vocabulaire grâce aux batailles
J'ai essayé de créer un BOT de traduction qui fonctionne avec Discord en utilisant googletrans
J'ai essayé de créer une fonction de dictionnaire insensible à la casse
J'ai fait de mon mieux pour créer une fonction d'optimisation, mais cela n'a pas fonctionné.
J'ai essayé de faire un "putain de gros convertisseur de littérature"
J'ai essayé de faire un BOT de détection de lèvre d'air et de réponse automatique pour le travail à distance
[LPIC 101] J'ai essayé de résumer les options de commande qui sont faciles à faire une erreur
J'ai essayé de créer un générateur de dialogue de personnage automatique par chaîne Markov N étage
Suite ・ J'ai essayé de créer Slackbot après avoir étudié Python3
J'ai essayé d'implémenter le perceptron artificiel avec python
J'ai essayé de déboguer.
J'ai essayé d'obtenir une AMI en utilisant AWS Lambda
J'ai essayé de devenir un Ann Man en utilisant OpenCV
J'ai essayé de faire une application mémo qui peut être pomodoro, mais un enregistrement de réflexion
J'ai essayé de visualiser les informations spacha de VTuber
C'est le jour du chat, alors j'ai essayé de créer quelque chose qui se traduise par des mots semblables à ceux d'un chat.
J'ai essayé de trouver la classe alternative avec tensorflow
[1 hour challenge] J'ai essayé de créer un site de bonne aventure qui soit trop adapté à Python
J'ai essayé de créer un générateur qui génère une classe conteneur C # à partir de CSV avec Python
J'ai essayé de faire d'Othello AI que j'ai appris 7,2 millions de mains par apprentissage profond avec Chainer
J'ai essayé de créer diverses "données factices" avec Python faker
J'ai essayé de notifier les informations de retard de train avec LINE Notify
J'ai essayé d'obtenir les informations du Web en utilisant "Requests" et "lxml"
J'ai fait un chronomètre en utilisant tkinter avec python
J'ai essayé de créer une interface graphique à trois yeux côte à côte avec Python et Tkinter
J'ai essayé d'obtenir diverses informations de l'API codeforces
J'ai créé un éditeur de texte simple en utilisant PyQt
J'ai essayé de créer un article dans Wiki.js avec SQL Alchemy
J'ai essayé d'apprendre PredNet
J'ai essayé d'organiser SVM.
J'ai essayé d'implémenter PCANet
J'ai essayé de réintroduire Linux
J'ai essayé de présenter Pylint
J'ai essayé de résumer SparseMatrix
jupyter je l'ai touché
J'ai essayé d'implémenter StarGAN (1)
J'ai essayé de construire un modèle d'estimation des titres d'articles susceptibles de faire le buzz avec Qiita
J'ai essayé de rendre possible l'envoi automatique d'un e-mail en double-cliquant simplement sur l'icône [Python]
J'ai essayé HR Tech pour développer un moteur de recherche expert par apprentissage automatique des informations de réunion en interne
[Python] J'ai essayé de créer un programme simple qui fonctionne sur la ligne de commande en utilisant argparse