我要求成功接收 FINE 和 COARSE 权限。然后构建GoogleAPIClient
并创建LocationRequest
,然后FusedLocationApi.getLastLocation
,它继续返回null。我知道在询问位置之前应该建立连接。因为建立连接的onStart()
是在retrieveLocation()
方法之后调用的,所以在构建mLocationApiClient.connect()
方法后立即调用GoogleApiClient. onConnected
并且当我检查mLocationApiClient.isConnected()时,它说'真正'。然后,当我尝试使用LastLocation
检索FusedLocationApi
时,它始终返回null。我感到困惑,因为我已多次检查并且有连接但没有检索到位置。我哪里错了?
MainActivity:
@EActivity(R.layout.activity_main)
public class MainActivity
extends AppCompatActivity
implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
private static final int MY_PERMISSION_REQUEST_CODE = 7171;
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 7172;
private static int UPDATE_INTERVAL = 5000; // seconds
private static int FATEST_INTERVAL = 3000; // seconds
private static int DISPLACEMENT = 10; // meters
private LocationRequest mLocatiionRequest;
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
@AfterViews
void retrieveLocation() {
int fineLocationPermission =
checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION);
int coarseLocationPermission =
checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION);
if (fineLocationPermission != PackageManager.PERMISSION_GRANTED
&& coarseLocationPermission != PackageManager.PERMISSION_GRANTED) {
this.requestPermissions(
new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION},
MY_PERMISSION_REQUEST_CODE
);
} else {
if (this.isPlayServiceAvailable()) {
this.buildGoogleApiClient();
this.createLocationRequest();
this.mLastLocation = LocationServices.FusedLocationApi.getLastLocation(this.mGoogleApiClient);
String message = "";
if (this.mLastLocation != null)
message = "Lat: " + this.mLastLocation.getLatitude() + ", Lon: " + this.mLastLocation.getLongitude();
else
message = "Didn't manage to get location.";
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case MY_PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (this.isPlayServiceAvailable())
this.buildGoogleApiClient();
}
break;
}
}
@Override
public void onConnected(@Nullable Bundle bundle) {
this.retrieveLocation();
}
@Override
public void onConnectionSuspended(int i) {
this.mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
@Override
public void onLocationChanged(Location location) {
this.mLastLocation = location;
}
@Override
protected void onStart() {
super.onStart();
if (this.mGoogleApiClient != null)
this.mGoogleApiClient.connect();
}
@Override
protected void onStop() {
LocationServices.FusedLocationApi.removeLocationUpdates(this.mGoogleApiClient, this);
if (this.mGoogleApiClient != null)
this.mGoogleApiClient.disconnect();
super.onStop();
}
private boolean isPlayServiceAvailable() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this, PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
Toast.makeText(getApplicationContext(), "The device is not supported", Toast.LENGTH_LONG).show();
finish();
}
return false;
}
return true;
}
private void buildGoogleApiClient() {
if (this.mGoogleApiClient == null) // avoid recreating client when it is already connected
this.mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
if (!this.mGoogleApiClient.isConnected()) // avoid unwanted hitting of onConnect callback
this.mGoogleApiClient.connect();
}
private void createLocationRequest() {
this.mLocatiionRequest = new LocationRequest();
this.mLocatiionRequest.setInterval(this.UPDATE_INTERVAL);
this.mLocatiionRequest.setFastestInterval(this.FATEST_INTERVAL);
this.mLocatiionRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
this.mLocatiionRequest.setSmallestDisplacement(this.DISPLACEMENT);
}
private void startLocationUpdates() {
int fineLocationPermission = checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION);
int coarseLocationPermission = checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION);
if (fineLocationPermission != PackageManager.PERMISSION_GRANTED && coarseLocationPermission != PackageManager.PERMISSION_GRANTED)
{
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(this.mGoogleApiClient, this.mLocatiionRequest, this);
}
private void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(this.mGoogleApiClient, this);
}
}
Build.graddle:
apply plugin: 'com.android.application'
apply plugin: 'android-apt'
def AAVersion = '4.3.1'
apt {
arguments {
androidManifestFile variant.outputs[0]?.processResources?.manifestFile
resourcePackageName 'com.mosy.kalin.mosy'
}
}
android {
compileSdkVersion 26
buildToolsVersion "26.0.0"
defaultConfig {
applicationId "mosy.mosyandroid"
minSdkVersion 26
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2',
{
exclude group: 'com.android.support', module: 'support-annotations'
})
apt "org.androidannotations:androidannotations:$AAVersion"
compile "org.androidannotations:androidannotations-api:$AAVersion"
compile 'com.android.support:appcompat-v7:26.0.0-beta2'
compile 'com.android.support:design:26.+'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.android.support:support-v4:26.0.0-beta2'
compile 'com.squareup.okhttp3:okhttp:3.8.1'
compile 'com.google.android.gms:play-services-location:11.0.4'
testCompile 'junit:junit:4.12'
}
答案 0 :(得分:3)
2 Reson for this
因此,为避免这种情况,您还必须从GPS获取位置,请考虑以下代码
在构建gradle中添加此依赖项
compile 'com.google.android.gms:play-services-location:10.2.1'
compile 'cn.pedant.sweetalert:library:1.3'
添加此类以获取位置 - LocationResolver.java
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import cn.pedant.SweetAlert.SweetAlertDialog;
import static android.content.Context.LOCATION_SERVICE;
public class LocationResolver implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener, android.location.LocationListener {
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 ; // 1 minute
//Location Request code
private final int REQUEST_LOCATION = 2;
//Google Api Client
private GoogleApiClient mGoogleApiClient;
//Location request for google fused location Api
private LocationRequest mLocationRequest;
//Location manager for location services
private LocationManager mLocationManager;
private OnLocationResolved mOnLocationResolved;
private Activity mActivity;
//Location permission Dialog
private SweetAlertDialog mDialog;
public LocationResolver(Activity activity){
mActivity=activity;
buildGoogleApiClient();
mLocationManager = (LocationManager) activity.getSystemService(LOCATION_SERVICE);
createLocationRequest();
}
public void resolveLocation(Activity activity, OnLocationResolved onLocationResolved){
this.mOnLocationResolved = onLocationResolved;
this.mActivity=activity;
if (isEveryThingEnabled()){
startLocationPooling();
}
}
public interface OnLocationResolved{
void onLocationResolved(Location location);
}
/*
* Checking every criteria are enabled for getting location from device
* */
public boolean isEveryThingEnabled() {
if (!isLocationPermissionEnabled()) {
showPermissionRequestDialog();
return false;
} else if (!isLocationEnabled(mActivity)) {
showLocationSettingsDialog();
return false;
} else if (!isConnected()) {
showWifiSettingsDialog(mActivity);
return false;
}
return true;
}
/*
* This function checks if location permissions are granted or not
* */
public boolean isLocationPermissionEnabled() {
return !(Build.VERSION.SDK_INT >= 23 &&
ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED);
}
/*
* Previous location permissions were denied , this function opens app settings page
* So user can enable permission manually
* */
private void startAppDetailsActivity() {
final Intent i = new Intent();
i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.setData(Uri.parse("package:" + mActivity.getPackageName()));
mActivity.startActivity(i);
}
private void showLocationSettingsDialog() {
SweetAlertDialog builder = new SweetAlertDialog(mActivity, SweetAlertDialog.WARNING_TYPE);
builder.setTitleText("Need Location");
builder.setContentText("In order for the app to work seamlessly.Please enable Location Service.");
builder.setConfirmText("Enable");
builder.setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() {
@Override
public void onClick(SweetAlertDialog dialog) {
dialog.cancel();
startLocationSettings();
}
});
builder.setCancelText("Cancel");
builder.setCancelClickListener(new SweetAlertDialog.OnSweetClickListener() {
@Override
public void onClick(SweetAlertDialog dialog) {
dialog.cancel();
}
});
builder.show();
}
private void startLocationSettings() {
mActivity.startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
/*
* location permissions were denied with "do not show" unchecked.. this function shows a dialog describing why this app
* need location permission.
* */
private void showPermissionRequestDialog() {
if (mDialog != null)
mDialog.cancel();
mDialog = new SweetAlertDialog(mActivity, SweetAlertDialog.NORMAL_TYPE);
mDialog.setTitleText("You need location permission");
mDialog.setContentText("Enable location permission");
mDialog.setConfirmText("grant");
mDialog.setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() {
@Override
public void onClick(SweetAlertDialog dialog) {
dialog.cancel();
ActivityCompat.requestPermissions(mActivity,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_LOCATION);
}
});
mDialog.setCancelText("Cancel");
mDialog.setCancelClickListener(new SweetAlertDialog.OnSweetClickListener() {
@Override
public void onClick(SweetAlertDialog dialog) {
dialog.cancel();
}
});
mDialog.show();
}
/*
*
*
* Previously Permission Request was cancelled with 'Dont Ask Again',
* Redirect to Settings after showing Information about why you need the permission
*
* */
private void showPermissionDeniedDialog() {
if (mDialog != null)
mDialog.cancel();
mDialog = new SweetAlertDialog(mActivity, SweetAlertDialog.NORMAL_TYPE);
mDialog.setTitleText("Need Location Permission");
mDialog.setContentText("Enable location permission");
mDialog.setConfirmText("grant");
mDialog.setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() {
@Override
public void onClick(SweetAlertDialog dialog) {
dialog.cancel();
startAppDetailsActivity();
}
});
mDialog.setCancelText("Cancel");
mDialog.setCancelClickListener(new SweetAlertDialog.OnSweetClickListener() {
@Override
public void onClick(SweetAlertDialog dialog) {
dialog.cancel();
}
});
mDialog.show();
}
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startLocationPooling();
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity,
Manifest.permission.ACCESS_FINE_LOCATION) && ActivityCompat.shouldShowRequestPermissionRationale(mActivity,
Manifest.permission.ACCESS_COARSE_LOCATION)) {
showPermissionRequestDialog();
} else {
showPermissionDeniedDialog();
}
}
}
}
}
/*
* Starting location pooling
* */
public void startLocationPooling() {
if (ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//
// 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 location = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (location != null) {
mOnLocationResolved.onLocationResolved(location);
} else {
if (mGoogleApiClient.isConnected())//if googleClient can get location from device the go for location update
startLocationUpdates();
else getLocation(); //Google Client cannot connected to its server. so we are fetching location directly from device
}
}
private synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(mActivity)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
public void onDestroy() {
mGoogleApiClient.disconnect();
}
public void onStop() {
if (mDialog != null) {
mDialog.cancel();
}
stopLocationUpdates();
mGoogleApiClient.disconnect();
}
public void onStart() {
mGoogleApiClient.connect();
}
@Override
public void onConnected(Bundle bundle) {
// startLocationPooling();
}
/*
* checks whether the device connected or not*/
public boolean isConnected() {
try {
ConnectivityManager cm = (ConnectivityManager) mActivity.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnected();
} catch (Exception e) {
return false;
}
}
@Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
@Override
public void onLocationChanged(Location location) {
if (location != null) {
mOnLocationResolved.onLocationResolved(location);
stopLocationUpdates();
}
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
}
@Override
public void onProviderDisabled(String s) {
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(mActivity, ConnectionResult.RESOLUTION_REQUIRED);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else {
Log.e("TAG", "Location services connection failed with code==>" + connectionResult.getErrorCode());
Log.e("TAG", "Location services connection failed Because of==> " + connectionResult.getErrorMessage());
}
}
private void createLocationRequest() {
Log.i("TAG", "CreateLocationRequest");
mLocationRequest = new LocationRequest();
long UPDATE_INTERVAL = 10 * 1000;
mLocationRequest.setInterval(UPDATE_INTERVAL);
long FASTEST_INTERVAL = 10000;
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
//**************************
builder.setAlwaysShow(true); //this is the key ingredient
//**************************
}
private void startLocationUpdates() {
Log.i("TAG", "StartLocationUpdates");
if (Build.VERSION.SDK_INT >= 23) {
if (ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this);
}
} else {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this);
}
}
private void stopLocationUpdates() {
try {
if (mGoogleApiClient.isConnected())
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
if (mLocationManager != null) {
mLocationManager.removeUpdates(this);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void getLocation() {
try {
// getting GPS status
Boolean isGPSEnabled = mLocationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
Boolean isNetworkEnabled = mLocationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
Log.e("Location", "No provider enabled");
} else {
if (ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mActivity, 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 location = null;
// First get location from Network Provider
if (isNetworkEnabled) {
if (mLocationManager != null) {
location = mLocationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
mOnLocationResolved.onLocationResolved(location);
} else {
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
if (location == null) {
if (mLocationManager != null) {
location = mLocationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
mOnLocationResolved.onLocationResolved(location);
} else {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* checks whether the device connected or not*/
public static boolean isNetWorkConnected(Context context) {
try {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnected();
} catch (Exception e) {
return false;
}
}
public void showWifiSettingsDialog(final Context context) {
SweetAlertDialog builder = new SweetAlertDialog(context, SweetAlertDialog.WARNING_TYPE);
builder.setTitleText("Need Internet");
builder.setContentText("Please enable your internet connection");
builder.setConfirmText("Enable");
builder.setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() {
@Override
public void onClick(SweetAlertDialog dialog) {
dialog.cancel();
startWifiSettings(context);
}
});
builder.setCancelText("Cancel");
builder.setCancelClickListener(new SweetAlertDialog.OnSweetClickListener() {
@Override
public void onClick(SweetAlertDialog dialog) {
dialog.cancel();
}
});
builder.show();
}
private void startWifiSettings(Context context) {
try {
context.startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
} catch (Exception e) {
Toast.makeText(context, "Something went wrong", Toast.LENGTH_SHORT).show();
}
}
public static boolean isLocationEnabled(Context context) {
int locationMode = 0;
String locationProviders;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
return false;
}
return locationMode != Settings.Secure.LOCATION_MODE_OFF;
} else {
locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
return !TextUtils.isEmpty(locationProviders);
}
}
}
在您的活动中,请按以下步骤操作
创建并初始化LocationResolver变量
private LocationResolver mLocationResolver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLocationResolver=new LocationResolver(this);
}
并将这些行添加到您的活动中
@Override
protected void onStart() {
super.onStart();
mLocationResolver.onStart();
}
@Override
protected void onStop() {
super.onStop();
mLocationResolver.onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
mLocationResolver.onDestroy();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
mLocationResolver.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
用法:当您想要位置时,使用此代码获取位置
void retrieveLocation() {
mLocationResolver.resolveLocation(this, new LocationResolver.OnLocationResolved() {
@Override
public void onLocationResolved(Location location) {
// Do what ever you want
}
});
}