1 /* 2 * MainActivity.java - libwebsockets test service for Android 3 * 4 * Copyright (C) 2016 Alexander Bruines <alexander.bruines@gmail.com> 5 * 6 * This file is made available under the Creative Commons CC0 1.0 7 * Universal Public Domain Dedication. 8 * 9 * The person who associated a work with this deed has dedicated 10 * the work to the public domain by waiving all of his or her rights 11 * to the work worldwide under copyright law, including all related 12 * and neighboring rights, to the extent allowed by law. You can copy, 13 * modify, distribute and perform the work, even for commercial purposes, 14 * all without asking permission. 15 * 16 * The test apps are intended to be adapted for use in your code, which 17 * may be proprietary. So unlike the library itself, they are licensed 18 * Public Domain. 19 */ 20 21 package org.libwebsockets.client; 22 23 24 import android.content.ComponentName; 25 import android.content.Context; 26 import android.content.DialogInterface; 27 import android.content.Intent; 28 import android.content.ServiceConnection; 29 import android.os.IBinder; 30 import android.os.Message; 31 import android.os.Messenger; 32 import android.os.RemoteException; 33 import android.support.v7.app.AlertDialog; 34 import android.support.v7.app.AppCompatActivity; 35 import android.os.Bundle; 36 import android.util.Log; 37 import android.view.inputmethod.InputMethodManager; 38 import android.view.View; 39 import android.widget.EditText; 40 import android.widget.TextView; 41 42 public class MainActivity extends AppCompatActivity implements LwsService.OutputInterface { 43 44 /** This is the Messenger that handles output from the Service */ 45 private Messenger mMessenger = null; 46 47 /** The Messenger for sending commands to the Service */ 48 private Messenger mService = null; 49 private ServiceConnection mServiceConnection = null; 50 51 private boolean mThreadIsRunning = false; 52 private boolean mThreadIsSuspended = false; 53 54 private TextView tvCounter; 55 private EditText etServer; 56 private EditText etPort; 57 58 @Override onCreate(Bundle savedInstanceState)59 protected void onCreate(Bundle savedInstanceState) { 60 super.onCreate(savedInstanceState); 61 setContentView(R.layout.activity_main); 62 63 // Get the layout items 64 tvCounter = (TextView) findViewById(R.id.textView_counter); 65 etServer = (EditText) findViewById(R.id.editText_serverLocation); 66 etPort = (EditText) findViewById(R.id.editText_portNumber); 67 68 // Create the Messenger for handling output from the service 69 mMessenger = new Messenger(new LwsService.OutputHandler(this)); 70 71 // Restore state from the Bundle when restarting due to a device change. 72 if(savedInstanceState!=null) { 73 mThreadIsRunning = savedInstanceState.getBoolean("mThreadIsRunning"); 74 } 75 76 mServiceConnection = new ServiceConnection() { 77 @Override 78 public void onServiceConnected(ComponentName name, IBinder service) { 79 mService = new Messenger(service); 80 try { 81 // Set the output messenger by starting the thread 82 Message msg = Message.obtain(null, LwsService.MSG_SET_OUTPUT_HANDLER, 0, 0); 83 msg.replyTo = mMessenger; 84 mService.send(msg); 85 if(mThreadIsRunning){ 86 // If the thread is already running at this point it means 87 // that the application was restarted after a device change. 88 // This implies that the thread was suspended by the onStop method. 89 msg = Message.obtain(null, LwsService.MSG_THREAD_RESUME, 0, 0); 90 mService.send(msg); 91 mThreadIsSuspended = false; 92 } 93 } 94 catch(RemoteException e) { 95 e.printStackTrace(); 96 } 97 } 98 99 @Override 100 public void onServiceDisconnected(ComponentName name) { 101 Log.e("MainActivity","onServiceDisconnected !"); 102 mService = null; 103 } 104 }; 105 106 if(savedInstanceState==null){ 107 startService(new Intent(getBaseContext(), LwsService.class)); 108 } 109 } 110 111 @Override onSaveInstanceState(Bundle outState)112 protected void onSaveInstanceState(Bundle outState) { 113 super.onSaveInstanceState(outState); 114 outState.putBoolean("mThreadIsRunning", mThreadIsRunning); 115 } 116 117 @Override onStart()118 protected void onStart() { 119 super.onStart(); 120 bindService(new Intent(getBaseContext(), LwsService.class), mServiceConnection, Context.BIND_AUTO_CREATE); 121 } 122 123 @Override onStop()124 protected void onStop() { 125 super.onStop(); 126 if(mThreadIsRunning) { 127 if (!mThreadIsSuspended) { 128 try { 129 mService.send(Message.obtain(null, LwsService.MSG_THREAD_SUSPEND, 0, 0)); 130 } catch (RemoteException e) { 131 e.printStackTrace(); 132 } 133 mThreadIsSuspended = true; 134 } 135 } 136 unbindService(mServiceConnection); 137 } 138 139 @Override onDestroy()140 protected void onDestroy() { 141 super.onDestroy(); 142 if(isFinishing()){ 143 stopService(new Intent(getBaseContext(), LwsService.class)); 144 } 145 } 146 147 /** Implement the interface to receive output from the LwsService */ 148 @Override handleOutputMessage(Message message)149 public void handleOutputMessage(Message message) { 150 switch(message.what) { 151 case LwsService.MSG_DUMB_INCREMENT_PROTOCOL_COUNTER: 152 tvCounter.setText((String)message.obj); 153 break; 154 case LwsService.MSG_LWS_CALLBACK_CLIENT_CONNECTION_ERROR: 155 connectErrorListener(); 156 break; 157 case LwsService.MSG_LWS_CALLBACK_CLIENT_ESTABLISHED: 158 break; 159 case LwsService.MSG_THREAD_STARTED: 160 // The thread was started 161 mThreadIsRunning = true; 162 mThreadIsSuspended = false; 163 break; 164 case LwsService.MSG_THREAD_STOPPED: 165 // The thread was stopped 166 mThreadIsRunning = false; 167 mThreadIsSuspended = false; 168 break; 169 case LwsService.MSG_THREAD_SUSPENDED: 170 // The thread is suspended 171 mThreadIsRunning = true; 172 mThreadIsSuspended = true; 173 break; 174 case LwsService.MSG_THREAD_RESUMED: 175 // the thread was resumed 176 mThreadIsRunning = true; 177 mThreadIsSuspended = false; 178 break; 179 default: 180 break; 181 } 182 } 183 connectErrorListener()184 private void connectErrorListener(){ 185 try { 186 Message msg; 187 if(mThreadIsRunning) { 188 msg = Message.obtain(null, LwsService.MSG_THREAD_STOP); 189 mService.send(msg); 190 } 191 AlertDialog.Builder adb = new AlertDialog.Builder(this); 192 adb.setTitle("Error"); 193 adb.setPositiveButton("OK", new DialogInterface.OnClickListener() { 194 public void onClick(DialogInterface dialog, int which) { 195 } 196 }); 197 adb.setMessage("Could not connect to the server."); 198 adb.show(); 199 } 200 catch (RemoteException e){} 201 } 202 203 /** 204 * Start/Stop Button Handler 205 */ 206 clickStart(View v)207 public void clickStart(View v) { 208 if(!mThreadIsRunning) { 209 View view = this.getCurrentFocus(); 210 if (view != null) { 211 InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 212 imm.hideSoftInputFromWindow(view.getWindowToken(), 0); 213 } 214 mThreadIsRunning = true; 215 mThreadIsSuspended = false; 216 try { 217 Message msg = Message.obtain(null, LwsService.MSG_SET_CONNECTION_PARAMETERS, 0, 0); 218 int port = 0; 219 if(!etPort.getText().toString().equals("")) // prevent NumberformatException 220 port = Integer.parseInt(etPort.getText().toString()); 221 LwsService.ConnectionParameters parameters = new LwsService.ConnectionParameters( 222 etServer.getText().toString(), 223 port 224 ); 225 msg.obj = parameters; 226 mService.send(msg); 227 msg = Message.obtain(null, LwsService.MSG_THREAD_START, 0, 0); 228 mService.send(msg); 229 } 230 catch(RemoteException e) { 231 e.printStackTrace(); 232 } 233 } 234 else { 235 try { 236 mService.send(Message.obtain(null, LwsService.MSG_THREAD_STOP, 0, 0)); 237 } 238 catch(RemoteException e) { 239 e.printStackTrace(); 240 } 241 mThreadIsRunning = false; 242 mThreadIsSuspended = false; 243 } 244 } 245 246 } 247