1

我做了一個簡單的TCP客戶機TCP-IP客戶端,它是當我使用簡單的活動和按鈕發送消息Android系統如何實現內部intentservice

現在我實現了地理圍欄應用程序中使用同一個Google地理圍欄例子做工精細這裏

public class GeofenceTransitionsIntentService extends IntentService { 

protected static final String TAG = "GeofenceTransitionsIS"; 

/** 
* This constructor is required, and calls the super IntentService(String) 
* constructor with the name for a worker thread. 
*/ 
public GeofenceTransitionsIntentService() { 
    // Use the TAG to name the worker thread. 
    super(TAG); 
} 

@Override 
public void onCreate() { 
    super.onCreate(); 
} 

/** 
* Handles incoming intents. 
* @param intent sent by Location Services. This Intent is provided to Location 
*    Services (inside a PendingIntent) when addGeofences() is called. 
*/ 
@Override 
protected void onHandleIntent(Intent intent) { 
    GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent); 
    if (geofencingEvent.hasError()) { 
     String errorMessage = GeofenceErrorMessages.getErrorString(this, 
       geofencingEvent.getErrorCode()); 
     Log.e(TAG, errorMessage); 
     return; 
    } 

    // Get the transition type. 
    int geofenceTransition = geofencingEvent.getGeofenceTransition(); 

    // Test that the reported transition was of interest. 
    if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || 
      geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) { 

     // Get the geofences that were triggered. A single event can trigger multiple geofences. 
     List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences(); 

     // Get the transition details as a String. 
     String geofenceTransitionDetails = getGeofenceTransitionDetails(
       this, 
       geofenceTransition, 
       triggeringGeofences 
     ); 

     // Send notification and log the transition details. 
     sendNotification(geofenceTransitionDetails); 
     Log.i(TAG, geofenceTransitionDetails); 
    } else { 
     // Log the error. 
     Log.e(TAG, getString(R.string.geofence_transition_invalid_type, geofenceTransition)); 
    } 
} 

/** 
* Gets transition details and returns them as a formatted string. 
* 
* @param context    The app context. 
* @param geofenceTransition The ID of the geofence transition. 
* @param triggeringGeofences The geofence(s) triggered. 
* @return      The transition details formatted as String. 
*/ 
private String getGeofenceTransitionDetails(
     Context context, 
     int geofenceTransition, 
     List<Geofence> triggeringGeofences) { 

    String geofenceTransitionString = getTransitionString(geofenceTransition); 

    // Get the Ids of each geofence that was triggered. 
    ArrayList triggeringGeofencesIdsList = new ArrayList(); 
    for (Geofence geofence : triggeringGeofences) { 
     triggeringGeofencesIdsList.add(geofence.getRequestId()); 
    } 
    String triggeringGeofencesIdsString = TextUtils.join(", ", triggeringGeofencesIdsList); 

    return geofenceTransitionString + ": " + triggeringGeofencesIdsString; 
} 

/** 
* Posts a notification in the notification bar when a transition is detected. 
* If the user clicks the notification, control goes to the MainActivity. 
*/ 
private void sendNotification(String notificationDetails) { 
    // Create an explicit content Intent that starts the main Activity. 
    Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class); 

    // Construct a task stack. 
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); 

    // Add the main Activity to the task stack as the parent. 
    stackBuilder.addParentStack(MainActivity.class); 

    // Push the content Intent onto the stack. 
    stackBuilder.addNextIntent(notificationIntent); 

    // Get a PendingIntent containing the entire back stack. 
    PendingIntent notificationPendingIntent = 
      stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); 

    // Get a notification builder that's compatible with platform versions >= 4 
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this); 

    // Define the notification settings. 
    builder.setSmallIcon(R.drawable.ic_launcher) 
      // In a real app, you may want to use a library like Volley 
      // to decode the Bitmap. 
      .setLargeIcon(BitmapFactory.decodeResource(getResources(), 
        R.drawable.ic_launcher)) 
      .setColor(Color.RED) 
      .setContentTitle(notificationDetails) 
      .setContentText(getString(R.string.geofence_transition_notification_text)) 
      .setContentIntent(notificationPendingIntent); 

    // Dismiss notification once the user touches it. 
    builder.setAutoCancel(true); 

    // Get an instance of the Notification manager 
    NotificationManager mNotificationManager = 
      (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 

    // Issue the notification 
    mNotificationManager.notify(0, builder.build()); 
} 

/** 
* Maps geofence transition types to their human-readable equivalents. 
* 
* @param transitionType A transition type constant defined in Geofence 
* @return     A String indicating the type of transition 
*/ 
private String getTransitionString(int transitionType) { 
    switch (transitionType) { 
     case Geofence.GEOFENCE_TRANSITION_ENTER: 
      return getString(R.string.geofence_transition_entered); 
     case Geofence.GEOFENCE_TRANSITION_EXIT: 
      return getString(R.string.geofence_transition_exited); 
     default: 
      return getString(R.string.unknown_geofence_transition); 
    } 
} 
} 

我想要的是將消息發送到在使用TCP

不斷進入/退出地理圍欄的服務器我做這樣的事情 啓動連接內部上創建

@Override 
public void onCreate() { 
    super.onCreate(); 
    if (mTcpClient == null) { 
     new ConnectTask().execute(""); 
    } 
} 

線程開始將消息發送到服務器

Thread thread=new Thread(){ 
     @Override 
     public void run() { 
      try { 
       mTcpClient.sendMessage("halo server"); 


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

     } 
    }; 
    thread.start(); 

它是第一次進入地理圍欄,成功發送郵件 但下一次進入/退出將給錯誤 顯示java.lang.NullPointerException工作在sendmessage方法

我認爲我不啓動和關閉連接權的問題,有人可以幫助我嗎?

編輯

的AsyncTask類

public class ConnectTask extends AsyncTask<String, String, TCPClient> { 

    @Override 
    protected TCPClient doInBackground(String... message) { 

     // create a TCPClient object 
     mTcpClient = new TCPClient(new TCPClient.OnMessageReceived() { 
      @Override 
      //here the messageReceived method is implemented 
      public void messageReceived(String message) { 
       //this method calls the onProgressUpdate 
       publishProgress(message); 
      } 
     }); 
     mTcpClient.run(); 

     return null; 
    } 

    @Override 
    protected void onProgressUpdate(String... values) { 
     super.onProgressUpdate(values); 


    } 
} 

的TcpClient類

public class TCPClient { 


// message to send to the server 
private String mServerMessage; 
// sends message received notifications 
private OnMessageReceived mMessageListener = null; 
// while this is true, the server will continue running 
private boolean mRun = false; 
// used to send messages 
private PrintWriter mBufferOut; 
// used to read messages from the server 
private BufferedReader mBufferIn; 

/** 
* Constructor of the class. 
*/ 
public TCPClient(OnMessageReceived listener) { 
    mMessageListener = listener; 
} 

/** 
* Sends the message entered by client to the server 
* 
* @param message text entered by client 
*/ 
public void sendMessage(String message) { 
    if (mBufferOut != null && !mBufferOut.checkError()) { 
     mBufferOut.println(message); 
     mBufferOut.flush(); 
    } 
} 

/** 
* Close the connection and release the members 
*/ 
public void stopClient() { 

    sendMessage("close"+"bye"); 
    mRun = false; 

    if (mBufferOut != null) { 
     mBufferOut.flush(); 
     mBufferOut.close(); 
    } 

    mMessageListener = null; 
    mBufferIn = null; 
    mBufferOut = null; 
    mServerMessage = null; 
} 

public void run() { 

    mRun = true; 

    try { 

     InetAddress serverAddr = InetAddress.getByName(Constants.SERVER_IP); 

     Log.e("TCP Client", "C: Connecting..."); 

     //create a socket to make the connection with the server 
     Socket socket = new Socket(serverAddr, Constants.SERVER_PORT); 

     try { 

      //sends the message to the server 
      mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); 

      //receives the message which the server sends back 
      mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      sendMessage("name"+"hi"); 

      while (mRun) { 

       mServerMessage = mBufferIn.readLine(); 

       if (mServerMessage != null && mMessageListener != null) { 
        //call the method messageReceived from MyActivity class 
        mMessageListener.messageReceived(mServerMessage); 
       } 

      } 

      Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + mServerMessage + "'"); 

     } catch (Exception e) { 

      Log.e("TCP", "S: Error", e); 

     } finally { 

      socket.close(); 
     } 

    } catch (Exception e) { 

     Log.e("TCP", "C: Error", e); 

    } 

} 

//Declare the interface. 
public interface OnMessageReceived { 
    public void messageReceived(String message); 
} 
} 
+1

我認爲ConnectTask是你的類,你打開的連接的服務器..張貼在這裏,所以我們可以檢查它.. – koperko

+0

是的,我編輯的代碼看到它 – hasd11

+1

當你有NullPointerException時,哪個指針爲空?哪個聲明導致它? logcat會告訴你。然後告訴我們。 – greenapps

回答

0

以及解決方案很容易 我只是我的TCP對象轉換爲靜態

private TCPClient mTcpClient; 

private static TCPClient mTcpClient; 

和我真的不明白爲什麼它的工作是靜態的,我會很感激,如果有人可以解釋這個

+1

,因爲IntentService是無狀態的。在IntentService中處理意圖之後,所有變量都將被處理。 – TGeorge