Good day! Stumbled upon the following problem with LocationServices , I can not get the current location. The findLocation() method findLocation() . The problem is that LocationServices.FusedLocationApi.requestLocationUpdates does not call onLocationChanged , and LocationServices.FusedLocationApi.getLastLocation(mClient); returns null .
And the problem is also solved by restarting the emulator ... And for some reason on my nexus 5 android 6.0.1 crashes with an error ... I would be grateful for any hint.
All code below.
import java.util.ArrayList; import java.util.List; import java.util.Locale; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationServices; import com.google.android.gms.location.LocationListener; import android.app.ProgressDialog; import android.content.ContentValues; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.location.Address; import android.location.Criteria; import android.location.Geocoder; import android.location.Location; import android.location.LocationManager; import android.os.Bundle; import android.provider.Settings; import android.support.v4.app.Fragment; import android.support.v7.app.AlertDialog; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import static android.content.ContentValues.TAG; public class LocationFragment extends Fragment{ //Widget private Location mLocation; private TextView mCityResultTextView; private TextView mLongitudeTextView; private TextView mLatitudeTextView; //List Widget&Adapter private RecyclerView mLocationRecyclerView; private LocationAdapter mAdapter; //DataStorage private List<CityLocation> mCityLocations; private SQLiteDatabase mDatabase; //Location private LocationManager mLocationManager; private GoogleApiClient mClient; private ProgressDialog mDialog; public static LocationFragment newInstance() { return new LocationFragment(); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mClient = new GoogleApiClient.Builder(getActivity()) .addApi(LocationServices.API) .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() { @Override public void onConnected(Bundle bundle) { findLocation(); } @Override public void onConnectionSuspended(int i) { } }) .build(); mDatabase = new LocationBaseHelper(getContext()) .getWritableDatabase(); mCityLocations = getCityLocations(); mLocationManager = (LocationManager)getActivity().getSystemService(Context.LOCATION_SERVICE); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_location, container, false); mCityResultTextView = (TextView) v.findViewById(R.id.city_result_textView); mLongitudeTextView = (TextView) v.findViewById(R.id.longitude_result_textView); mLatitudeTextView = (TextView) v.findViewById(R.id.latitude_result_textView); mLocationRecyclerView = (RecyclerView) v.findViewById(R.id.location_recycler_view); LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); layoutManager.setReverseLayout(true); layoutManager.setStackFromEnd(true); mLocationRecyclerView.setLayoutManager(layoutManager); Button addLocationButton = (Button) v.findViewById(R.id.add_location); addLocationButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //findCityLocation(); findLocation(); } }); updateUI(); return v; } private void updateUI(){ mCityLocations = getCityLocations(); if (mCityLocations.size() > 0) { CityLocation city = mCityLocations.get(mCityLocations.size() - 1); mLatitudeTextView.setText(city.getLatLocation()); mLongitudeTextView.setText(city.getLongLocation()); mCityResultTextView.setText(city.getCity()); if (mAdapter == null) { mAdapter = new LocationAdapter(mCityLocations); mLocationRecyclerView.setAdapter(mAdapter); } else { mAdapter.setCityLocation(mCityLocations); mAdapter.notifyDataSetChanged(); mLocationRecyclerView.smoothScrollToPosition(mAdapter.getItemCount() - 1); } } } private String getAddressFromLocation(){ Geocoder geocoder = new Geocoder(getContext(), Locale.getDefault()); try { List<Address> addresses = geocoder.getFromLocation(mLocation.getLatitude(), mLocation.getLongitude(), 1); if (addresses != null) { if (!addresses.get(0).getLocality().equals("")) { return addresses.get(0).getLocality(); } else { return "Нет адресов!"; } } else { return "Нет адресов!"; } } catch (Exception e) { e.printStackTrace(); return "Не могу получить адрес!"; } } private boolean checkLocation() { if(!isLocationEnabled()) showAlert(); return isLocationEnabled(); } private boolean isLocationEnabled() { boolean temp1 = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); boolean temp2 = mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); return (temp1||temp2); } private void showAlert() { final AlertDialog.Builder dialog = new AlertDialog.Builder(getContext()); dialog.setTitle("Enable Location") .setMessage("Your Locations Settings is set to 'Off'.\nPlease Enable Location to " + "use this app") .setPositiveButton("Location Settings", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface paramDialogInterface, int paramInt) { Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); startActivity(myIntent); } }) .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface paramDialogInterface, int paramInt) { } }); dialog.show(); } public void findLocation(){ if(!checkLocation()) return; LocationRequest request = LocationRequest.create(); request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); request.setNumUpdates(1); request.setInterval(0); LocationServices.FusedLocationApi .requestLocationUpdates(mClient, request, new LocationListener() { @Override public void onLocationChanged(Location location) { Log.i(TAG, "Got a fix: " + location); mLocation = location; CityLocation cityLocation = new CityLocation(); if (mLocation != null) { //получаем адрес cityLocation.setCity(getAddressFromLocation()); //подготавливаем данные для БД cityLocation.setLocation(mLocation); mCityLocations.add(cityLocation); addLocations(cityLocation); //Обновляем представление updateUI(); } else { Toast.makeText(getContext(), "Location not Detected", Toast.LENGTH_SHORT).show(); cityLocation.setCity( "Location not Detected"); } } }); //реализация вторая LocationServices.FusedLocationApi.getLastLocation(mClient); CityLocation cityLocation = new CityLocation(); if (mLocation != null) { Toast.makeText(getContext(), mLocation.toString(), Toast.LENGTH_SHORT).show(); //получаем адрес cityLocation.setCity(getAddressFromLocation()); //подготавливаем данные для БД cityLocation.setLocation(mLocation); mCityLocations.add(cityLocation); addLocations(cityLocation); //Обновляем представление updateUI(); } else { Toast.makeText(getContext(), "Location not Detected", Toast.LENGTH_SHORT).show(); cityLocation.setCity( "Location not Detected"); } } //Database private static ContentValues getContentValues(CityLocation cityLocation) { ContentValues values = new ContentValues(); values.put(LocationTable.Cols.TITLE, cityLocation.getCity()); values.put(LocationTable.Cols.LATITUDE, cityLocation.getLatLocation()); values.put(LocationTable.Cols.LONGITUDE, cityLocation.getLongLocation()); return values; } public void addLocations(CityLocation cityLocation) { ContentValues values = getContentValues(cityLocation); mDatabase.insert(LocationTable.NAME, null, values); } private CityLocationCursorWrapper queryCityLocations(String whereClause, String[] whereArgs) { Cursor cursor = mDatabase.query( LocationTable.NAME, null, // Columns - null выбирает все столбцы whereClause, whereArgs, null, // groupBy null, // having null // orderBy ); return new CityLocationCursorWrapper(cursor); } public List<CityLocation> getCityLocations() { List<CityLocation> cityLocations = new ArrayList<>(); try (CityLocationCursorWrapper cursor = queryCityLocations(null, null)) { cursor.moveToFirst(); while (!cursor.isAfterLast()) { cityLocations.add(cursor.getCityLocation()); cursor.moveToNext(); } } return cityLocations; } @Override public void onStart() { super.onStart(); mClient.connect(); } @Override public void onStop() { super.onStop(); mClient.disconnect(); } } gradle:
apply plugin: 'com.android.application' android { compileSdkVersion 25 buildToolsVersion "24.0.1" defaultConfig { applicationId "com.fgurbanov.skynet.in_search_hire_test" minSdkVersion 21 targetSdkVersion 22 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" // Enabling multidex support. multiDexEnabled true } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:25.1.0' testCompile 'junit:junit:4.12' compile 'com.android.support:recyclerview-v7:25.1.0' compile 'com.android.support:design:25.1.0' compile 'com.google.android.gms:play-services-location:10.0.1' compile 'com.android.support:multidex:1.0.1' } Manifesto
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.fgurbanov.skynet.in_search_hire_test"> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <meta-data android:name="android.support.multidex.MultiDexApplication" android:value="@integer/google_play_services_version" />- <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>