2012-02-01 64 views
0

下面是我準備好的代碼,它偵聽位置更新,一旦位置在指定區域內,它將連接到服務器並開始發送它的位置和時間戳,直到它退出該地區。android async任務正確使用ui線程

我被告知,不同的方法可能會壓出ui線程,並且我需要網絡連接在後臺或單獨的線程中運行,以防止應用程序中的速度變慢。

我正在閱讀有關android文檔中的Async Task

這裏是我的問題:

  1. 我想我需要放在一個單獨的線程中的部分應用程序決定了它是指定的區域(矩形),它試圖在瞬間內後連接併發送到服務器?

  2. 我該怎麼做?

    public class GpsActivity extends Activity { 
    
    private LocationManager lm; 
    private LocationListener locationListener; 
    public static TelephonyManager tm; 
    public static TextView tv; 
    public static Socket s; 
    public static PrintWriter out; 
    
    
    /** 
    * Called when the activity is first created. 
    */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    /** 
    * retrieve a reference to provide access to information about the telephony services on the device  
    */ 
    tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 
    setContentView(R.layout.main); 
    /** 
    * retrieve a reference to provide access to the system location services  
    */    
    lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);  
    
    
    /** 
        * explicitly select the provider, create a set of Criteria and let android choose the best provider available 
        */ 
    
        Criteria criteria = new Criteria(); 
        criteria.setAccuracy(Criteria.ACCURACY_FINE); 
        criteria.setAltitudeRequired(false); 
        criteria.setBearingRequired(false); 
        criteria.setCostAllowed(true); 
        criteria.setPowerRequirement(Criteria.POWER_LOW); 
        String provider = lm.getBestProvider(criteria, true); 
        /** 
        * This method takes in four parameters: 
        provider: The name of the provider with which you register 
        minTime: The minimum time interval for notifications, in milliseconds. 
        minDistance: The minimum distance interval for notifications, in meters. 
        listener: An object whose onLocationChanged() method will be called for each location update. 
        */ 
        locationListener = new MyLocationListener(); 
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); 
    
        tv = (TextView) findViewById(R.id.textView1); 
        tv.setText("I currently have no Location Data."); 
    
        } 
    
        /** 
        * Connects the Android Client to a given server 
        * 
        * @param name 
        *   The name of the remote server 
        * @param port 
        *   Port number to connect to at the remote server. 
        * @throws IOException 
        * @throws UnknownHostException 
        */ 
        public static void connect(String name, int port) 
        throws UnknownHostException, IOException 
    { 
    
    s = new Socket(name, port); 
    out = new PrintWriter(s.getOutputStream(), true); 
    } 
    
    /** 
    * Sends a string message to the server. 
    * 
    * @param msg 
    *   The message to be sent. 
    * @throws IOException 
    */ 
    public static void send(String msg) throws IOException 
    { 
    if (!s.isClosed() && msg != null) 
    { 
        out.println(msg); 
        if (msg.contains("CMD_QUIT")) 
        { 
         out.close(); 
         s.close(); 
         Log.i("ServerConnection", "Client Disconnected."); 
        } 
    } 
    } 
    
    //Used for receiving notifications from the LocationManager when the location has changed 
    
    private class MyLocationListener implements LocationListener{ 
    
    @Override 
    public void onLocationChanged(Location loc) { 
        String txt = "Latitude:" + loc.getLatitude() + "/nLongitude:" + loc.getLongitude(); 
        Log.i("GeoLocation", "My current location is:\n " + txt); 
        tv.setText("My current location is:\n" + txt); 
        final String msg = loc.getLongitude() + "\n" + loc.getLatitude() + "\n" 
         + loc.getTime(); 
    
    
        //determines if the location is within a designated area (rectangle) 
        double lat0 = 14.618572; 
        double long0 = 120.993816; 
        double lat1 = 14.619652; 
        double long1 = 120.992770; 
        double lat2 = 14.620285; 
        double long2 = 120.993451; 
        double lat3 = 14.619242; 
        double long3 = 120.994497; 
        double rel1 = (loc.getLongitude()- long0)*(lat1 - lat0)- ((loc.getLatitude()-lat0)*(long1-long0)); 
        double rel2 = (loc.getLongitude()- long1)*(lat2 - lat1)- ((loc.getLatitude()-lat1)*(long2-long1)); 
        double rel3 = (loc.getLongitude()- long2)*(lat3 - lat2)- ((loc.getLatitude()-lat2)*(long3-long2)); 
        double rel4 = (loc.getLongitude()- long3)*(lat0 - lat3)- ((loc.getLatitude()-lat3)*(long0-long3)); 
    
        // if yes, it will connect to server and send the location and timestamp 
    
    
        if (rel1 >= 0 && rel2 >= 0 && rel3 >= 0 && rel4 >= 0) 
        { 
    
         try 
         { 
         connect("IP address", 27960); 
         send("CMD_HELLO"); 
         send(msg); 
         tv.setText("Location is inside the road network...sending coordinates to server"); 
         send("CMD_QUIT"); 
         } catch (UnknownHostException e) 
         { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } catch (IOException e) 
         { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 
         } 
    
    
        else 
        { 
         tv.setText("Current location is outside the road network"); 
    
        } 
        } 
    
    
    
    
    
    @Override 
    public void onProviderDisabled(String provider) { 
        // TODO Auto-generated method stub 
    
    } 
    
    @Override 
    public void onProviderEnabled(String provider) { 
        // TODO Auto-generated method stub 
    
    } 
    
    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) { 
        // TODO Auto-generated method stub 
    
    } 
    
         } 
         } 
    

回答

0

之所以能夠做到這一點,它的工作遵循的tutorial

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
/** 
    * retrieve a reference to provide access to information about the telephony services on the device  
    */ 
    tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 
    setContentView(R.layout.main); 
/** 
    * retrieve a reference to provide access to the system location services  
    */    
lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);  


/** 
explicitly select the GPS provider, create a set of Criteria and let android choose 
the best provider available 
*/ 

Criteria criteria = new Criteria(); 
criteria.setAccuracy(Criteria.ACCURACY_FINE); 
criteria.setAltitudeRequired(false); 
criteria.setBearingRequired(false); 
criteria.setCostAllowed(true); 
criteria.setPowerRequirement(Criteria.POWER_LOW); 
String provider = lm.getBestProvider(criteria, true); 
/** 
* This method takes in four parameters: 
provider: The name of the provider with which you register 
minTime: The minimum time interval for notifications, in milliseconds. 
minDistance: The minimum distance interval for notifications, in meters. 
listener: An object whose onLocationChanged() method will be called for each location update. 
*/ 
locationListener = new MyLocationListener(); 
lm.requestLocationUpdates(provider, 1000, 1, locationListener); 

tv = (TextView) findViewById(R.id.textView1); 
tv.setText("I currently have no Location Data."); 

} 

/** 
* Connects the Android Client to a given server 
* 
* @param name 
*   The name of the remote server 
* @param port 
*   Port number to connect to at the remote server. 
* @throws IOException 
* @throws UnknownHostException 
*/ 
public static void connect(String name, int port) 
     throws UnknownHostException, IOException 
{ 

    s = new Socket(name, port); 
    out = new PrintWriter(s.getOutputStream(), true); 
} 

/** 
* Sends a string message to the server. 
* 
* @param msg 
*   The message to be sent. 
* @throws IOException 
*/ 
public static void send(String outmsg) throws IOException 
{ 
    if (!s.isClosed() && outmsg != null) 
    { 
     out.println(outmsg); 
     out.close(); 
     s.close(); 
     }} 



    //Used for receiving notifications from the LocationManager when the location has changed 

private class MyLocationListener implements LocationListener{ 


    @Override 
    public void onLocationChanged(Location loc) { 
     String txt = "Latitude:" + loc.getLatitude() + "/nLongitude:" + loc.getLongitude(); 
     Log.i("GeoLocation", "My current location is:\n " + txt); 
     tv.setText("My current location is:\n" + txt); 
     String msg=loc.getLongitude() + "\n" + loc.getLatitude() + "\n" 
     + loc.getTime(); 
     tv1 = (TextView) findViewById(R.id.textView2); 
     tv2 = (TextView) findViewById(R.id.textView3); 
     //determines if the location is within a designated area (rectangle) 
     double lat0 = 14.609794; 
     double long0 = 120.986018; 
     double lat1 = 14.608966; 
     double long1 = 120.986037; 
     double lat2 = 14.609031; 
     double long2 = 120.984991; 
     double lat3 = 14.609877; 
     double long3 = 120.985069; 
     double rel1 = (loc.getLongitude()- long0)*(lat1 - lat0)- ((loc.getLatitude()-lat0)*(long1-long0)); 
     double rel2 = (loc.getLongitude()- long1)*(lat2 - lat1)- ((loc.getLatitude()-lat1)*(long2-long1)); 
     double rel3 = (loc.getLongitude()- long2)*(lat3 - lat2)- ((loc.getLatitude()-lat2)*(long3-long2)); 
     double rel4 = (loc.getLongitude()- long3)*(lat0 - lat3)- ((loc.getLatitude()-lat3)*(long0-long3)); 

     // if yes, it will connect to server and send the location and timestamp 

     if (rel1 >= 0 && rel2 >= 0 && rel3 >= 0 && rel4 >= 0) 
     { 
      tv1.setText("Location is inside the road network..."); 
      **new connectSend().execute(msg);** 
      } 


     else 
     { 
      tv1.setText("Current location is outside the road network"); 

     } 
     } 

    @Override 
    public void onProviderDisabled(String provider) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onProviderEnabled(String provider) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) { 
     // TODO Auto-generated method stub 

    } 

    **public class connectSend extends AsyncTask<String, String, String>{ 

     @Override 
     protected String doInBackground(String... msg) { 
      // TODO Auto-generated method stub 
      String result; 

      try 
      { 
      connect("ip address", port); 

      send(msg[0]); 

      result = "SUCCESSFUL coordinates sent to server"; 

      } catch (UnknownHostException e) 
      { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
       result = "NOT SUCCESSFUL "; 
      } catch (IOException e) 
      { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
       result = "NOT SUCCESSFUL "; 
      } 
      return result;} 

     @Override 
     protected void onPostExecute(String result) { 
      // TODO Auto-generated method stub 
      super.onPostExecute(result); 
      tv2.setText("result"); 

      }** 


} 


    } 

} 
0

只是可以使用runnOnUIThread(Runnable R)來更改文本。

無論如何,使用AsyncTask更好,因爲在連接時不會凍結UI。