2011-08-31 31 views
1

我的好奇的问题是,在我的应用程序中,GPS定位需要相当长的时间(因为它倾向于这样做),因此我想将它作为自己的线程运行,而用户在其他视图中进行选择。在Android的后台线程中运行GPS定位

我的结构是,我有一个“主”视图,它始终在后台处于活动状态,然后向用户显示一系列他或她做出几个选择的视图。最后,根据所作出的选择和当前位置向用户呈现结果。所有这些工作,但我想要将GPS位移动到它自己的线程,以便用户不必等待它完成。

所有用户的选择和GPS坐标存储在一个名为CurrentLogEntry的单例中。程序不同部分之间的所有通信都是通过它执行的。

我创建在主视图中的handleMessage(Message msg)覆盖,然后我实现在Main.java此功能:

void startGPSThread() { 
    Thread t = new Thread() { 

     LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);  
     boolean isDebug = CurrentLogEntry.getInstance().isDebug(); 

     // Define a listener that responds to location updates 
     LocationListener locationListener = new LocationListener() { 

      public void onStatusChanged(String provider, int status, Bundle extras) { 
       /* This is called when the GPS status changes */ 
       String tag = "onStatusChanged, "; 
       switch (status) { 
        case LocationProvider.OUT_OF_SERVICE: 
         Log.w(tag, "Status Changed: Out of Service"); 
         break; 
        case LocationProvider.TEMPORARILY_UNAVAILABLE: 
         Log.w(tag, "Status Changed: Temporarily Unavailable"); 
         break; 
        case LocationProvider.AVAILABLE: 
         break; 
       } 
      } 

      public void onProviderEnabled(String provider) { 
      } 

      public void onProviderDisabled(String provider) { 
       // This is called if the GPS is disabled in settings. 
       // Bring up the GPS settings 
       Intent intent = new Intent(
         android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
       startActivity(intent); 
      } 

      public void onLocationChanged(Location location) { 

       // Once a location has been received, ignore all other position 
       // updates. 
       locationManager.removeUpdates(locationListener); 
       locationManager.removeUpdates(this); 

       // Make sure that the received location is a valid one, 
       // otherwise show a warning toast and hit "back". 
       if (location == null) { 
        String warningString = "Location was unititialized!"; 

        if (isDebug) { 
         Toast.makeText(getApplicationContext(), 
           warningString, 
           Toast.LENGTH_LONG).show(); 
        } 

        KeyEvent kev = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK); 
        onKeyDown(KeyEvent.KEYCODE_BACK, kev); 
       } 

       CurrentLogEntry.getInstance().setUserLatitude(location.getLatitude()); 
       CurrentLogEntry.getInstance().setUserLongitude(location.getLongitude()); 

       //Send update to the main thread 
       int result = 0; 
       if (location.getLatitude() == 0 || location.getLongitude() == 0) { 
        result = -1; 
       } 

       messageHandler.sendMessage(Message.obtain(messageHandler, result)); 
      } 
     }; 

     @Override 
     public void run() { 

      locationManager.requestLocationUpdates(
        LocationManager.GPS_PROVIDER, 0, 0, locationListener); 

      // Wait until a position has bee acquired. 
      while(!CurrentLogEntry.getInstance().isReadyToCalculate()){ 
       try { 
        wait(250); 
       } catch (InterruptedException ex) { 
        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
       } 
      } 
     } 
    }; 

    t.start(); 
} 

调用该函数在Main.onCreate()

不幸的是,这根本不起作用。该程序崩溃,只要它达到locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);,这让我完全陷入困境。

任何人都可以启发我为什么这不会作为后台线程运行?另外,我最终是否真的需要等待轮询来确保线程保持活动状态直到它接收到它的数据?在我想把它放在自己的线程中之前,GPS位工作得很好,那么我在做什么错了?

+0

你可以发布错误日志吗? – PedroAGSantos

+0

我很想去,但没有。我得到的只是“应用程序意外停止,请重试。” Netbeans不给我任何输出。编辑:是否有其他输出,我错过了? –

+0

Netbeans调试器控制台仅包含有关我的断点和“用户程序正在运行 用户程序已完成”的消息。 –

回答

0

从我理解你必须使线程循环线程为了在后台运行位置更新...但是我仍然试图找出自己...当我弄清楚如何做到这一点我会发布它。

可能有,我接受,这是在线程其中Looper.prepare()没有被调用

希望你得到它的工作芽不能创建处理程序

0

检查this线程同样的错误并专门为this回答。它们处理相同的主题,位置和相同的问题,从Thread循环中运行它。