簡體   English   中英

如何在android 8.0中獲取位置?

[英]How to get location in android 8.0?

我想在應用程序運行時在 Android 8.0+ 中獲取當前位置的經度和緯度,我不想像在后台服務中那樣顯示通知。

我以前在 8.0 以下的 android 中使用后台位置服務,但在 8.0 中我們需要顯示通知。

使用作業調度器它將在空閑狀態下工作

  if(Build.VERSION.SDK_INT>= 21)
            {
                jobScheduler = (JobScheduler) (getActivity()).getSystemService(JOB_SCHEDULER_SERVICE);
                ComponentName componentName = new ComponentName((getActivity()), MyBackgroundService.class);
                JobInfo jobInfo = new JobInfo.Builder(1, componentName)
                        .setPeriodic(100).build();
                Toast.makeText(getActivity(), "Service started!", Toast.LENGTH_SHORT).show();
                jobScheduler.schedule(jobInfo);
            }

MyBackgroundService.class

public class MyBackgroundService extends JobService {

private JobParameters params;
private myTask doThisTask;
boolean isGPSEnable = false;
boolean isNetworkEnable = false;
double latitude,longitude;
LocationManager locationManager;
Location location;
private String UserIDForToken;
private WeakReference<Context> cReference;
private RequestQueue requestQueue;
private LocationListener locationListener;
ConnectivityManager connectivityManager;


@Override
public boolean onStartJob(JobParameters params) {
    Log.d("called","onStartJob");
    this.params = params;
    cReference = new WeakReference<Context>(MyBackgroundService.this);
    requestQueue = Volley.newRequestQueue(cReference.get());
    doThisTask = new myTask();
    doThisTask.execute();
    return false;
}

@Override
public boolean onStopJob(JobParameters params) {
    if (doThisTask != null)
        doThisTask.cancel(true);
    return false;
}

private class myTask extends AsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(Void... params) {

        Log.d("called","doInBack");
        Log.d("called","done");

        /** displaying a toast ... **/
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {

            @Override
            public void run() {
                Log.d("called","handle.post");
                Toast.makeText(getApplicationContext(), "DONE !", Toast.LENGTH_SHORT).show();
                fn_getlocation();
            }
        });
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        //jobFinished(params, false);
        super.onPostExecute(aVoid);
    }
}


@SuppressLint("MissingPermission")
private void fn_getlocation(){
    Log.d("called","fn_getlocation");
    locationManager = (LocationManager)getApplicationContext().getSystemService(LOCATION_SERVICE);
    isGPSEnable = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    isNetworkEnable = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

    if (!isGPSEnable && !isNetworkEnable){

    }else {


        if (isGPSEnable){
            location = null;
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, new LocationListener() {
                @Override
                public void onLocationChanged(Location location) {
                }

                @Override
                public void onStatusChanged(String provider, int status, Bundle extras) {

                }

                @Override
                public void onProviderEnabled(String provider) {

                }

                @Override
                public void onProviderDisabled(String provider) {

                }
            });
            if (locationManager!=null){
                location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                if (location!=null){
                    latitude = location.getLatitude();
                    longitude = location.getLongitude();
                    fn_update(location);
                }
            }
        }


    }

}
private void fn_update(Location location){
    if(haveNetwork()) {
      // do your job here
    }else if(!haveNetwork())
    {
       Log.d("network not there","what");
    }

}





private boolean haveNetwork(){
    boolean have_WIFI=false;
    boolean have_MOBILE_DATA= false;

    connectivityManager = (ConnectivityManager) cReference.get().getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo[] networkInfos= connectivityManager.getAllNetworkInfo();


    for(NetworkInfo info:networkInfos)
    {
        if(info.getTypeName().equalsIgnoreCase("WIFI"))
            if(info.isConnected())
                have_WIFI = true;
        if(info.getTypeName().equalsIgnoreCase("MOBILE"))
            if(info.isConnected())
                have_MOBILE_DATA = true;
    }
    return have_MOBILE_DATA || have_WIFI;
}

}

我假設您的意思是通知是在此處提示位置許可的對話框。

要在 Android 8.0 中獲取用戶位置,可以使用 Google 的FusedLocationProviderClient

在此之前,您需要獲得用戶的位置許可。 請按照以下步驟操作:

在您的 AndroidManifest.xml 中添加權限

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

向用戶請求位置

//This can be any integer you want, just make sure they are same while requesting and handling the result
val REQUEST_LOCATION_PERMISSION_CODE = 100

ActivityCompat.requestPermissions(this@SplashActivity,
                    listOf(Manifest.permission.ACCESS_FINE_LOCATION).toTypedArray(),
                    1)

覆蓋onRequestPermissionsResult函數以捕獲權限對話框結果

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if(requestCode == REQUEST_LOCATION_PERMISSION_CODE){
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //Permission Granted. Yeah!
            }else{
                //Permission Denied. You might need to show a dialog to let user understand why u need the location, or disable any features that need location
            }
        }
    }

實現庫,在應用程序級別的gradle中添加以下行:

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

然后,在您想要獲取位置的活動/片段中,

LocationServices.getFusedLocationProviderClient(this)
                .lastLocation
                .addOnSuccessListener { location->
                    Log.i("LocationLatitude",location.latitude.toString())
                    Log.i("LocationLongitude",location.longitude.toString())
                }
                .addOnFailureListener { error->
                    error.printStackTrace()
                }

如果您想在應用程序中重復使用該位置,您實際上可以將LocationServices.getFusedLocationProviderClient(this)聲明為全局變量或使用數據注入。

如果您更喜歡快捷方式而不是本機方式,您可以查看DexterEasyPermissions等庫

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM