How to put a Popup that asks permission to use GPS?

Asked

Viewed 987 times

5

Guys, I’m programming in Java (with Android Studio) and this code to get the position of GPS, which works very well!

Now I’m trying to learn how request authorization from the user to use GPS, but found "too much information" on google... and nothing else seems to fit...

Of course it has to be because I’m new and I’m missing something:

if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    // TODO: Consider calling
    //    ActivityCompat#requestPermissions
    // here to request the missing permissions, and then overriding
    //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
    //                                          int[] grantResults)
    // to handle the case where the user grants the permission. See the documentation
    // for ActivityCompat#requestPermissions for more details.
    return;
}
Location l = LocationServices
        .FusedLocationApi
        .getLastLocation(mGoogleApiClient);

if(l != null){
    accuracy = l.getAccuracy();
    locationLatLng = new LatLng(l.getLatitude(), l.getLongitude());
    //garantee to get the "GPS position"  and only after that, show the map.
    if(map != null){
        setMarker(locationLatLng);
    }
}

So I’d like to divide my question into three parts:

  1. How is it and/or how does this part of "ask" authorization work? There is no simple rule to follow?

  2. How to adjust my android (version 5.1) to "lock the GPS" and force each APP to ask again to use it? I need to test repeatedly and block several times to be able to repeat the tests!

  3. Where am I missing this code that it does not ask for authorization (the popup does not open) and already leaves using GPS? It would be some config of my android?

I’m sorry if I wasn’t clear, I’m learning! Correct me, please!

PS: Here is the complete code of my class, I think it facilitates the understanding:

package jp.co.e_grid.rakuseki;

import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import io.realm.Realm;
import io.realm.RealmConfiguration;
import jp.co.e_grid.rakuseki.model.Report;

import static jp.co.e_grid.rakuseki.config.Constants.MAP_ZOOM;


/**
 * Created by ootaegd on 2016/12/16.
 */

public class PostPositionActivity extends AppCompatActivity
        implements OnMapReadyCallback, GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks {

    private GoogleMap map;
    private Marker marker = null;
    private LatLng locationLatLng;
    private float accuracy;
    private String uuId;
    protected Realm realm;
    private TextView tvCoordinate;
    private GoogleApiClient mGoogleApiClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_post_position);

        //前のactivityから渡されたデータを取得する
        Intent intent = getIntent();
        uuId = intent.getStringExtra("uuId");

        //realm設定
        Realm.init(this);
        RealmConfiguration config = new RealmConfiguration.Builder().build();
        Realm.setDefaultConfiguration(config);

        //toolbarを設定
        Toolbar toolbar = (Toolbar) findViewById(R.id.post_position_toolbar);
        toolbar.setTitle(getString(R.string.headPositionTitle));
        setSupportActionBar(toolbar);

        onBtnGpsClicked();
        nextViewActivity();

        //Fragment を取得
        MapFragment mapFragment = (MapFragment) getFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        // Start GPS Procedures
        callConnection();
    }

    /**
     * Getting the Google GPS API OnLine.
     */
    private synchronized void callConnection() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addOnConnectionFailedListener(this)
                .addConnectionCallbacks(this)
                .addApi(LocationServices.API)
                .build();
        mGoogleApiClient.connect();
    }

    /**
     * Getting the actual GPS position.
     */
    @Override
    public void onConnected(Bundle bundle) {

        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        Location l = LocationServices
                .FusedLocationApi
                .getLastLocation(mGoogleApiClient);

        if(l != null){
            accuracy = l.getAccuracy();
            locationLatLng = new LatLng(l.getLatitude(), l.getLongitude());
            //garantee to get the "GPS position"  and only after that, show the map.
            if(map != null){
                setMarker(locationLatLng);
            }
        }
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    /**
     * 次の画面へ遷移する処理
     */
    private void nextViewActivity() {
        //位置情報ボタンを押された時の処理
        Button btnPost = (Button) findViewById(R.id.btnPost);
        btnPost.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                //位置情報を追加する
                addReport();

                // 画面を起動
                Intent intent = new Intent();
                intent.setClassName("jp.co.e_grid.rakuseki", "jp.co.e_grid.rakuseki.PostConfirmationActivity");
                intent.putExtra("uuId",uuId);
                startActivity(intent);
            }
        });
    }

    /**
     * 現在地取得ボタンを押された時、現在地を取得する
     */
    private void onBtnGpsClicked() {
        Button btnPost = (Button) findViewById(R.id.btnLocation);
        btnPost.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                //現在地取得
            }
        });
    }

    /**
     * GoogleMapを読み込む前に、オーバライドして処理を行う
     *
     * @param googleMap
     */
    @Override
    public void onMapReady( GoogleMap googleMap ) {
        map = googleMap;

        //garantee to get the "GPS position"  and only after that, show the map.
        if(locationLatLng != null){
            setMarker(locationLatLng);
        }

        // GoogleMapが押下された時の処理
        googleMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
            @Override
            public void onMapClick( LatLng latLng ){
                // クリックされるたびにマーカが増えていく
                // 一つ前のマーカは削除する
                marker.remove();
                //Mapが押下されたらその位置にピンを立てる
                //緯度経度を取得
                locationLatLng = latLng;
                //garantee to get the "GPS position"  and only after that, show the map.
                if(locationLatLng != null){
                    //ピンを立てる
                    setMarker(locationLatLng);
                }
            }
        });
    }

    /**
     * Markerを立てる関数
     *
     * @param lacation 緯度経度情報
     */
    private void setMarker(LatLng lacation){
        marker = map.addMarker(new MarkerOptions()
                .position(lacation)
                .title("報告場所")
                .draggable(false));
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(lacation, MAP_ZOOM));
    }

    /**
     * 位置情報を追加する
     * @return プライマリキー
     */
    private void addReport(){

        realm = Realm.getDefaultInstance();
        //トランザクション開始
        realm.beginTransaction();
        //uuIdでターゲットを抽出
        Report report = realm.where(Report.class).equalTo("key",uuId).findFirst();
        //保存を行う
        report.setLat(Double.parseDouble(String.valueOf(locationLatLng.latitude)));
        report.setLon(Double.parseDouble(String.valueOf(locationLatLng.longitude)));
        report.setAccuracy(Double.parseDouble(String.valueOf(accuracy)));
        //トランザクション終了
        realm.commitTransaction();
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }
}

2 answers

4

You need to do two types of checks when it comes to GPS. The first is if your GPS is enabled and the second is if you are using API 23, you have to use Request for runtime permissions. Let’s go over the details.

Verification 1

For the first check, you can create a method that checks whether your GPS is enabled or not. If it is not enabled it sends a message asking if "you want to configure". This message can be adjustable according to your preferences. See the code below and adapt it the way you prefer:

 /**
 * Este metodo exite uma alerta para configuração do GPS
 */
public void showSettingsAlert(){
    android.app.AlertDialog.Builder alertDialog = new android.app.AlertDialog.Builder(Main.this);

    // Titulo do dialogo
    alertDialog.setTitle("GPS");

    // Mensagem do dialogo
    alertDialog.setMessage("GPS não está habilitado. Deseja configurar?");

    // botao ajustar configuracao
    alertDialog.setPositiveButton("Configurar", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog,int which) {
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(intent);
        }
    });

    // botao cancelar
    alertDialog.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            dialog.cancel();
        }
    });

    // visualizacao do dialogo
    alertDialog.show();
}

To call it, you first have to make the check whether the location is null or not in this way:

Location location = LocationServices.FusedLocationApi.getLastLocation(mapGoogleApiClient);
if (location != null) {
    // aqui você captura lat e lgn caso o localização seja diferente de nul
} else {
    // caso contrario ele chama seu método
    showSettingsAlert();
}

Verification 2

Starting with Android 6.0 (API level 23), users grant permissions to applications while they are running, not when they are installed. So this check is only for those who have API 23 or higher. This approach optimizes the application installation process as the user does not need to grant permissions when installing or updating the application.

To check if you have a permission, call the method ActivityCompat.checkSelfPermission(). For example, this snippet shows how to check if the activity is allowed to access location:

if (ActivityCompat.checkSelfPermission(context, 
    Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED 
    && ActivityCompat.checkSelfPermission(context,
    Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)

So basically you can create a return method of the kind boolean in this way:

public boolean getLocalization(Context context) {
    int REQUEST_PERMISSION_LOCALIZATION = 221;
    boolean res = true;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    public void requestPermissions(@NonNull String[] permissions, int requestCode)
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for Activity#requestPermissions for more details.

            res = false;
            ActivityCompat.requestPermissions((Activity) context, new String[]{
                            Manifest.permission.ACCESS_FINE_LOCATION},
                    REQUEST_PERMISSION_LOCALIZATION);

        }
    }
    return res;
}

In the verification and execution of the method, soon it will already show an alert requesting authorization. Then you just check this way:

if(getLocalization(this)){
    //ao entrar aqui é porque já foi liberado
}

In the question about "The location obtained by getLastLocation() always returns null", i explain exactly how it should be done to search for location by two ways Google Location API and for Locationmanager. Worth the thought you orient yourself there too, where I show the two ways.

I created a repository on Github by name obtgps picking up strings using two forms. You can download the project and do the proper checks.

  • COOL! I’ll study ! as soon as I finish I’ll come back to explain what happened! THANK YOU!

  • just a little question... that "checkSelfPermission" that I did there, well an hour to open the map.. is wrong??

  • @Camilayamamoto got the answer putting a project there on github.

  • AWESOME!!!! I will be able to study!!!! FINALLY!! Fight!!!!!!!!! then I will return with my results!

-1

In your manifest is where are saved the permission requests of everything your app can use, so just add the lines:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

If you are using targetSDK 21 or more, you may need this line tb:

<uses-feature android:name="android.hardware.location.gps" />

Source: Stack Overflow

If he goes out using GPS it’s probably because he’s already authorized, it’s a tough business to test.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.