Programming

Android에서 GPS를 프로그래밍 방식으로 활성화 또는 비활성화하려면 어떻게해야합니까?

procodes 2020. 6. 12. 23:07
반응형

Android에서 GPS를 프로그래밍 방식으로 활성화 또는 비활성화하려면 어떻게해야합니까?


나는 프로그래밍 방식에 안드로이드 GPS 끄기 / 켜기에 대한 질문은 알고 있다 논의 많은 시간을 , 대답은 항상 동일합니다 :

"보안 / 개인 정보 보호를 위해 위치 환경 설정 화면으로 이동하여 사용자가 활성화 / 비활성화 할 수 있도록해야합니다."

그러나 나는 내가 최근에 구입, 그 이해 태 스커을 미리 정해진 응용 프로그램 및 출구에 해제 (참조 입력에 GPS를 자동 활성화에 당신이 규칙을 설정할 수 있습니다, 당신이 그것으로 달성 할 수있는 많은 다른 것들 사이에, 시장에서와 여기 위해를 그것을 수행하는 방법에 대한 자습서, 그리고 그것은 작동합니다!))이 응용 프로그램은 많은 안드로이드 버전과 다른 장치에서 작동하기 때문에 펌웨어 서명 키로 서명 할 수 없으며 루팅 할 필요조차 없습니다.

내 앱 에서이 작업을 수행하고 싶습니다. 물론, 나는 사용자의 프라이버시를 날려 버리고 싶지 않기 때문에, 먼저 일반적인 "내 결정을 기억하라"체크 상자를 사용하여 사용자가 자동으로 켜고 싶은지 물어보고 그가 대답하면, 가능하게하십시오.

Tasker가 이것을 달성하는 방법에 대한 아이디어 나 단서가 있습니까?


전원 관리자 위젯의 버그를 이용 하여 GPS를 전환 할 수 있습니다 . 자세한 내용은이 xda 스레드참조하십시오 .

여기 내가 사용하는 예제 코드가 있습니다.

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);
    }
}

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

    if(provider.contains("gps")){ //if gps is enabled
        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);
    }
}

다음을 사용하여 기존 버전의 전원 제어 위젯이 gps를 토글 할 수 있는지 테스트하십시오.

private boolean canToggleGPS() {
    PackageManager pacman = getPackageManager();
    PackageInfo pacInfo = null;

    try {
        pacInfo = pacman.getPackageInfo("com.android.settings", PackageManager.GET_RECEIVERS);
    } catch (NameNotFoundException e) {
        return false; //package not found
    }

    if(pacInfo != null){
        for(ActivityInfo actInfo : pacInfo.receivers){
            //test if recevier is exported. if so, we can toggle GPS.
            if(actInfo.name.equals("com.android.settings.widget.SettingsAppWidgetProvider") && actInfo.exported){
                return true;
            }
        }
    }

    return false; //default
}

이 모든 답변은 현재 허용되지 않습니다. 다음은 올바른 것입니다.

여전히 답을 찾는 모든 사람들에게 :

다음은 OLA Cabs 및 기타 해당 앱이 수행하는 방식입니다.

onCreate에 이것을 추가하십시오

if (googleApiClient == null) {
    googleApiClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API).addConnectionCallbacks(this)
            .addOnConnectionFailedListener(Login.this).build();
    googleApiClient.connect();
            LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(30 * 1000);
    locationRequest.setFastestInterval(5 * 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(LocationSettingsResult result) {
            final Status status = result.getStatus();
            final LocationSettingsStates state = result
                    .getLocationSettingsStates();
            switch (status.getStatusCode()) {
            case LocationSettingsStatusCodes.SUCCESS:
                // All location settings are satisfied. The client can
                // initialize location
                // requests here.
                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(Login.this, 1000);
                } catch (IntentSender.SendIntentException e) {
                    // Ignore the 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;
            }
        }
    });
}

다음은 내포 된 방법입니다.

@Override
public void onConnected(Bundle arg0) {
    // TODO Auto-generated method stub

}

@Override
public void onConnectionSuspended(int arg0) {
    // TODO Auto-generated method stub

}

@Override
public void onConnectionFailed(ConnectionResult arg0) {
    // TODO Auto-generated method stub

}

다음은 동일한 Android 설명서 입니다.

다른 사람들이 여전히 어려움을 겪고 있다면 도움이됩니다.

편집 : 도움 더를 위해 Irfan Raza의 의견 추가.

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
     if (requestCode == 1000) {
         if(resultCode == Activity.RESULT_OK){
             String result=data.getStringExtra("result"); 
         } if (resultCode == Activity.RESULT_CANCELED) {
             //Write your code if there's no result 
         } 
    } 
} 

GPS 활성화 :

Intent intent=new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", true);
sendBroadcast(intent);

GPS 비활성화 :

Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", false);
sendBroadcast(intent);

이 코드는 작동 루팅 된앱을 이동하는 경우 /system/aps , 그들은 매니페스트에 다음과 같은 권한이 :

<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>

암호

private void turnGpsOn (Context context) {
    beforeEnable = Settings.Secure.getString (context.getContentResolver(),
                                              Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
    String newSet = String.format ("%s,%s",
                                   beforeEnable,
                                   LocationManager.GPS_PROVIDER);
    try {
        Settings.Secure.putString (context.getContentResolver(),
                                   Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
                                   newSet); 
    } catch(Exception e) {}
}


private void turnGpsOff (Context context) {
    if (null == beforeEnable) {
        String str = Settings.Secure.getString (context.getContentResolver(),
                                                Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
        if (null == str) {
            str = "";
        } else {                
            String[] list = str.split (",");
            str = "";
            int j = 0;
            for (int i = 0; i < list.length; i++) {
                if (!list[i].equals (LocationManager.GPS_PROVIDER)) {
                    if (j > 0) {
                        str += ",";
                    }
                    str += list[i];
                    j++;
                }
            }
            beforeEnable = str;
        }
    }
    try {
        Settings.Secure.putString (context.getContentResolver(),
                                   Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
                                   beforeEnable);
    } catch(Exception e) {}
}

Android 버전 4.4부터는 프로그래밍 방식으로 GPS를 활성화 / 비활성화 할 수 없습니다. 이 답변에 제안 된 코드를 시도하면 예외가 발생합니다.

java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGE

의도 설정을 사용하는 대신 ACTION_LOCATION_SOURCE_SETTINGS 대신 확인 버튼을 클릭하면 Google지도 및 GPS와 같은 앱에 팝업을 직접 표시 할 수 있습니다. 설정으로 리디렉션 할 필요가 없습니다. 간단히 내 코드를 사용해야합니다.

참고 :이 코드 줄은 위치가 켜져 있지 않으면 대화 상자를 자동으로 엽니 다. 이 줄은 Google지도에서도 사용됩니다.

 public class MainActivity extends AppCompatActivity
    implements GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener {


LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
PendingResult<LocationSettingsResult> result;
final static int REQUEST_LOCATION = 199;

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

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this).build();
    mGoogleApiClient.connect();

}

@Override
public void onConnected(Bundle bundle) {

    mLocationRequest = LocationRequest.create();
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setInterval(30 * 1000);
    mLocationRequest.setFastestInterval(5 * 1000);

    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
            .addLocationRequest(mLocationRequest);
    builder.setAlwaysShow(true);

    result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());

    result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
        @Override
        public void onResult(LocationSettingsResult result) {
            final Status status = result.getStatus();
            //final LocationSettingsStates state = result.getLocationSettingsStates();
            switch (status.getStatusCode()) {
                case LocationSettingsStatusCodes.SUCCESS:
                    // All location settings are satisfied. The client can initialize location
                    // requests here.
                    //...
                    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(
                                MainActivity.this,
                                REQUEST_LOCATION);
                    } catch (SendIntentException e) {
                        // Ignore the 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;
            }
        }
    });

}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    Log.d("onActivityResult()", Integer.toString(resultCode));

    //final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
    switch (requestCode)
    {
        case REQUEST_LOCATION:
            switch (resultCode)
            {
                case Activity.RESULT_OK:
                {
                    // All required changes were successfully made
                    Toast.makeText(MainActivity.this, "Location enabled by user!", Toast.LENGTH_LONG).show();
                    break;
                }
                case Activity.RESULT_CANCELED:
                {
                    // The user was asked to change settings, but chose not to
                    Toast.makeText(MainActivity.this, "Location not enabled, user cancelled.", Toast.LENGTH_LONG).show();
                    break;
                }
                default:
                {
                    break;
                }
            }
            break;
    }
}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {

}
} 

참고 :이 코드 줄은 위치가 켜져 있지 않으면 대화 상자를 자동으로 엽니 다. 이 줄은 Google지도에서도 사용됩니다.


프로그래밍 방식으로 GPS를 켜거나 끄려면 '루트'액세스 권한과 BusyBox가 설치되어 있어야합니다. 그럼에도 불구하고 과제는 사소한 것이 아닙니다.

샘플은 여기 : Google Drive , Github , Sourceforge

2.3.5 및 4.1.2 Android에서 테스트되었습니다.


다른 질문에 대한 답변이 개발되었지만 닫히고 커뮤니티에서도 시도해보고 싶습니다.

boolean gpsStatus = locmanager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!gpsStatus) {
    Settings.Secure.putString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "network,gps");
}

이 의견 보기

이 솔루션에는 WRITE_SETTINGSWRITE_SECURE_SETTINGS권한 이 필요합니다 .


어쩌면 수업 주위에 반사 트릭이있을 수 android.server.LocationManagerService있습니다.

또한 방법이 있습니다 (API 8부터) android.provider.Settings.Secure.setLocationProviderEnabled


이것은에서 제공하는 최상의 솔루션 Google Developers입니다. 초기화 후 onResume of onCreate에서이 메소드를 호출하기 만하면 GoogleApiClient됩니다.

private void updateMarkers() {
    if (mMap == null) {
        return;
    }

    if (mLocationPermissionGranted) {
        // Get the businesses and other points of interest located
        // nearest to the device's current location.
         mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API).build();
        mGoogleApiClient.connect();
        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(10000);
        locationRequest.setFastestInterval(10000 / 2);

        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
        builder.setAlwaysShow(true);


        LocationSettingsRequest.Builder builder = new LocationSettingsRequest
                .Builder()
                .addLocationRequest(mLocationRequest);
        PendingResult<LocationSettingsResult> resultPendingResult = LocationServices
                .SettingsApi
                .checkLocationSettings(mGoogleApiClient, builder.build());

        resultPendingResult.setResultCallback(new ResultCallback<LocationSettingsResult>() {
            @Override
            public void onResult(@NonNull LocationSettingsResult locationSettingsResult) {
                final Status status = locationSettingsResult.getStatus();
                final LocationSettingsStates locationSettingsStates = locationSettingsResult.getLocationSettingsStates();
                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.SUCCESS:
                        // All location settings are satisfied. The client can
                        // initialize location requests here.

                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        // Location settings are not satisfied, but this can be fixed
                        // by showing the user a dialog.


                        try {
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            status.startResolutionForResult(
                                    MainActivity.this,
                                    PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
                        } catch (IntentSender.SendIntentException e) {
                            // Ignore the 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;
                }

            }
        });


        @SuppressWarnings("MissingPermission")
        PendingResult<PlaceLikelihoodBuffer> result = Places.PlaceDetectionApi
                .getCurrentPlace(mGoogleApiClient, null);
        result.setResultCallback(new ResultCallback<PlaceLikelihoodBuffer>() {
            @Override
            public void onResult(@NonNull PlaceLikelihoodBuffer likelyPlaces) {
                for (PlaceLikelihood placeLikelihood : likelyPlaces) {
                    // Add a marker for each place near the device's current location, with an
                    // info window showing place information.
                    String attributions = (String) placeLikelihood.getPlace().getAttributions();
                    String snippet = (String) placeLikelihood.getPlace().getAddress();
                    if (attributions != null) {
                        snippet = snippet + "\n" + attributions;
                    }

                    mMap.addMarker(new MarkerOptions()
                            .position(placeLikelihood.getPlace().getLatLng())
                            .title((String) placeLikelihood.getPlace().getName())
                            .snippet(snippet));
                }
                // Release the place likelihood buffer.
                likelyPlaces.release();
            }
        });
    } else {
        mMap.addMarker(new MarkerOptions()
                .position(mDefaultLocation)
                .title(getString(R.string.default_info_title))
                .snippet(getString(R.string.default_info_snippet)));
    }
}

참고 : 이 코드 줄은 Location켜져 있지 않으면 대화 상자를 자동으로 엽니 다 . 이 줄은 Google지도에서도 사용됩니다.

 status.startResolutionForResult(
 MainActivity.this,
 PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);

이 코드는 ROOTED 전화에서 작동합니다.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        String[] cmds = {"cd /system/bin" ,"settings put secure location_providers_allowed +gps"};
        try {
            Process p = Runtime.getRuntime().exec("su");
            DataOutputStream os = new DataOutputStream(p.getOutputStream());
            for (String tmpCmd : cmds) {
                os.writeBytes(tmpCmd + "\n");
            }
            os.writeBytes("exit\n");
            os.flush();
        }
        catch (IOException e){
            e.printStackTrace();
        }
    }
}

GPS를 끄려면 대신이 명령을 사용할 수 있습니다

settings put secure location_providers_allowed -gps

다음 명령을 사용하여 네트워크 정확도를 전환 할 수도 있습니다.

settings put secure location_providers_allowed +network

끄려면 다음을 사용할 수 있습니다.

settings put secure location_providers_allowed -network

이 질문이 게시 된 이후 상황이 변경되었습니다. 이제 새로운 Google 서비스 API를 사용하여 사용자에게 GPS를 사용하도록 설정할 수 있습니다.

https://developers.google.com/places/android-api/current-place

매니페스트에서 ACCESS_FINE_LOCATION 권한을 요청해야합니다.

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

이 비디오도보십시오 :

https://www.youtube.com/watch?v=F0Kh_RnSM0w


위의 정답은 매우 오래되어 새로운 것이 필요하므로 여기에 답이 있습니다.

마지막 업데이트에서 우리는 androidx를 지원하므로 먼저 앱 레벨 build.gradle 파일에 종속성을 포함시킵니다

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

그런 다음 매니페스트 파일에 추가하십시오.

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

릴리스하는 경우 이러한 권한에 대한 사용자 동의를 잊지 마십시오

이제 여기 코드가 있습니다.

 protected void createLocationRequest() {
    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setInterval(10000);
    locationRequest.setFastestInterval(5000);
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
            .addLocationRequest(locationRequest);

    SettingsClient client = LocationServices.getSettingsClient(this);
    Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());



    task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
        @Override
        public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
            // All location settings are satisfied. The client can initialize
            // location requests here.
            // ...

            Toast.makeText(MainActivity.this, "Gps already open", 
                                          Toast.LENGTH_LONG).show();
            Log.d("location settings",locationSettingsResponse.toString());
        }
    });

    task.addOnFailureListener(this, new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            if (e instanceof ResolvableApiException) {
                // Location settings are not satisfied, but this can be fixed
                // by showing the user a dialog.
                try {
                    // Show the dialog by calling startResolutionForResult(),
                    // and check the result in onActivityResult().
                    ResolvableApiException resolvable = (ResolvableApiException) e;
                    resolvable.startResolutionForResult(MainActivity.this,
                            REQUEST_CHECK_SETTINGS);
                } catch (IntentSender.SendIntentException sendEx) {
                    // Ignore the error.
                }
            }
        }
    });
}


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

    if(requestCode==REQUEST_CHECK_SETTINGS){

        if(resultCode==RESULT_OK){

            Toast.makeText(this, "Gps opened", Toast.LENGTH_SHORT).show();
            //if user allows to open gps
            Log.d("result ok",data.toString());

        }else if(resultCode==RESULT_CANCELED){

            Toast.makeText(this, "refused to open gps", 
                                         Toast.LENGTH_SHORT).show();
            // in case user back press or refuses to open gps
            Log.d("result cancelled",data.toString());
        }
    }
}

문제가 발생하면 핑 해주세요


당신은 단지를 제거 할 필요 LocationListener에서LocationManager

manager.removeUpdates(listener);

이 코드를 사용하면 간단하고 쉽게 액세스 할 수 있습니다.

권한 :

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

이 코드에 따라 프로그래밍 방식으로 GPS에 액세스하십시오.

LocationManager locationManager ;
 boolean GpsStatus ;


            GPSStatus();

            if(GpsStatus == true)
            {
                textview.setText("Your Location Services Is Enabled");
            }else
                {textview.setText("Your Location Services Is Disabled");}

            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(intent);


    public void GPSStatus(){
    locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
    GpsStatus = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
} 

참고 URL : https://stackoverflow.com/questions/4721449/how-can-i-enable-or-disable-the-gps-programmatically-on-android

반응형