2016-07-08 13 views
0

私は、ユーザーの位置情報を取得する必要があるアプリを開発しています。 私のマシュマロ電話のようなGPS付きのデバイスで問題なく動作します。GPSセンサーなしのタブレットなどのAndroid搭載端末の地理的位置

私はまた、GPSなしのマシュマロ錠を持っています。 設定のプルダウンでは、ジオロケーションのオンとオフを切り替えるための位置アイコンが残っています。それはスイッチをオンにしたときに地図上に正しく表示されるので、同じ方法を使用したいと思います。 SIMカードもありませんので、ネットワークオペレータセルに依存しません。

私のタブレットでアプリを実行すると、アプリが明らかにクラッシュし、存在しないGPSセンサーを使用する許可を求めます。

チュートリアルの場所やタブレットの位置センサーの使い方の例を教えてもらえますか?私は多くの検索をしましたが、関連するものは見つかりませんでした。

また、次のクラスを修正する方法についていくつかのヒントを与えて、GPSが存在しない場合でも動作させることができますか?私は、関連するすべてのコードが第二コンストラクタであり、他のクラスは、ちょうど要求方法

の町や郵便番号をフォーマットするために使用されていると信じて「私の場所」、事前に非常に

public class GeolocationUtil implements LocationListener 
{ 
    // Public values to determine if first part of postcode has to be returned (in countries 
    // where it's in two parts separated by space) or full postcode 
    public static final boolean GET_FULL_POSTCODE = true; 
    public static final boolean GET_FIRST_PART_OF_POSTCODE = false; 

    private AppCompatActivity aca; 
    private TextView locationTV; 
    private GeolocationBean geolocation; 
    private boolean showFullPostcode; 

    /** 
    * 
    * Takes care of geolocation operations 
    * 
    * @param acaParam   activity requesting geolocation 
    * 
    * @param locationTVParam text view which will be updated with the town and postcode 
    *       of the device location 
    * 
    * @param geolocationParam bean which will be populated 
    * 
    */ 

    public GeolocationUtil (AppCompatActivity acaParam, TextView locationTVParam, 
         GeolocationBean geolocationParam) 
    { 
     this (acaParam, locationTVParam, geolocationParam, GET_FIRST_PART_OF_POSTCODE); 
    } 


    /** 
    * 
    * Takes care of geolocation operations 
    * 
    * @param acaParam    activity requesting geolocation 
    * 
    * @param locationTVParam  text view which will be updated with the town and postcode 
    *        of the device location 
    * 
    * @param geolocationParam  bean which will be populated 
    * 
    * @param showFullPostcodeParam parameter which lets users choose if the full postcode must be 
    *        displayed, or only the first part. Only works for countries in 
    *        which the postcode is made up by two parts separated by a space 
    * 
    */ 

    public GeolocationUtil (AppCompatActivity acaParam, TextView locationTVParam, 
         GeolocationBean geolocationParam, boolean showFullPostcodeParam) 
    { 
     boolean gpsSensorAvailable; 

     aca = acaParam; 
     locationTV = locationTVParam; 
     geolocation = geolocationParam; 
     showFullPostcode = showFullPostcodeParam; 

     // Find out if device location is coarse or fine 
     gpsSensorAvailable = hasGPSDevice (aca); 

     // Location variables which vary depending on presence or lack of GPS sensor. 
     // Default values for when it is not present, change if the device has it 

     String locationAccessType = Manifest.permission.ACCESS_COARSE_LOCATION; 
     String locationProviderType; 

     LocationManager locationManager = (LocationManager) aca.getSystemService (Context.LOCATION_SERVICE); 

     // Check app has permission to access GPS sensor 
     if (ActivityCompat.checkSelfPermission (aca, Manifest.permission.ACCESS_FINE_LOCATION) 
      != PackageManager.PERMISSION_GRANTED) 
     { 
      ActivityCompat.requestPermissions (aca, new String[] 
       { Manifest.permission.ACCESS_FINE_LOCATION }, 2); 
     } 

     // If the sensor is switched off, open settings page to switch it on 
     if (! locationManager.isProviderEnabled (LocationManager.GPS_PROVIDER)) 
     { 
      showSettingsAlert(); 
     } 
       locationManager.requestLocationUpdates (LocationManager.GPS_PROVIDER, 1000, 
      1, this); 
    } 


    /** 
    * Town/city and postcode of current location 
    * 
    * @param latitude latitude of required location and postcode 
    * @param longitude 
    * @return 
    * 
    */ 

    private String getTownAndPostcode (double latitude, double longitude) 
    { 
     String townAndPostcode = ""; 

      try 
      { 
       Geocoder geo = new Geocoder (aca, Locale.getDefault()); 
       List<Address> addresses = geo.getFromLocation (latitude, longitude, 1); 
       if (addresses.isEmpty()) 
       { 
        townAndPostcode = "@string/location_failed"; 
       } 
       else 
       { 
        if (addresses.size() > 0) 
        { 
         Address address = addresses.get (0); 

         // Town/city and first part of postcode if separated by space. 
         // To avoid having a slightly incorrect one, in the UK at least 

         if (showFullPostcode) 
         { 
          townAndPostcode = address.getLocality() + " " + address.getPostalCode(); 
         } 
         else 
         { 
          townAndPostcode = address.getLocality() + " " + address.getPostalCode().split ("\\s+")[ 0 ]; 
         } 
        } 
       } 
      } 
      catch (IOException ioe) 
      { 
       ioe.printStackTrace(); 
      } 
     return townAndPostcode; 
    } 


    // Determine if the device has a GPS sensor or not 

    private boolean hasGPSDevice (Context context) 
    { 
     final LocationManager mgr = (LocationManager) context.getSystemService (Context.LOCATION_SERVICE); 

     if (mgr == null) 
     { 
      return false; 
     } 

     final List <String> providers = mgr.getAllProviders(); 
     { 
      if (providers == null) return false; 
     } 

     return providers.contains (LocationManager.GPS_PROVIDER); 
    } 


    @Override 
    public void onLocationChanged (Location location) 
    { 
     double latitude = geolocation.getLatitude(); 
     double longitude = geolocation.getLongitude(); 

     // Only retrieve location once 
     if (location.getLatitude() != 0 || location.getLongitude() != 0) 
     { 
      geolocation.setLatitude (location.getLatitude()); 
      geolocation.setLongitude (location.getLongitude()); 

      String townAndPostcode = getTownAndPostcode (latitude, longitude); 

      locationTV.setText (townAndPostcode); 
      geolocation.setTownAndPostcode (townAndPostcode); 
     } 
    } 

    @Override 
    public void onProviderEnabled (String provider) { } 

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

    @Override 
    public void onProviderDisabled (String provider) { } 


    public void showSettingsAlert() 
    { 
     final Context context = aca.getApplicationContext(); 

     AlertDialog.Builder alertDialog = new AlertDialog.Builder (aca); 

     // Setting Dialog Title 
     alertDialog.setTitle ("Geolocation settings"); 

     // Setting Dialog Message 
     alertDialog.setMessage ("Geolocation sensor is switched off. Click on settings to switch it on, then back to return to the app"); 

     // Setting Icon to Dialog 
     //alertDialog.setIcon(R.drawable.delete); 

     // On pressing Settings button 
     alertDialog.setPositiveButton ("Settings", new DialogInterface.OnClickListener() 
     { 
      public void onClick (DialogInterface dialog, int which) 
      { 
       Intent intent = new Intent (Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
       intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK); 
       context.startActivity (intent); 
      } 
     }); 

     // on pressing cancel button 
     alertDialog.setNegativeButton ("Cancel", new DialogInterface.OnClickListener() 
     { 
      public void onClick (DialogInterface dialog, int which) 
      { 
       dialog.cancel(); 
      } 
     }); 

     // Showing Alert Message 
     alertDialog.show(); 
    } 
} 

答えて

0

は、解決策を見つけました。

まず、インターフェースと基本機能のアクティビティクラスと、アプリケーション全体でジオロケーションプロセスを利用できるようにジオロケーションutilクラスを使用していました。これは、AppCompatActivityメソッド(onRequestPermissionsResult)とLocationListenerメソッドをオーバーライドする必要があるため不可能です。

これですべてがアクティビティに入ります。これは、私のアプリケーションでのみ必要なすべてのコードなしでそれです:

public class RegistrationPersonalDataActivity extends AppCompatActivity implements LocationListener 
{ 
    private GeolocationBean geolocation; 

    private String locationProvider; 

    private LocationManager locationManager; 

    /** 
    * Prepare menu items, load previous entered data if present 
    * 
    * @param savedInstanceState data for screen restoration 
    * 
    */ 

    @Override 
    protected void onCreate (Bundle savedInstanceState) 
    { 
     super.onCreate (savedInstanceState); 
     setContentView (R.layout.activity_registration_personal_data); 

     locationManager = (LocationManager) getSystemService (Context.LOCATION_SERVICE); 

     if (deviceHasGpsSensor()) 
     { 
      locationProvider = LocationManager.GPS_PROVIDER; 
     } 
     else 
     { 
      locationProvider = LocationManager.NETWORK_PROVIDER; 
     } 
    } 


    /** 
    * 
    * if permission to access location (GPS or network, according to availability) is granted, 
    * location update listener is registered and checks if location provider is switched on 
    * 
    * @param requestCode the code of the request 
    * 
    * @param permissions an array of strings with the permission 
    * 
    * @param grantResults an array with the corresponding results 
    * 
    */ 

    @Override 
    public void onRequestPermissionsResult (int requestCode, @NonNull String[] permissions, int[] grantResults) 
    { 
     for (int i = 0; i < permissions.length; i++) 
     { 
      String permission = permissions[i]; 
      int grantResult = grantResults[i]; 

      if (permission.equals (Manifest.permission.ACCESS_FINE_LOCATION) && grantResult == 0) 
      { 
       try 
       { 
        locationManager.requestLocationUpdates (locationProvider, 1000, 
         1, this); 

        if (! locationManager.isProviderEnabled (locationProvider)) 
        { 
         showSettingsAlert(); 
        } 
       } 
       catch (SecurityException se) 
       { 
        // It won't happen, this checked exception is mandatory for 
       // location updates, but it's inside a method that verifies it 
       } 
      } 
     } 
    } 

    /** 
    * triggers the geolocating process 
    * 
    * @param view "Locate me" button 
    * 
    */ 

    public void getGpsLocation (View view) 
    { 
     locationTV.setText (R.string.please_wait); 

     // Check app has permission to access GPS sensor 
     if (ActivityCompat.checkSelfPermission (this, Manifest.permission.ACCESS_FINE_LOCATION) 
      != PackageManager.PERMISSION_GRANTED) 
     { 
      ActivityCompat.requestPermissions (this, new String[] 
       { Manifest.permission.ACCESS_FINE_LOCATION }, 2); 
     } 
    } 


    // Goes through the steps required by the geoloation process 

    private void setLocationProcess (GeolocationBean geolocationBean) 
    { 
     if (geolocationBean.getLatitude() != 0 || geolocationBean.getLongitude() != 0) 
     { 
      locationTV.setText (geolocationBean.getTownAndPostcode()); 
      geolocation = geolocationBean; 
     } 
    } 


    // Opens a dialog asking the user to switch on the device location method if it already isn't 

    private void showSettingsAlert() 
    { 
     final Context context = this.getApplicationContext(); 
     AlertDialog.Builder alertDialog = new AlertDialog.Builder (RegistrationPersonalDataActivity.this); 

     // Title 
     alertDialog.setTitle ("Geolocation settings"); 

     // Message 
     alertDialog.setMessage ("Geolocation sensor is switched off. Click on settings to switch it on, then back to return to the app"); 

     // On pressing Settings button 
     alertDialog.setPositiveButton ("Settings", new DialogInterface.OnClickListener() 
     { 
      public void onClick (DialogInterface dialog, int which) 
      { 
       Intent intent = new Intent (Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
       intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK); 
       context.startActivity (intent); 
      } 
     }); 

     // on pressing cancel button 
     alertDialog.setNegativeButton ("Cancel", new DialogInterface.OnClickListener() 
     { 
      public void onClick (DialogInterface dialog, int which) 
      { 
       dialog.cancel(); 
      } 
     }); 

     // Showing Alert Message 
     alertDialog.show(); 
    } 


    // Determine if the device has a GPS sensor or not 

    private boolean deviceHasGpsSensor() 
    { 
     if (locationManager == null) 
     { 
      return false; 
     } 

     final List<String> providers = locationManager.getAllProviders(); 
     { 
      if (providers == null) return false; 
     } 

     return providers.contains (LocationManager.GPS_PROVIDER); 
    } 


    /** 
    * 
    * is called when the location changes or at regular intervals 
    * 
    * @param location the location with latitude and longitude 
    * 
    */ 

    @Override 
    public void onLocationChanged (Location location) 
    { 
     double latitude = geolocation.getLatitude(); 
     double longitude = geolocation.getLongitude(); 

     geolocation.setLatitude (location.getLatitude()); 
     geolocation.setLongitude (location.getLongitude()); 

     String townAndPostcode = getTownAndPostcode (latitude, longitude); 

     locationTV.setText (townAndPostcode); 
     geolocation.setTownAndPostcode (townAndPostcode); 
    } 


    /** 
    * 
    * is called when the location sensor is switched on 
    * 
    * @param provider the location provider 
    * 
    */ 

    @Override 
    public void onProviderEnabled (String provider) 
    { 
     try 
     { 
      locationManager.requestLocationUpdates (locationProvider, 1000, 
       1, this); 
     } 
     catch (SecurityException se) 
     { 
      new ExceptionLoggingUtil (se); 
     } 
    } 


    /** 
    * 
    * is called when the location sensor is switched on or off 
    * 
    * @param provider the location provider 
    * 
    * @param status the new status 
    * 
    * @param extras absolutely no idea 
    * 
    */ 

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


    /** 
    * 
    * is called when the location sensor is switched off 
    * 
    * @param provider the location provider 
    * 
    */ 

    @Override 
    public void onProviderDisabled (String provider) { } 
} 
1

をありがとうこの機能はセルタワー技術で機能します。あなたのオペレータのセルタワーは、それがどこにあるのかを特定するための固有のコードを生成します。だから、基本的に私のロケーション機能は、あなたがレセプションを受ける場所からセルタワーの場所を指摘しています。シンプル!

私たちが行う必要があるのは、これらのコードを取得し、電子メール/ IM/SMS経由でコンピュータに送信し、それらをGoogleマップに入力することだけです。このようにして、デバイスのおおよその位置を追跡することができます。

これを試してみてください:誰もが彼/彼女自身が同じ問題を抱えて見つける必要がありLocating current position in android without GPS

+0

MattiaGit、クイックアンサーに感謝します。申し訳ありませんが、私は自分のタブレットにはSIMカードがないと言い足りないので、代わりにWiFiに依存しているとしか思えません。 WiFi名、またはルータに割り当てられたIPアドレス。だから、それは場所を決定する別の方法を持っている必要があります。私はちょうど元の投稿にこの詳細を追加しました – Dan

+0

リンクのおかげで、私はすぐにそれを試してみます – Dan

+1

はい、あなたのタブレットにSIMを持っていない場合、AndroidはIP地理位置を取る。残念ながら時々場所が間違っています... – MattiaGit

関連する問題