How to put a PopUp that asks for authorization to use GPS?

5

People, I'm programming in Java (with Android Studio) and this code to get the GPS position, which works great!

Now I'm trying to learn how to ask the user permission to use GPS, but I found "more info" on google ... And nothing else seems to fit ...

Of course it can only be because I'm new and I'm not understanding anything:

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 split my question into three parts:

  • How is and / or how does this part of "request" authorization work? Do not you have a simple rule to follow?

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

  • Where am I going wrong in this code that it does not ask for authorization (the popup does not open) and it already exits using GPS? Would it be some config from my android?

  • Sorry if I was not clear, I'm learning! Correct me, please!

    PS: Here's the complete code for my class, I think it makes it easier to understand:

    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) {
    
        }
    }
    
        
    asked by anonymous 25.01.2017 / 00:52

    2 answers

    4

    You need to do two types of checks when it comes to GPS. The first one is if your GPS is enabled and the second is if you are using API 23, you have to use Request run-time permissions . Let's get down to 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 issues a message asking if "you want to configure". This message can be adjusted 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 have to first check whether the location is null or not:

    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

    As of 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 because the user does not need to grant permissions when installing or updating the application.

    To verify that you have a permission, call the ActivityCompat.checkSelfPermission() method. 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 type boolean like this:

    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 show an alert asking for authorization. So just check it this way:

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

    In the question about " Google Location API and LocationManager . It's worth thinking you go there too, where I show you both ways.

    I created a repository in Github named obtgps picking lambs using two shapes. You can download the project and do the proper checks.

        
    25.01.2017 / 02:36
    -1

    In your manifest is where permission requests are saved from everything your app can use, then 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 target SDK 21 or higher, you may need this line tb:

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

    Source: Stack Overflow

    If it comes out using GPS is probably because it is already authorized, it is a difficult business to test.

        
    25.01.2017 / 02:14