java.lang.IllegalStateException:尝试将用户位置存储为变量时,onCreate()之前的活动无法使用系统服务
我为最后一年的项目创建了一个距离计算器。计算器应显示用户当前位置,然后在按下时在地图上显示标记。将显示从用户当前位置到标记的距离 我已检索到用户位置并将其存储为一个变量,我在代码中使用该变量,但在onCreate()之前,系统服务不可用于活动时抛出了java.lang.IllegalStateException:尝试将用户位置存储为变量时,onCreate()之前的活动无法使用系统服务,java,android,google-maps,system-services,Java,Android,Google Maps,System Services,我为最后一年的项目创建了一个距离计算器。计算器应显示用户当前位置,然后在按下时在地图上显示标记。将显示从用户当前位置到标记的距离 我已检索到用户位置并将其存储为一个变量,我在代码中使用该变量,但在onCreate()之前,系统服务不可用于活动时抛出了java.lang.IllegalStateException:System services错误。我试着从一开始就将代码放在onCreate()方法中,但这也不起作用。任何帮助都将不胜感激。我已经试了几个小时让它工作,但没有运气。当我尝试放置(Lo
java.lang.IllegalStateException:System services
错误。我试着从一开始就将代码放在onCreate()
方法中,但这也不起作用。任何帮助都将不胜感激。我已经试了几个小时让它工作,但没有运气。当我尝试放置(LocationManager)getSystemService(Context.LOCATION\u服务)时代码>在onCreate()
中,它需要权限,我已经尝试了所有操作
这是我的密码
package com.example.matthewmcnabb.moyola;
import android.Manifest;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.view.View;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
import java.io.IOException;
import java.util.List;
public class MapsActivity extends FragmentActivity {
// the Google Map object
private GoogleMap mMap;
private LocationManager locationManager;
private Location mCurrentLocation;
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
public Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
private double longitude = location.getLongitude();
private double latitude = location.getLatitude();
private LatLng STARTING_MARKER_POSITION =new LatLng(longitude, latitude);
private LatLng distanceFrom = STARTING_MARKER_POSITION;
// line will be drawn at the click event
private Polyline line=null;
// A Geocoder can transform a pair of latitude/longitude into a street address and viceversa.
// We'll use it in the listener
private static Geocoder geocoder=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// we set the layout for the Activity
setContentView(R.layout.activity_maps);
// the geocoder is instantiated for the first time
geocoder=new Geocoder(this);
// if there isn't a map, it will be created
setUpMapIfNeeded();
}
private GoogleMap.OnMapClickListener clickListener=new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(final LatLng pos) {
// this method is called when the user taps the map
// if a line already appears, it's removed
if (line!=null)
line.remove();
// a new line is created
line = mMap.addPolyline(new PolylineOptions()
.add(distanceFrom, pos)
.width(5) // width of the line
.color(Color.RED)); // line color
// call the converter object for geocoding invocation and distance calculation
new AddressConverter().execute(distanceFrom, pos);
}
};
@Override
protected void onResume() {
super.onResume();
// the availability of the GoogleMap will be checked before the Activity starts interacting with the user
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
// the map is created only it has not been initialized
if (mMap == null) {
// the map is located in the layout
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
// if a map exists, we proceed with initialization
if (mMap != null) {
setUpMap();
}
}
}
// Now it's time to configure the map. We can add markers, shapes, event handlers and so on
private void setUpMap() {
// the camera will be positioned according to the new coordinates
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(STARTING_MARKER_POSITION, 16));
// we choose the type of the map: Satellite in this case
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
// markerOptions describes the marker we want to place
MarkerOptions markerOptions=new MarkerOptions()
.position(STARTING_MARKER_POSITION)
.draggable(true);
// the marker has to be draggable as we'll move it
// the marker is rendered on the map
mMap.addMarker(markerOptions);
// we define the object to invoke when the marker is dragged
mMap.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener()
{
@Override
public void onMarkerDragStart(Marker arg0)
{
// this method is called when the drag starts
// the operation we need is the cancellation of a preexisting line
if (line!=null)
line.remove();
}
@Override
public void onMarkerDragEnd(final Marker pos)
{
// we get the final position of the marker
distanceFrom=pos.getPosition();
}
@Override
public void onMarkerDrag(Marker arg0)
{
// operations performed during the movement. Nothing to do
}
});
// the callback to invoke is set
mMap.setOnMapClickListener(clickListener);
}
// we want to know which address corresponds to this location
// we use AsyncTask to perform slower operations on a separate thread
private class AddressConverter extends AsyncTask<LatLng,Void,String>
{
// The ProgressDialog window we'll show during the calculation
private ProgressDialog progress=null;
// this method is called before the background job starts. It works on the main thread
@Override
protected void onPreExecute() {
// ProgressDialog is shown
progress= ProgressDialog.show(MapsActivity.this,"Distance calculator","We are calcultating the distance...", true,false);
}
// this method works on a separate thread
// it performs geocoding operations to retrieve the address of the points and calculates the distance in meters between them
@Override
protected String doInBackground(LatLng... params) {
float[] distance=new float[1];
try {
// the Location class contains what we need to calculate distances
Location.distanceBetween(params[0].latitude,params[0].longitude,params[1].latitude,params[1].longitude,distance);
// geocoding operations
List<Address> fromResult=geocoder.getFromLocation(params[0].latitude,params[0].longitude,1);
List<Address> toResult=geocoder.getFromLocation(params[1].latitude,params[1].longitude,1);
// the message informs the user about the distance from the marker to the point selected with the click
// if we have got both the addresses, we use them to compose the message, otherwise we show only the distance
if (fromResult.size()>0 && toResult.size()>0)
{
return "The distance is " + Math.round(distance[0]) + " meters";
}
else
return "The distance is " + Math.round(distance[0]) + " meters";
}
catch (IOException e) {
return "The distance is " + Math.round(distance[0]) + " meters";
}
}
@Override
protected void onPostExecute(String message)
{
if (progress!=null)
progress.dismiss();
// The builder of the window is instantiated
AlertDialog.Builder builder=new AlertDialog.Builder(MapsActivity.this);
builder.setTitle("Distance");
builder.setMessage(message);
// the Alert dialog appears
builder.show();
}
}
// this method only formats the message with addresses
private String getAddressDescription(Address a)
{
String city=a.getLocality();
String address=a.getAddressLine(0);
return "'"+address+"' ("+city+")";
}
}
package com.example.matthewmcnabb.moyola;
导入android.Manifest;
导入android.app.AlertDialog;
导入android.app.ProgressDialog;
导入android.content.Context;
导入android.content.pm.PackageManager;
导入android.graphics.Color;
导入android.location.Address;
导入android.location.Geocoder;
导入android.location.location;
导入android.location.LocationListener;
导入android.location.LocationManager;
导入android.os.AsyncTask;
导入android.support.v4.app.ActivityCompat;
导入android.support.v4.app.FragmentActivity;
导入android.os.Bundle;
导入android.support.v4.content.ContextCompat;
导入android.view.view;
导入com.google.android.gms.common.api.GoogleAppClient;
导入com.google.android.gms.location.LocationServices;
导入com.google.android.gms.maps.CameraUpdateFactory;
导入com.google.android.gms.maps.GoogleMap;
导入com.google.android.gms.maps.OnMapReadyCallback;
导入com.google.android.gms.maps.SupportMapFragment;
导入com.google.android.gms.maps.model.BitmapDescriptorFactory;
导入com.google.android.gms.maps.model.LatLng;
导入com.google.android.gms.maps.model.Marker;
导入com.google.android.gms.maps.model.MarkerOptions;
导入com.google.android.gms.maps.model.Polyline;
导入com.google.android.gms.maps.model.PolylineOptions;
导入java.io.IOException;
导入java.util.List;
公共类映射活动扩展了FragmentActivity{
//谷歌地图对象
私有谷歌地图;
私人场所经理场所经理;
私有位置mCurrentLocation;
LocationManager lm=(LocationManager)getSystemService(Context.LOCATION\u服务);
公共位置位置=lm.getLastKnownLocation(LocationManager.GPS\U提供程序);
private double longitude=location.getLongitude();
私有双纬度=location.getLatitude();
专用车床起始标记位置=新车床(经度、纬度);
专用车床距离=起始标记位置;
//将在单击事件时绘制线
专用多段线=空;
//地理编码器可以将一对纬度/经度转换为街道地址,反之亦然。
//我们将在侦听器中使用它
专用静态地理编码器Geocoder=null;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//我们为活动设置了布局
setContentView(R.layout.activity_映射);
//地理编码器第一次被实例化
地理编码器=新地理编码器(本);
//如果没有地图,将创建它
setupmapifneed();
}
私有GoogleMap.OnMapClickListener clickListener=新建GoogleMap.OnMapClickListener(){
@凌驾
点击时的公共作废(最终车床位置){
//当用户点击地图时调用此方法
//如果一行已经出现,它将被删除
如果(行!=null)
行。删除();
//将创建一个新行
line=mMap.addPolyline(新的PolylineOptions()
.添加(距离,位置)
.width(5)//行的宽度
.color(color.RED));//线条颜色
//调用converter对象进行地理编码调用和距离计算
新建AddressConverter()。执行(距离,位置);
}
};
@凌驾
受保护的void onResume(){
super.onResume();
//在活动开始与用户交互之前,将检查Google地图的可用性
setupmapifneed();
}
私有void setUpMapIfNeeded(){
//仅当映射尚未初始化时,才会创建映射
如果(mMap==null){
//地图位于布局中
mMap=((SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
//如果存在映射,则继续初始化
如果(mMap!=null){
setUpMap();
}
}
}
//现在是配置映射的时候了。我们可以添加标记、形状、事件处理程序等等
私有void setUpMap(){
//摄像机将根据新坐标进行定位
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(起始标记位置,16));
//我们选择地图的类型:在本例中为卫星
mMap.setMapType(GoogleMap.MAP_TYPE_卫星);
//markerOptions描述我们要放置的标记
MarkerOptions MarkerOptions=新MarkerOptions()
.位置(起始标记位置)
.draggable(正确);
//在我们移动标记时,它必须是可拖动的
//标记将在地图上渲染
mMap.addMarker(markerOptions);
//我们定义了在拖动标记时要调用的对象
mMap.setOnMarkerDragListener(新的GoogleMap.OnMarkerDragListener()
{
FATAL EXCEPTION: main
Process: com.example.matthewmcnabb.moyola, PID: 27349
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.matthewmcnabb.moyola/com.example.matthewmcnabb.moyola.MapsActivity}: java.lang.IllegalStateException: System services not available to Activities before onCreate()
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2515)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2723)
at android.app.ActivityThread.access$900(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1422)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5832)
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:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: java.lang.IllegalStateException: System services not available to Activities before onCreate()
at android.app.Activity.getSystemService(Activity.java:5259)
at com.example.matthewmcnabb.moyola.MapsActivity.<init>(MapsActivity.java:51)
at java.lang.reflect.Constructor.newInstance(Native Method)
at java.lang.Class.newInstance(Class.java:1650)
at android.app.Instrumentation.newActivity(Instrumentation.java:1079)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2505)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2723)
at android.app.ActivityThread.access$900(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1422)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5832)
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:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
template=getActivity().getString(R.string.url);
mgr=
(LocationManager)getActivity().getSystemService(Context.LOCATION_SERVICE);
}