4

ボタンをクリックして現在地を更新しようとしています。位置情報は、GPSまたはセルタワーのいずれか利用可能な方を介して取得できます。私の問題は、「ロード画面」が表示されないことです。座標がゼロのままで、何かが即座に現れたり閉じたりするように見えることを私は知っています。誰かが私を助けることができます-私が下で間違っていることは何ですか?

場所は更新されず、ロード画面も表示されません。ロード画面がなく、「更新ボタン」を複数回クリックすることで、場所を取得できます。以下は、「更新ボタン」のクリックを処理するための私のコードです。

FieldChangeListener refreshImgListener = new FieldChangeListener() {   
    public void fieldChanged(Field field, int context) 
    {
        Thread backgroundWorker = new Thread(new Runnable() {
            public void run() {
                refreshCoordinates();
            }
        });
        busyDialog.setEscapeEnabled(false);  
        busyDialog.show();
        backgroundWorker.start();
    }
};

そして私のrefreshCoordinates()方法は以下の通りです:

public void refreshCoordinates() {
    do
    {
        getLatitude(handleeGPS.latitude);
        getLongitude(handleeGPS.longitude);
    } while ((longi == "0.0" || lati == "0.0") || (longi.length() == 0 || lati.length()==0));

    UiApplication.getUiApplication().invokeLater( new Runnable()
    {
        public void run ()
        {
            lblLatitude.setText(lati);
            lblLongitude.setText(longi);
            busyDialog.cancel();
        }
    } );
}

public static String getLatitude(double value) 
{
    lati= Double.toString(value);
    return lati;
}
public static String getLongitude(double value) 
{
    longi= Double.toString(value);
    return longi;
}

緯度と経度の値を返すクラス:

public class handleeGPS{

    static GPSThread gpsThread;
    public static double latitude;
    public static double longitude;

    public handleeGPS(){
        gpsThread = new GPSThread();
        gpsThread.start();
    }

    private static class GPSThread extends Thread{
        public void run() {
            Criteria myCriteria = new Criteria();
            myCriteria.setCostAllowed(false);
            int m_bbHandle = CodeModuleManager.getModuleHandle("net_rim_bb_lbs");
            if(m_bbHandle>0){
                try {
                    int cellID = GPRSInfo.getCellInfo().getCellId();
                    int lac = GPRSInfo.getCellInfo().getLAC();
                    String urlString2 = "http://www.google.com/glm/mmap";
                    // Open a connection to Google Maps API
                    ConnectionFactory connFact = new ConnectionFactory();
                    ConnectionDescriptor connDesc;
                    connDesc = connFact.getConnection(urlString2);
                    HttpConnection httpConn2;
                    httpConn2 = (HttpConnection)connDesc.getConnection();
                    httpConn2.setRequestMethod("POST");
                    // Write some custom data to Google Maps API
                    OutputStream outputStream2 = httpConn2.openOutputStream();//getOutputStream();
                    WriteDataGoogleMaps(outputStream2, cellID, lac);
                    // Get the response
                    InputStream inputStream2 = httpConn2.openInputStream();//getInputStream();
                    DataInputStream dataInputStream2 = new DataInputStream(inputStream2);
                    // Interpret the response obtained
                    dataInputStream2.readShort();
                    dataInputStream2.readByte();
                    int code = dataInputStream2.readInt();
                    //Dialog.alert(code+"");
                    if (code == 0) {
                        latitude= dataInputStream2.readInt() / 1000000D;
                        longitude=dataInputStream2.readInt() / 1000000D;
                        //Dialog.alert(latitude+"-----"+longitude);
                        dataInputStream2.readInt();
                        dataInputStream2.readInt();
                        dataInputStream2.readUTF();
                    } else {
                        System.out.println("Error obtaining Cell Id ");
                    }
                    outputStream2.close();
                    inputStream2.close();
                } catch (Exception e) {
                    System.out.println("Error: " + e.getMessage());
                }
            } else {
                try {
                    LocationProvider myLocationProvider = LocationProvider.getInstance(myCriteria);
                    try {
                        Location myLocation = myLocationProvider.getLocation(300);
                        latitude  = myLocation.getQualifiedCoordinates().getLatitude();
                        longitude = myLocation.getQualifiedCoordinates().getLongitude();
                        if(latitude==0.0 && longitude==0.0){
                            try {
                                int cellID = GPRSInfo.getCellInfo().getCellId();
                                int lac = GPRSInfo.getCellInfo().getLAC();
                                String urlString2 = "http://www.google.com/glm/mmap";
                                // Open a connection to Google Maps API
                                ConnectionFactory connFact = new ConnectionFactory();
                                ConnectionDescriptor connDesc;
                                connDesc = connFact.getConnection(urlString2);
                                HttpConnection httpConn2;
                                httpConn2 = (HttpConnection)connDesc.getConnection();
                                httpConn2.setRequestMethod("POST");
                                // Write some custom data to Google Maps API
                                OutputStream outputStream2 = httpConn2.openOutputStream();
                                //getOutputStream();
                                WriteDataGoogleMaps(outputStream2, cellID, lac);
                                // Get the response
                                InputStream inputStream2 = httpConn2.openInputStream();
                                //getInputStream();
                                DataInputStream dataInputStream2 = new DataInputStream(inputStream2);
                                // Interpret the response obtained
                                dataInputStream2.readShort();
                                dataInputStream2.readByte();
                                int code = dataInputStream2.readInt();
                                //Dialog.alert(code+"");
                                if (code == 0) {
                                    latitude= dataInputStream2.readInt() / 1000000D;
                                    longitude=dataInputStream2.readInt() / 1000000D;
                                    //Dialog.alert(latitude+"-----"+longitude);
                                    dataInputStream2.readInt();
                                    dataInputStream2.readInt();
                                    dataInputStream2.readUTF();
                                } else {
                                    System.out.println("Error obtaining Cell Id ");
                                }
                                outputStream2.close();
                                inputStream2.close();
                            } catch (Exception e) {
                                System.out.println("Error: " + e.getMessage());
                            }
                        }
                    }
                    catch ( InterruptedException iex ) {
                        return;
                    }
                    catch ( LocationException lex ) {
                        return;
                    }
                } catch ( LocationException lex ) {
                    return;
                }
            }
            return;
        }
    }

    private static void WriteDataGoogleMaps(OutputStream out, int cellID, int lac)
    throws IOException {
        DataOutputStream dataOutputStream = new DataOutputStream(out);
        dataOutputStream.writeShort(21);
        dataOutputStream.writeLong(0);
        dataOutputStream.writeUTF("en");
        dataOutputStream.writeUTF("Android");
        dataOutputStream.writeUTF("1.0");
        dataOutputStream.writeUTF("Web");
        dataOutputStream.writeByte(27);
        dataOutputStream.writeInt(0);
        dataOutputStream.writeInt(0);
        dataOutputStream.writeInt(3);
        dataOutputStream.writeUTF("");
        dataOutputStream.writeInt(cellID);
        dataOutputStream.writeInt(lac);
        dataOutputStream.writeInt(0);
        dataOutputStream.writeInt(0);
        dataOutputStream.writeInt(0);
        dataOutputStream.writeInt(0);
        dataOutputStream.flush();
    }
}
4

3 に答える 3

5

さて、私の元の答えは有効でしたが、あなたが投稿した新しいコードにはいくつかの異なる問題があるので、2番目の答えを投稿しています。正しく見えないことがたくさんあったので、handleeGPSクラスを書き直しました。私が行った主な変更を1つずつ説明します。

  1. Javaの命名規則を使用してみてください。これにより、私たちがあなたを助けやすくなります。handleeGPSコードをクラスに投稿する前は、変数ではなく小文字の名前が通常使用されるため、変数だと思っていました。

  2. コードの重複は避けてください。handleeGPSクラスには読み通すコードがたくさんありましたが、そのほとんどは、2か所で複製したGoogleのウェブサービスから場所を取得するためのコードでした。そのコードのみを含むメソッドを作成し、それを2回呼び出すだけです。

  3. handleeGPSクラスの名前をに変更しましたGPSHandlerhandleeエラーだったのか、それともあなたが使った別の言語の単語なのかはわかりません。とにかく、名前は少なくとも大文字で始まる必要があります。

  4. static多くの変数とメソッドを避けてください。時々、本当に何かが1つしかないはずです。デバイスにはGPSシステムが1つしかないため、GPS処理クラスはおそらくその良い例です。ただし、このコード構造を強制するために、すべてを。としてマークしないでくださいstaticクラスをシングルトンにするだけです。これには、1つのstaticメンバー変数(_instance)と1つの静的メソッド( )のみが作成されgetInstance()ます。私のコードでは、次のようにクラスにアクセスしますGPSHandler gps = GPSHandler.getInstance();

  5. BBマップがインストールされているかどうかのチェックは、実際には逆方向だったと思います。モジュールを検索し、net_rim_bb_lbsそれがゼロより大きい場合(つまり、BBマップがインストールされている場合)、GoogleWebサービスに直接アクセスしました。逆にしたいと思います(BBマップがインストールされている場合はデバイスのGPSを試してください)。また、6.0以降はnet_rim_bb_maps、もチェックする必要があります。

  6. アップデートを投稿する前は、あなたgetLatitude()getLongitude()メソッドが実際にデバイスの場所を取得していると思いました。それは私の側の悪い仮定でした。彼らはただ数字を文字列に変換していました。したがって、バックグラウンドで(を使用して)実行する理由はありませんThread。あなたはすでにhandleeGPSバックグラウンドスレッドを使用するようにクラスを作成しました。これは良いことです。1つのバックグラウンドスレッドで十分です。位置情報を使用するUIには、背景も必要ありませんThreadGPSListenerコードを変更してインターフェースを追加しました。そのインターフェースは、位置情報の更新を受信するために、UIコードによって実装される必要があります。場所が{0.0、0.0}に等しくないかどうかを尋ねて、ループを続ける理由はありません。それは非効率的です。私のコードでは、場所が変更されたときに通知が届きます。

  7. 元のコードはスレッドセーフではありませんでした。および変数はバックグラウンドスレッドhandleeGPS latitudelongitude設定され、UIスレッドでアクセスされました。それは安全ではありません。2つのスレッドが同じデータを同時に読み書きすることはできません。位置データをにプッシュするようにコードを変更することGPSListenerで、この問題を回避します。

  8. Dialog.alert()クラス内にあるコードのコメントを外しましたhandleeGPSが、バックグラウンドからUI呼び出しを行うことは許可されていないため、機能しませんでした。UiApplication.getUiApplication().invokeLater()私はそれらを安全にするためにそれらの呼び出しを囲みました。

このクラスを使用するには、UIコードのどこかで、を使用してメソッドThreadを実行する代わりに、次のようにします。refreshCoordinates()

public void fieldChanged(Field field, int context) 
    // this is called when your location refresh button is clicked
    GPSHandler.getInstance().setListener(this); 
    GPSHandler.getInstance().requestLocationUpdates();
    busyDialog.setEscapeEnabled(false);  
    busyDialog.show();
}

..。

public void onLocationReceived(Coordinates location) {
    lblLatitude.setText(Double.toString(location.getLatitude()));               
    lblLongitude.setText(Double.toString(location.getLongitude()));               
    busyDialog.cancel();               
}     

そのコードを配置するクラス(上記)もimplements GPSListener、ここで定義されているインターフェイスであることを確認してください。

public interface GPSListener {
    public void onLocationReceived(Coordinates location);
}

そして最後にGPSHandler

public class GPSHandler { 

   private GPSThread _gpsThread;
   private Coordinates _location;
   private boolean _gotLocation;
   private GPSListener _listener;

   /** this class will be a Singleton, as the device only has one GPS system */
   private static GPSHandler _instance;

   /** @return the Singleton instance of the GPSHandler */
   public static GPSHandler getInstance() {
      if (_instance == null) {
         _instance = new GPSHandler();
      }
      return _instance;
   }

   /** not publicly accessible ... use getInstance() */
   private GPSHandler() { 
   }

   /** call this to trigger a new location fix */
   public void requestLocationUpdates() {
       if (_gpsThread == null || !_gpsThread.isAlive()) {
          _gpsThread = new GPSThread();
          _gpsThread.start(); 
       }
   }

   public void setListener(GPSListener listener) {
      // only supports one listener this way
      _listener = listener;   
   }

   private void setLocation(final Coordinates value) {
      _location = value;
      if (value.getLatitude() != 0.0 || value.getLongitude() != 0.0) {
         _gotLocation = true;
         if (_listener != null) {
            // this assumes listeners are UI listeners, and want callbacks on the UI thread:
            UiApplication.getUiApplication().invokeLater(new Runnable() {
               public void run() {
                  _listener.onLocationReceived(value);
               }
            });
         }
      }
   }

   private class GPSThread extends Thread {

      private void getLocationFromGoogle() {
         try { 
            int cellID = GPRSInfo.getCellInfo().getCellId(); 
            int lac = GPRSInfo.getCellInfo().getLAC(); 

            String urlString2 = "http://www.google.com/glm/mmap"; 

            // Open a connection to Google Maps API  
            ConnectionFactory connFact = new ConnectionFactory(); 
            ConnectionDescriptor connDesc; 
            connDesc = connFact.getConnection(urlString2); 

            HttpConnection httpConn2; 
            httpConn2 = (HttpConnection)connDesc.getConnection(); 
            httpConn2.setRequestMethod("POST"); 

            // Write some custom data to Google Maps API  
            OutputStream outputStream2 = httpConn2.openOutputStream();//getOutputStream(); 
            writeDataGoogleMaps(outputStream2, cellID, lac); 

            // Get the response   
            InputStream inputStream2 = httpConn2.openInputStream();//getInputStream(); 
            DataInputStream dataInputStream2 = new DataInputStream(inputStream2); 

            // Interpret the response obtained  
            dataInputStream2.readShort(); 
            dataInputStream2.readByte(); 

            final int code = dataInputStream2.readInt(); 
            UiApplication.getUiApplication().invokeLater(new Runnable() {
               public void run() {
                  Dialog.alert(code + "");   
               }
            });                        

            if (code == 0) { 
               final double latitude = dataInputStream2.readInt() / 1000000D; 
               final double longitude = dataInputStream2.readInt() / 1000000D; 
               setLocation(new Coordinates(latitude, longitude, 0.0f));

               UiApplication.getUiApplication().invokeLater(new Runnable() {
                  public void run() {
                     Dialog.alert(latitude+"-----"+longitude);   
                  }
               });

               dataInputStream2.readInt(); 
               dataInputStream2.readInt(); 
               dataInputStream2.readUTF(); 
            } else { 
               System.out.println("Error obtaining Cell Id "); 
            } 
            outputStream2.close(); 
            inputStream2.close(); 
         } catch (Exception e) { 
            System.out.println("Error: " + e.getMessage()); 
         } 
      }

      private void tryGetLocationFromDevice() {
         _gotLocation = false;
         try {
            Criteria myCriteria = new Criteria(); 
            myCriteria.setCostAllowed(false); 
            LocationProvider myLocationProvider = LocationProvider.getInstance(myCriteria); 

            try { 
               Location myLocation = myLocationProvider.getLocation(300); 
               setLocation(myLocation.getQualifiedCoordinates()); 
            } catch ( InterruptedException iex ) { 
               System.out.println(iex.getMessage());
            } catch ( LocationException lex ) { 
               System.out.println(lex.getMessage());
            } 
         } catch ( LocationException lex ) { 
            System.out.println(lex.getMessage());
         }

         if (!_gotLocation) { 
            getLocationFromGoogle();
         } 
      }

      public void run() { 
         int bbMapsHandle = CodeModuleManager.getModuleHandle("net_rim_bb_lbs");    // OS < 6.0
         int bbMapsHandle60 = CodeModuleManager.getModuleHandle("net_rim_bb_maps"); // OS 6.0+
         if (bbMapsHandle > 0 || bbMapsHandle60 > 0) { 
            tryGetLocationFromDevice();
         } else {
            getLocationFromGoogle();
         }
      } 
   } 

   private void writeDataGoogleMaps(OutputStream out, int cellID, int lac) throws IOException { 
      DataOutputStream dataOutputStream = new DataOutputStream(out); 
      dataOutputStream.writeShort(21); 
      dataOutputStream.writeLong(0); 
      dataOutputStream.writeUTF("en"); 
      dataOutputStream.writeUTF("Android"); 
      dataOutputStream.writeUTF("1.0"); 
      dataOutputStream.writeUTF("Web"); 
      dataOutputStream.writeByte(27); 
      dataOutputStream.writeInt(0); 
      dataOutputStream.writeInt(0); 
      dataOutputStream.writeInt(3); 
      dataOutputStream.writeUTF(""); 

      dataOutputStream.writeInt(cellID); 
      dataOutputStream.writeInt(lac); 

      dataOutputStream.writeInt(0); 
      dataOutputStream.writeInt(0); 
      dataOutputStream.writeInt(0); 
      dataOutputStream.writeInt(0); 
      dataOutputStream.flush(); 
   } 

} 
于 2012-08-15T03:02:20.903 に答える
2

見えないコードがたくさんあります(例getLatitude()、、getLongitude()refreshDetails()。したがって、そこで何か問題が発生している可能性があります。また、投稿したコードにロード画面が表示されないため、なぜ表示されないのかわかりません。

しかし、ここに正しく見えないものがあります:

        synchronized (Application.getEventLock())
        {
            busyDialog.show();
        }

このBlackBerryフォーラムの質問を読むと、メイン(UI)スレッドからのアプリケーションイベントロックで同期しようとすると、アプリがフリーズする可能性があることがわかります。このpublic void fieldChanged(Field field, int context)メソッドは常にUIスレッドで呼び出されます。これは、ボタンのクリックを監視し、のようなクリックハンドラーを呼び出すUIスレッドであるためfieldChanged()です。

また、アプリケーションのBlackBerry APIドキュメントを読むこともできます。これは、メイン(別名UI )スレッドではなく、ワーカー(バックグラウンドとも呼ばれる)スレッドgetEventLock()用であることを説明しています。

したがって、UIスレッドですでに実行されているコードでは、イベントロックを取得するために特別な手法を使用する必要はありません。上記のコードの代わりに、次のようにします。

            busyDialog.show();

これらのテクニックの両方:

        synchronized (Application.getEventLock())
        {
            busyDialog.show();
        }

また

        UiApplication.getUiApplication().invokeLater(new Runnable() {
            public void run() {
               busyDialog.show();  
            }
        });

バックグラウンドスレッドからUIメソッドを安全に呼び出す方法です。ただし、UIスレッドですでに実行されていることがわかっているコードでそれらを使用するべきではありません。

それを修正してみて、問題がなくなるかどうかを確認してください。

編集:また、コードは場所を更新する前にユーザー名とパスワードをチェックしています。それは本当にあなたが望むものですか?これはあなたの問題とは何の関係もないと思いますが、通常、位置情報サービスにアクセスするためにユーザー名やパスワードは必要ないと思います。もちろん、私はあなたのアプリケーションを知らないので、これは本当に私の側のコメントにすぎません。

于 2012-08-14T07:38:40.727 に答える
2

私はあなたが簡単な答えはここでエラーだと思います:

((longi == "0.0" || lati == "0.0") || (longi.length() == 0 || lati.length()==0));

演算子String.equals()の代わりに使用する必要があります。==

最初の呼び出しの後longi、価値latiがあり"0.0"ます。ただし、デフォルトで参照を比較し、オブジェクトが異なるため参照が異なるため、==戻ります。false

于 2012-08-14T12:12:55.313 に答える