web-dev-qa-db-ja.com

アプリケーションの起動時にGPSを有効にするようにユーザーに要求するにはどうすればよいですか?

private void turnGPSOn(){
String provider = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);

if(!provider.contains("gps")){ //if gps is disabled
    final Intent poke = new Intent();
    poke.setClassName("com.Android.settings", "com.Android.settings.widget.SettingsAppWidgetProvider"); 
    poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
    poke.setData(Uri.parse("3")); 
    sendBroadcast(poke);
}
}

logcatを参照してください

04/20 17:35:26: Launching app
$ adb Push F:\AndroidProject\Picker\app\build\outputs\apk\app-debug.apk /data/local/tmp/picker.novasyslabs.com.picker
$ adb Shell pm install -r "/data/local/tmp/picker.novasyslabs.com.picker"
    pkg: /data/local/tmp/picker.novasyslabs.com.picker
Success


$ adb Shell am start -n "picker.novasyslabs.com.picker/picker.novasyslabs.com.picker.SlashScreen" -a Android.intent.action.MAIN -c Android.intent.category.LAUNCHER
Connected to process 22502 on device sony-d2302-ZH80065A89
W/ResourceType: Found multiple library tables, ignoring...
W/ResourceType: Found multiple library tables, ignoring...
W/ResourceType: Found multiple library tables, ignoring...
W/art: Before Android 4.1, method Android.graphics.PorterDuffColorFilter Android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(Android.graphics.PorterDuffColorFilter, Android.content.res.ColorStateList, Android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in Android.graphics.drawable.Drawable
I/art: Background partial concurrent mark sweep GC freed 151(19KB) AllocSpace objects, 0(0B) LOS objects, 39% free, 13MB/22MB, paused 5.156ms total 20.919ms
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: picker.novasyslabs.com.picker, PID: 22502
                  Java.lang.RuntimeException: Unable to start activity ComponentInfo{picker.novasyslabs.com.picker/picker.novasyslabs.com.picker.SlashScreen}: Java.lang.ClassCastException: picker.novasyslabs.com.picker.SlashScreen cannot be cast to com.google.Android.gms.common.api.GoogleApiClient$ConnectionCallbacks
                      at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2379)
                      at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2442)
                      at Android.app.ActivityThread.access$800(ActivityThread.Java:156)
                      at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1351)
                      at Android.os.Handler.dispatchMessage(Handler.Java:102)
                      at Android.os.Looper.loop(Looper.Java:211)
                      at Android.app.ActivityThread.main(ActivityThread.Java:5371)
                      at Java.lang.reflect.Method.invoke(Native Method)
                      at Java.lang.reflect.Method.invoke(Method.Java:372)
                      at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:945)
                      at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:740)
                   Caused by: Java.lang.ClassCastException: picker.novasyslabs.com.picker.SlashScreen cannot be cast to com.google.Android.gms.common.api.GoogleApiClient$ConnectionCallbacks
                      at picker.novasyslabs.com.picker.SlashScreen.onCreate(SlashScreen.Java:65)
                      at Android.app.Activity.performCreate(Activity.Java:5990)
                      at Android.app.Instrumentation.callActivityOnCreate(Instrumentation.Java:1106)
                      at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2332)
                      at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2442) 
                      at Android.app.ActivityThread.access$800(ActivityThread.Java:156) 
                      at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1351) 
                      at Android.os.Handler.dispatchMessage(Handler.Java:102) 
                      at Android.os.Looper.loop(Looper.Java:211) 
                      at Android.app.ActivityThread.main(ActivityThread.Java:5371) 
                      at Java.lang.reflect.Method.invoke(Native Method) 
                      at Java.lang.reflect.Method.invoke(Method.Java:372) 
                      at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:945) 
                      at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:740) 
Application terminated.

パッケージマネージャー、ロケーションマネージャーなど、他の多くのオプションを試してみましたが、自分のやりたいことができませんでした。アプリケーションの起動時に、ユーザーにGPSを有効にするように求めるメッセージが表示されます。ユーザーが設定内に移動しないようにします。

そして、私が欲しかったのは、APIレベル> = 19です。

私の問題を解決するのを手伝ってください.........ありがとう

7
Mishu
 GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this).build();
    googleApiClient.connect();

    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(5 * 1000);
    locationRequest.setFastestInterval(2 * 1000);
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
            .addLocationRequest(locationRequest);

    //**************************
    builder.setAlwaysShow(true); //this is the key ingredient
    //**************************

    PendingResult<LocationSettingsResult> result =
            LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
    result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
        @Override
        public void onResult(@NonNull LocationSettingsResult result) {
            final Status status = result.getStatus();
//                final LocationSettingsStates state = result.getLocationSettingsStates();

            switch (status.getStatusCode()) {
                case LocationSettingsStatusCodes.SUCCESS:


                    break;
                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                    // Location settings are not satisfied. But could be fixed by showing the user
                    // a dialog.
                    try {
                        // Show the dialog by calling startResolutionForResult(),
                        // and check the result in onActivityResult().
                        status.startResolutionForResult(
                                context, 1000);
                    } catch (IntentSender.SendIntentException e) {
                        // Ignore the error.
                    }
                    break;
                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    break;
            }
        }
    });
11

下の画像に示すようなものが必要な場合は、それに従ってください。

Permission for GPS

  1. アプリに次の依存関係を追加します_build.gradle_

    _  implementation 'com.google.Android.gms:play-services-location:16.0.0'
    _
  2. 必要なタイプの位置要求を作成します。GPSには高精度が必要です

    _  LocationRequest locationRequest = LocationRequest.create();
      locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
      LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                    .addLocationRequest(locationRequest);
    _
  3. GPSの現在の状態を確認する必要があります。そのためには、LocationServices.getSettingsClient(getActivity()).checkLocationSettings(builder.build())を使用する必要があります。これにより、非同期で処理する必要があるTaskが返されます。 RESOLUTION_REQUIREDの場合、ユーザーにアクセス許可を与えるように要求します。これは、ユーザーにGPSを有効にするよう求めるプロンプトを表示する場所です。

    _Task<LocationSettingsResponse> result =
                    LocationServices.getSettingsClient(getActivity()).checkLocationSettings(builder.build());
    
    
    
    result.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() {
                @Override
                public void onComplete(@NonNull Task<LocationSettingsResponse> task) {
                    try {
                        LocationSettingsResponse response = task.getResult(ApiException.class);
                        // All location settings are satisfied. The client can initialize location
                        // requests here.
                    } catch (ApiException exception) {
                        switch (exception.getStatusCode()) {
                            case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                                // Location settings are not satisfied. But could be fixed by showing the
                                // user a dialog.
                                try {
                                    // Cast to a resolvable exception.
                                    ResolvableApiException resolvable = (ResolvableApiException) exception;
                                    // Show the dialog by calling startResolutionForResult(),
                                    // and check the result in onActivityResult().
                                    resolvable.startResolutionForResult(
                                            getActivity(),
                                            LocationRequest.PRIORITY_HIGH_ACCURACY);
                                } catch (IntentSender.SendIntentException e) {
                                    // Ignore the error.
                                } catch (ClassCastException e) {
                                    // Ignore, should be an impossible error.
                                }
                                break;
                            case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                                // Location settings are not satisfied. However, we have no way to fix the
                                // settings so we won't show the dialog.
                                break;
                        }
                    }
                }
            });
    _
  4. GPSをオンにするようにユーザーに要求したので、ユーザーがそれを許可したか無視したかを確認する必要があります。このためには、onActivityResultをオーバーライドします。上記のコードをフラグメントで実装している場合、結果は囲んでいるアクティビティで受信されることに注意してください。したがって、ActivityクラスのonActivityResultをオーバーライドします。

    _@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case LocationRequest.PRIORITY_HIGH_ACCURACY:
            switch (resultCode) {
                case Activity.RESULT_OK:
                    // All required changes were successfully made
                    Log.i(TAG, "onActivityResult: GPS Enabled by user");
                    break;
                case Activity.RESULT_CANCELED:
                    // The user was asked to change settings, but chose not to
                    Log.i(TAG, "onActivityResult: User rejected GPS request");
                    break;
                default:
                    break;
            }
            break;
        } 
    }
    _

From Androidドキュメント から

7
Ananth

ユーザーに設定ページに移動させてgpsを有効にしたくない場合は、SettingsApiを使用します。ここで、SettingsApiの使用方法のリンク SettingsApi

2
Hitesh Gehlot

これは@Ananth回答のKotlin実装です

private fun showLocationPrompt() {
        val locationRequest = LocationRequest.create()
        locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        val builder = LocationSettingsRequest.Builder().addLocationRequest(locationRequest)

        val result: Task<LocationSettingsResponse> = LocationServices.getSettingsClient(activity).checkLocationSettings(builder.build())

        result.addOnCompleteListener { task ->
            try {
                val response = task.getResult(ApiException::class.Java)
                // All location settings are satisfied. The client can initialize location
                // requests here.
            } catch (exception: ApiException) {
                when (exception.statusCode) {
                    LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> {
                        try {
                            // Cast to a resolvable exception.
                            val resolvable: ResolvableApiException = exception as ResolvableApiException
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            resolvable.startResolutionForResult(
                                activity, LocationRequest.PRIORITY_HIGH_ACCURACY
                            )
                        } catch (e: IntentSender.SendIntentException) {
                            // Ignore the error.
                        } catch (e: ClassCastException) {
                            // Ignore, should be an impossible error.
                        }
                    }
                    LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
                        // Location settings are not satisfied. But could be fixed by showing the
                        // user a dialog.

                        // Location settings are not satisfied. However, we have no way to fix the
                        // settings so we won't show the dialog.
                    }
                }
            }
        }
    }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            LocationRequest.PRIORITY_HIGH_ACCURACY -> {
                if (resultCode == Activity.RESULT_OK) {
                    Log.e("Status: ","On")
                } else {
                    Log.e("Status: ","Off")
                }
            }
        }
    }
1
OhhhThatVarun