1

я сделал простой TCP-клиент, и это отлично работает, когда я использую простую деятельность и кнопку, чтобы отправить сообщениеAndroid-как реализовать TCP-IP клиент внутри intentservice

теперь я реализовать GeoFence приложения, используя тот же Google GeoFence примера здесь

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); 
    } 
} 
} 

, что я хочу, чтобы отправить сообщение на сервер, когда-либо входа/выхода из Geofence с использованием протокола TCP

я сделать что-то вроде этого запустить соединение внутри на Create

@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(); 

это работа впервые войти в Geofence и отправить сообщение успешно но в следующий раз вход/выход будет давать ошибку java.lang.NullPointerException по методу sendmessage

Я думаю, проблема в том, что я не начинаю и не закрываю соединение, может кто-нибудь мне помочь?

EDIT

класс 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

Какой указатель имеет значение null, когда у вас есть это NullPointerException? Какое утверждение вызывает это? Логарифм скажет вам. Тогда скажите нам. – greenapps

ответ

0

хорошо решение было легко я просто преобразовать свой объект ТСР статический

старый

private TCPClient mTcpClient; 

нового

private static TCPClient mTcpClient; 

и на самом деле я не понимаю, почему это работа как статические, я буду благодарен, если кто-то может объяснить эту

+1

, потому что IntentService без гражданства. Все переменные расположены после того, как в IntentService было обработано намерение. – TGeorge

 Смежные вопросы

  • Нет связанных вопросов^_^