2017-05-07 22 views
0

情况: 我有一个OpenActivity,我想要有当前的位置,要做到这一点我要求所有需要的权限,之后我想打开新的活动并提供这个数据。Android-等待改变经纬度

问题:第一次启动我提供的经度和纬度= 0.00。

问题:我该如何解决这个问题?只有当我的位置设置正确时,我才会呼叫新的活动。

这是我的代码:

public class OpenActivity extends AppCompatActivity { 
    public static final int PERMISSIONS_REQUEST_LOCATION = 99; 
    public static final int PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 98; 
    public Boolean networkPermission=false; 
    public Boolean locationPermission=false; 
    public Boolean storagePermission=false; 

    private TrackGPS gps = null; 


    double longitude=0.00; 
    double latitude=0.00; 
    private Location location=null; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_open); 
     checkLocationPermission(); 
     checkStoragePermission(); 
     networkPermission=checkNetworkState(); 
     getLocation(); 
     Intent i = new Intent(OpenActivity.this,MainActivity.class); 
    i.putExtra("location",location); 
    startActivity(i); 

    } 

    public void getLocation(){ 


     if(locationPermission){ 
      gps = new TrackGPS(OpenActivity.this); 
      if(gps.canGetLocation() && gps.getLoc()!=null){ 
       location=gps.getLoc(); 
        latitude=location.getLatitude(); 
        longitude=location.getLongitude(); 

      } 
      else 
      { 
       if (!gps.canGetLocation()) 
        { 
        gps.showSettingsAlert(); 
        } 
      } 
     } 
    } 
    @Override 
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
     switch (requestCode) { 
      case PERMISSIONS_REQUEST_LOCATION: 
       if (grantResults.length > 0 
         && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
        locationPermission=true; 

       } else { 
        locationPermission=false; 
       } 


      break; 
      case PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE: 
      { 
       if (grantResults.length > 0 
         && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
        storagePermission=true; 
        } else { 
        storagePermission=false; 
       } 

      } 
      break; 
     } 


    } 


    private void checkStoragePermission() { 
     if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE) 
       != PackageManager.PERMISSION_GRANTED) { 
      if (ActivityCompat.shouldShowRequestPermissionRationale(this, 
        Manifest.permission.READ_EXTERNAL_STORAGE)) { 
       new AlertDialog.Builder(this) 
         .setTitle("Storage Permission Needed") 
         .setMessage("This app needs the Storage permission, please accept to use Storage functionality") 
         .setPositiveButton("OK", new DialogInterface.OnClickListener() { 
          @Override 
          public void onClick(DialogInterface dialogInterface, int i) { 
           ActivityCompat.requestPermissions(OpenActivity.this, 
             new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 
             PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE); 
          } 
         }) 
         .create() 
         .show(); 


      } else { 
       ActivityCompat.requestPermissions(this, 
         new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 
         PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE); 
      } 
     }else{ 
      storagePermission=true; 
     } 
    } 



    private void checkLocationPermission() { 
     if (ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) 
       != PackageManager.PERMISSION_GRANTED) { 
      if (ActivityCompat.shouldShowRequestPermissionRationale(this, 
        android.Manifest.permission.ACCESS_FINE_LOCATION)) { 
       new AlertDialog.Builder(this) 
         .setTitle("Location Permission Needed") 
         .setMessage("This app needs the Location permission, please accept to use location functionality") 
         .setPositiveButton("OK", new DialogInterface.OnClickListener() { 
          @Override 
          public void onClick(DialogInterface dialogInterface, int i) { 
           ActivityCompat.requestPermissions(OpenActivity.this, 
             new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 
             PERMISSIONS_REQUEST_LOCATION); 
          } 
         }) 
         .create() 
         .show(); 


      } else { 
       ActivityCompat.requestPermissions(this, 
         new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 
         PERMISSIONS_REQUEST_LOCATION); 
      } 
     }else{ 
      locationPermission=true; 
     } 
    } 

    protected boolean checkNetworkState(){ 
     ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(OpenActivity.this.CONNECTIVITY_SERVICE); 
     if(connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState() == NetworkInfo.State.CONNECTED || 
       connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState() == NetworkInfo.State.CONNECTED) { 
      return true ; 
     } 
     else { 
      return false; 
     } 
    } 

} 

TrackGPS.java

public class TrackGPS extends Service implements LocationListener { 

    private final Context mContext; 


    boolean checkGPS = false; 


    boolean checkNetwork = false; 

    boolean canGetLocation = false; 

    Location loc; 
    double latitude; 
    double longitude; 

    public Location getLoc() { 
     return loc; 
    } 

    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; 


    private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; 
    protected LocationManager locationManager; 

    public TrackGPS(Context mContext) { 
     this.mContext = mContext; 
     getLocation(); 
    } 

    private Location getLocation() { 

     try { 
      locationManager = (LocationManager) mContext 
        .getSystemService(LOCATION_SERVICE); 

      // getting GPS status 
      checkGPS = locationManager 
        .isProviderEnabled(LocationManager.GPS_PROVIDER); 

      // getting network status 
      checkNetwork = locationManager 
        .isProviderEnabled(LocationManager.NETWORK_PROVIDER); 

      if (!checkGPS && !checkNetwork) { 
       Toast.makeText(mContext, "No access", Toast.LENGTH_SHORT).show(); 
      } else { 
       this.canGetLocation = true; 
       if (checkNetwork) { 
        try { 
         locationManager.requestLocationUpdates(
           LocationManager.NETWORK_PROVIDER, 
           MIN_TIME_BW_UPDATES, 
           MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
         if (locationManager != null) { 
          loc = locationManager 
            .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 

         } 

         if (loc != null) { 
          latitude = loc.getLatitude(); 
          longitude = loc.getLongitude(); 
         } 
        } 
        catch(SecurityException e){ 

        } 
        } 
       } 
       if (checkGPS) { 
        if (loc == null) { 
         try { 
          locationManager.requestLocationUpdates(
            LocationManager.GPS_PROVIDER, 
            MIN_TIME_BW_UPDATES, 
            MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
          if (locationManager != null) { 
           loc = locationManager 
             .getLastKnownLocation(LocationManager.GPS_PROVIDER); 
           if (loc != null) { 
            latitude = loc.getLatitude(); 
            longitude = loc.getLongitude(); 
           } 
          } 
         } catch (SecurityException e) { 

         } 
        } 
      } 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return loc; 
    } 

    public double getLongitude() { 
     if (loc != null) { 
      longitude = loc.getLongitude(); 
     } 
     return longitude; 
    } 

    public double getLatitude() { 
     if (loc != null) { 
      latitude = loc.getLatitude(); 
     } 
     return latitude; 
    } 

    public boolean canGetLocation() { 
     return this.canGetLocation; 
    } 

    public void showSettingsAlert() { 
     AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext); 


     alertDialog.setTitle("GPS non attivo"); 

     alertDialog.setMessage("E' necessario abilitare il GPS, vuoi abilitarlo"); 


     alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialog, int which) { 
       Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
       mContext.startActivity(intent); 
       ((Activity)mContext).finish(); 

      } 
     }); 


     alertDialog.setNegativeButton("No", new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialog, int which) { 
       dialog.cancel(); 
      } 
     }); 


     alertDialog.show(); 
    } 


    public void stopUsingGPS() { 
     if (locationManager != null) { 

      locationManager.removeUpdates(TrackGPS.this); 
     } 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public void onLocationChanged(Location location) { 

    } 

    @Override 
    public void onStatusChanged(String s, int i, Bundle bundle) { 

    } 

    @Override 
    public void onProviderEnabled(String s) { 

    } 

    @Override 
    public void onProviderDisabled(String s) { 

    } 
} 

在gradle这个:compile 'com.google.android.gms:play-services:9.4.0'

+0

从[摆脱'TrackGPS'类开始](https://stackoverflow.com/questions/43082062/code-will-only-return-0-0-0-0-gps-coordinate-while-投掷nullpointerexceptio)。然后,在获得许可之前不要调用getLocation()。然后,不要调用'startActivity()'直到从LocationListener获得位置(因为'getLastKnownLocation()'可能返回'null')。 – CommonsWare

+0

@CommonsWare如何在“获得许可之前不要调用getLocation()”?如果我使用正常的条件,不工作,如果我使用循环条件,我的程序在循环中崩溃 – Juantums

回答

0

打电话给你的意图在 “OnLoctaionChanged” 的方法。在“OnLocationChanged”方法中定义一个条件来检查你是否得到了正确的位置。当这个条件成立时,传递意图,否则什么都不做。 “OnLocationChanged”方法会一直重复调用,直到您停止。 希望这会有所帮助。

+0

这种方法似乎解决了部分问题,因为在这种情况下,当我的位置发生变化时,我可以获得新的Activity,但也是如此,我把控制权交给我的TrackGPS类而不是OpenActivity.class – Juantums

1

我解决了自己的问题,我实现了一个回调方法,我不知道现在是否是有效的,但工作,我后,我加入新行代码/更新:

TrackGPS.java,

 public interface Icall{ 
      void call(Location location); 
     } 
     private Icall callerActivity; 

     public void show(Location posizione){ 
      callerActivity.call(posizione); 
     } 
    @Override 
    public void onLocationChanged(Location location) { 
     this.show(location); 
    } 

我更新的构造:

public TrackGPS(Context mContext,Activity activity) { 
     this.mContext = mContext; 
     callerActivity=(Iprova)activity; 
     getLocation(); 
    } 

和OpenActivity.class我实现的iCall:

public class OpenActivity extends AppCompatActivity implements TrackGPS.ICall 

改变呼吁TrackGPS对象:

gps = new TrackGPS(OpenActivity.this, (Activity)this); 

和覆盖方法:

@Override 
    public void call(Location location) { 
     //code to call 
    } 

我希望这可以成为一个人。