Setting up service discovery
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<uses-sdk
|
<uses-sdk
|
||||||
android:minSdkVersion="10"
|
android:minSdkVersion="10"
|
||||||
android:targetSdkVersion="18" />
|
android:targetSdkVersion="19" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
|
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
@@ -11,4 +11,4 @@
|
|||||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||||
|
|
||||||
# Project target.
|
# Project target.
|
||||||
target=android-18
|
target=android-19
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:text="@string/start_button" />
|
android:text="@string/start_button" />
|
||||||
|
|
||||||
<EditText
|
<!-- <EditText
|
||||||
android:id="@+id/ipAddressField"
|
android:id="@+id/ipAddressField"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@@ -34,5 +34,6 @@
|
|||||||
android:layout_alignBottom="@+id/ipAddressField"
|
android:layout_alignBottom="@+id/ipAddressField"
|
||||||
android:layout_toLeftOf="@+id/ipAddressField"
|
android:layout_toLeftOf="@+id/ipAddressField"
|
||||||
android:text="@string/ipAddressLabel" />
|
android:text="@string/ipAddressLabel" />
|
||||||
|
-->
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<string name="camera_success">Cámara abierta exitosamente</string>
|
<string name="camera_success">Cámara abierta exitosamente</string>
|
||||||
<string name="camera_failure">La cámara no pudo abrirse</string>
|
<string name="camera_failure">La cámara no pudo abrirse</string>
|
||||||
<string name="get_server_button">Conectar con NxtAR</string>
|
<string name="get_server_button">Conectar con NxtAR</string>
|
||||||
<string name="start_button">Encender cámara</string>
|
<string name="start_button">Conectar con dispositivo controlador</string>
|
||||||
<string name="title_activity_cam">CamActivity</string>
|
<string name="title_activity_cam">CamActivity</string>
|
||||||
<string name="ipAddressLabel">Dirección IP de NxtAR</string>
|
<string name="ipAddressLabel">Dirección IP de NxtAR</string>
|
||||||
<string name="badIpToast">La dirección IP no es válida</string>
|
<string name="badIpToast">La dirección IP no es válida</string>
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
<string name="camera_failure">Camera could not be opened</string>
|
<string name="camera_failure">Camera could not be opened</string>
|
||||||
<string name="title_activity_cam">CamActivity</string>
|
<string name="title_activity_cam">CamActivity</string>
|
||||||
<string name="get_server_button">Connect with NxtAR</string>
|
<string name="get_server_button">Connect with NxtAR</string>
|
||||||
<string name="start_button">Start camera</string>
|
<string name="start_button">Connect with controller device</string>
|
||||||
<string name="ipAddressLabel">NxtAR IP Address</string>
|
<string name="ipAddressLabel">NxtAR IP Address</string>
|
||||||
<string name="badIpToast">Invalid IP address</string>
|
<string name="badIpToast">Invalid IP address</string>
|
||||||
<string name="emptyIpToast">Fill out the IP address field</string>
|
<string name="emptyIpToast">Fill out the IP address field</string>
|
||||||
|
@@ -5,6 +5,7 @@ import ve.ucv.ciens.ccg.nxtcam.network.ImageTransferThread;
|
|||||||
import ve.ucv.ciens.ccg.nxtcam.utils.Logger;
|
import ve.ucv.ciens.ccg.nxtcam.utils.Logger;
|
||||||
import ve.ucv.ciens.ccg.nxtcam.utils.ProjectConstants;
|
import ve.ucv.ciens.ccg.nxtcam.utils.ProjectConstants;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
import android.hardware.Camera;
|
import android.hardware.Camera;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -23,6 +24,7 @@ public class CamActivity extends Activity{
|
|||||||
private CameraPreview cPreview;
|
private CameraPreview cPreview;
|
||||||
private CameraSetupTask camSetupTask;
|
private CameraSetupTask camSetupTask;
|
||||||
private ImageTransferThread imThread;
|
private ImageTransferThread imThread;
|
||||||
|
private String serverIp;
|
||||||
|
|
||||||
/*******************
|
/*******************
|
||||||
* Android methods *
|
* Android methods *
|
||||||
@@ -35,6 +37,9 @@ public class CamActivity extends Activity{
|
|||||||
cPreview = new CameraPreview(this, hwCamera);
|
cPreview = new CameraPreview(this, hwCamera);
|
||||||
setContentView(cPreview);
|
setContentView(cPreview);
|
||||||
|
|
||||||
|
Intent intent = getIntent();
|
||||||
|
serverIp = intent.getStringExtra("address");
|
||||||
|
|
||||||
imThread = new ImageTransferThread();
|
imThread = new ImageTransferThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,13 +1,18 @@
|
|||||||
package ve.ucv.ciens.ccg.nxtcam;
|
package ve.ucv.ciens.ccg.nxtcam;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
import java.net.MulticastSocket;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
import ve.ucv.ciens.ccg.nxtcam.utils.Logger;
|
import ve.ucv.ciens.ccg.nxtcam.utils.Logger;
|
||||||
|
import ve.ucv.ciens.ccg.nxtcam.utils.ProjectConstants;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.net.wifi.WifiManager.MulticastLock;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
@@ -16,14 +21,32 @@ import android.widget.Button;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry point por the NxtCAM application.
|
||||||
|
*
|
||||||
|
* This activity shows a splashscreen and handles the search for the controller device
|
||||||
|
* via a simle ad hoc UDP based service discovery method. Basically, it just listens for
|
||||||
|
* multicast packets sent by the controller device on the multicast address defined in
|
||||||
|
* ProjectConstants.java. When the packet is received the next activity of the application
|
||||||
|
* is launched with the ip address found. The service discovery process continues until a
|
||||||
|
* datagram carrying the string "NxtAR server here!" is received.
|
||||||
|
*
|
||||||
|
* @author miky
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class MainActivity extends Activity {
|
public class MainActivity extends Activity {
|
||||||
|
// Cosntant fields.
|
||||||
private final String TAG = "NXTCAM_MAIN";
|
private final String TAG = "NXTCAM_MAIN";
|
||||||
private final String CLASS_NAME = MainActivity.class.getSimpleName();
|
private final String CLASS_NAME = MainActivity.class.getSimpleName();
|
||||||
|
|
||||||
|
// Gui components.
|
||||||
private Button startButton;
|
private Button startButton;
|
||||||
private TextView ipField;
|
//private TextView ipField;
|
||||||
|
|
||||||
|
// Resources.
|
||||||
private WifiManager wifiManager;
|
private WifiManager wifiManager;
|
||||||
|
|
||||||
|
// Variables.
|
||||||
private boolean wifiOnByMe;
|
private boolean wifiOnByMe;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -31,35 +54,34 @@ public class MainActivity extends Activity {
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
|
// Set up fields.
|
||||||
|
wifiOnByMe = false;
|
||||||
|
|
||||||
|
// Set up gui components.
|
||||||
startButton = (Button)findViewById(R.id.startButton);
|
startButton = (Button)findViewById(R.id.startButton);
|
||||||
startButton.setOnClickListener(startClickListener);
|
startButton.setOnClickListener(startClickListener);
|
||||||
|
// ipField = (TextView)findViewById(R.id.ipAddressField);
|
||||||
|
|
||||||
ipField = (TextView)findViewById(R.id.ipAddressField);
|
// Set up services.
|
||||||
|
|
||||||
wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
|
wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
|
||||||
|
if(!wifiManager.isWifiEnabled())
|
||||||
if(!wifiManager.isWifiEnabled()) setWifi(true);
|
setWifi(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume(){
|
public void onResume(){
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
if(!wifiManager.isWifiEnabled()) setWifi(true);
|
if(!wifiManager.isWifiEnabled())
|
||||||
|
setWifi(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPause(){
|
public void onPause(){
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
|
||||||
if(wifiManager.isWifiEnabled() && wifiOnByMe) setWifi(false);
|
if(wifiManager.isWifiEnabled() && wifiOnByMe)
|
||||||
}
|
setWifi(false);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy(){
|
|
||||||
super.onDestroy();
|
|
||||||
|
|
||||||
if(wifiManager.isWifiEnabled() && wifiOnByMe) wifiManager.setWifiEnabled(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -69,10 +91,17 @@ public class MainActivity extends Activity {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startCamActivity(boolean canStart){
|
/**
|
||||||
if(canStart){
|
* Start the camera capture activity if a server was found through service discovery.
|
||||||
|
*
|
||||||
|
* @param serverFound Indicates if a server was found, doh!
|
||||||
|
* @param ipAddress The ip address of the server.
|
||||||
|
*/
|
||||||
|
private void startCamActivity(boolean serverFound, String ipAddress){
|
||||||
|
if(serverFound){
|
||||||
Logger.log(Logger.LOG_TYPES.DEBUG, TAG, CLASS_NAME + ".startCamActivity() :: Launching camera activity.");
|
Logger.log(Logger.LOG_TYPES.DEBUG, TAG, CLASS_NAME + ".startCamActivity() :: Launching camera activity.");
|
||||||
Intent intent = new Intent(this, CamActivity.class);
|
Intent intent = new Intent(this, CamActivity.class);
|
||||||
|
intent.putExtra("address", ipAddress);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}else{
|
}else{
|
||||||
Logger.log(Logger.LOG_TYPES.DEBUG, TAG, CLASS_NAME + ".startCamActivity() :: Cannot launch camera activity.");
|
Logger.log(Logger.LOG_TYPES.DEBUG, TAG, CLASS_NAME + ".startCamActivity() :: Cannot launch camera activity.");
|
||||||
@@ -80,16 +109,21 @@ public class MainActivity extends Activity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setWifi(boolean on){
|
/**
|
||||||
wifiManager.setWifiEnabled(on);
|
* Sets the state of the device's WiFi radio.
|
||||||
Logger.log(Logger.LOG_TYPES.DEBUG, TAG, CLASS_NAME + ".ImageTransferThread() :: setting wifi to " + (on ? "on" : "off"));
|
*
|
||||||
if(on)
|
* @param radioState The state to set the radio to; true for on, false for off.
|
||||||
|
*/
|
||||||
|
private void setWifi(boolean radioState){
|
||||||
|
wifiManager.setWifiEnabled(radioState);
|
||||||
|
Logger.log(Logger.LOG_TYPES.DEBUG, TAG, CLASS_NAME + ".setWifi() :: setting wifi to " + (radioState ? "on" : "off"));
|
||||||
|
if(radioState)
|
||||||
wifiOnByMe = true;
|
wifiOnByMe = true;
|
||||||
else
|
else
|
||||||
wifiOnByMe = false;
|
wifiOnByMe = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateIpAddress(){
|
/*private void validateIpAddress(){
|
||||||
if(ipField.getText().toString().compareTo("") != 0){
|
if(ipField.getText().toString().compareTo("") != 0){
|
||||||
Logger.log(Logger.LOG_TYPES.DEBUG, TAG, CLASS_NAME + "validateIpAddress() :: Launching verification task.");
|
Logger.log(Logger.LOG_TYPES.DEBUG, TAG, CLASS_NAME + "validateIpAddress() :: Launching verification task.");
|
||||||
VerifyIpAddressTask verifyIp = new VerifyIpAddressTask();
|
VerifyIpAddressTask verifyIp = new VerifyIpAddressTask();
|
||||||
@@ -98,16 +132,93 @@ public class MainActivity extends Activity {
|
|||||||
Logger.log(Logger.LOG_TYPES.DEBUG, TAG, CLASS_NAME + "validateIpAddress() :: Ip address field is empty.");
|
Logger.log(Logger.LOG_TYPES.DEBUG, TAG, CLASS_NAME + "validateIpAddress() :: Ip address field is empty.");
|
||||||
Toast.makeText(this, R.string.emptyIpToast, Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, R.string.emptyIpToast, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event listener for the connection button.
|
||||||
|
*/
|
||||||
private final View.OnClickListener startClickListener = new View.OnClickListener() {
|
private final View.OnClickListener startClickListener = new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
validateIpAddress();
|
//validateIpAddress();
|
||||||
|
ServiceDiscoveryTask serviceDiscovery = new ServiceDiscoveryTask();
|
||||||
|
serviceDiscovery.execute();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private class VerifyIpAddressTask extends AsyncTask<String, Void, Boolean>{
|
/**
|
||||||
|
* Asynchronous task for ad hoc UDP service discovery.
|
||||||
|
*
|
||||||
|
* @author Miguel Angel Astor Romero
|
||||||
|
*/
|
||||||
|
private class ServiceDiscoveryTask extends AsyncTask<Void, Void, Boolean>{
|
||||||
|
|
||||||
|
private final String CLASS_NAME = ServiceDiscoveryTask.class.getSimpleName();
|
||||||
|
|
||||||
|
private MulticastSocket udpSocket;
|
||||||
|
private DatagramPacket packet;
|
||||||
|
private MulticastLock multicastLock;
|
||||||
|
|
||||||
|
public ServiceDiscoveryTask(){
|
||||||
|
// Open a multicast socket and join the project's multicast group.
|
||||||
|
try{
|
||||||
|
udpSocket = new MulticastSocket(ProjectConstants.SERVER_UDP_PORT);
|
||||||
|
InetAddress group = InetAddress.getByName(ProjectConstants.MULTICAST_ADDRESS);
|
||||||
|
udpSocket.joinGroup(group);
|
||||||
|
}catch(IOException io){
|
||||||
|
Logger.log(Logger.LOG_TYPES.ERROR, TAG ,CLASS_NAME + ".ServiceDiscoveryTask() :: " + io.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Boolean doInBackground(Void... params){
|
||||||
|
boolean result, done = false;
|
||||||
|
byte[] buffer = (new String("Server is here")).getBytes();
|
||||||
|
|
||||||
|
// Create a buffer and tell Android we want to receive multicast datagrams.
|
||||||
|
packet = new DatagramPacket(buffer, buffer.length);
|
||||||
|
multicastLock = wifiManager.createMulticastLock(TAG);
|
||||||
|
multicastLock.setReferenceCounted(true);
|
||||||
|
multicastLock.acquire();
|
||||||
|
|
||||||
|
// Listen for a UDP datagram on the multicast group.
|
||||||
|
// If the datagram received contains a string with it's content equal to "NxtAR server here!"
|
||||||
|
// then assume the server found is a valid controller device.
|
||||||
|
try{
|
||||||
|
while(!done){
|
||||||
|
udpSocket.receive(packet);
|
||||||
|
Logger.log(Logger.LOG_TYPES.DEBUG, TAG, CLASS_NAME + ".run() :: Found a server at " + packet.getAddress().getHostAddress());
|
||||||
|
String received = new String(packet.getData());
|
||||||
|
if(received.compareTo("NxtAR server here!") == 0)
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
result = true;
|
||||||
|
}catch(IOException io){
|
||||||
|
Logger.log(Logger.LOG_TYPES.ERROR, TAG, CLASS_NAME + ".doInBackground() :: " + io.getMessage());
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell Android we do not want to receive more UDP datagrams to save battery life.
|
||||||
|
if(multicastLock != null){
|
||||||
|
multicastLock.release();
|
||||||
|
multicastLock = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Boolean result){
|
||||||
|
super.onPostExecute(result);
|
||||||
|
// If a server was found then start the next activity.
|
||||||
|
if(packet != null)
|
||||||
|
startCamActivity(result, packet.getAddress().getHostAddress());
|
||||||
|
else
|
||||||
|
startCamActivity(false, null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* private class VerifyIpAddressTask extends AsyncTask<String, Void, Boolean>{
|
||||||
private final String CLASS_NAME = VerifyIpAddressTask.class.getSimpleName();
|
private final String CLASS_NAME = VerifyIpAddressTask.class.getSimpleName();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -127,5 +238,5 @@ public class MainActivity extends Activity {
|
|||||||
super.onPostExecute(result);
|
super.onPostExecute(result);
|
||||||
startCamActivity(result);
|
startCamActivity(result);
|
||||||
}
|
}
|
||||||
};
|
};*/
|
||||||
}
|
}
|
||||||
|
@@ -1,13 +0,0 @@
|
|||||||
package ve.ucv.ciens.ccg.nxtcam.network;
|
|
||||||
|
|
||||||
public class ServiceDiscoveryThread extends Thread {
|
|
||||||
|
|
||||||
public ServiceDiscoveryThread(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run(){
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@@ -5,5 +5,7 @@ public abstract class ProjectConstants {
|
|||||||
public static final int SERVER_TCP_PORT_1 = 9989;
|
public static final int SERVER_TCP_PORT_1 = 9989;
|
||||||
public static final int SERVER_TCP_PORT_2 = 9990;
|
public static final int SERVER_TCP_PORT_2 = 9990;
|
||||||
|
|
||||||
|
public static final String MULTICAST_ADDRESS = "230.0.0.1";
|
||||||
|
|
||||||
public static final boolean DEBUG = true;
|
public static final boolean DEBUG = true;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user