Android app updated (now the Android app acts even as client using the

device's accelerometers).
This commit is contained in:
Daniele Verducci 2014-03-16 12:43:55 +01:00
parent ecb44abd7a
commit 8aa13953ee
38 changed files with 418 additions and 207 deletions

View File

@ -1,14 +1,15 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="it.danieleverducci.explorerbotserver" package="it.danieleverducci.explorerbot"
android:versionCode="1" android:versionCode="1"
android:versionName="1.0" > android:versionName="1.0" >
<uses-sdk <uses-sdk
android:minSdkVersion="14" android:minSdkVersion="1"
android:targetSdkVersion="19" /> android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission> <uses-permission android:name="android.permission.INTERNET" >
</uses-permission>
<application <application
android:allowBackup="true" android:allowBackup="true"
@ -16,19 +17,32 @@
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/AppTheme" > android:theme="@style/AppTheme" >
<activity <activity
android:name="it.danieleverducci.explorerbotserver.MainActivity" android:name="it.danieleverducci.explorerbot.MainActivity"
android:label="@string/app_name" > android:label="@string/app_name"
android:screenOrientation="portrait" >
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity>
<activity
android:name="it.danieleverducci.explorerbot.server.ServerActivity"
android:label="@string/app_name"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<meta-data <meta-data
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter" /> android:resource="@xml/device_filter" />
</activity> </activity>
<activity
android:name="it.danieleverducci.explorerbot.client.ClientActivity"
android:label="@string/app_name"
android:screenOrientation="landscape" >
</activity>
</application> </application>
</manifest> </manifest>

View File

@ -1,14 +1,15 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="it.danieleverducci.explorerbotserver" package="it.danieleverducci.explorerbot"
android:versionCode="1" android:versionCode="1"
android:versionName="1.0" > android:versionName="1.0" >
<uses-sdk <uses-sdk
android:minSdkVersion="14" android:minSdkVersion="1"
android:targetSdkVersion="19" /> android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission> <uses-permission android:name="android.permission.INTERNET" >
</uses-permission>
<application <application
android:allowBackup="true" android:allowBackup="true"
@ -16,19 +17,32 @@
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/AppTheme" > android:theme="@style/AppTheme" >
<activity <activity
android:name="it.danieleverducci.explorerbotserver.MainActivity" android:name="it.danieleverducci.explorerbot.MainActivity"
android:label="@string/app_name" > android:label="@string/app_name"
android:screenOrientation="portrait" >
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity>
<activity
android:name="it.danieleverducci.explorerbot.server.ServerActivity"
android:label="@string/app_name"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<meta-data <meta-data
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter" /> android:resource="@xml/device_filter" />
</activity> </activity>
<activity
android:name="it.danieleverducci.explorerbot.client.ClientActivity"
android:label="@string/app_name"
android:screenOrientation="landscape" >
</activity>
</application> </application>
</manifest> </manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<lint>
</lint>

Binary file not shown.

After

Width:  |  Height:  |  Size: 568 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ToggleButton
android:id="@+id/drive"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/drive"
android:layout_centerHorizontal="true"
android:text="@string/drive"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="@+id/exit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="Exit" />
</RelativeLayout>

View File

@ -1,52 +1,50 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" > android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center" >
<ImageView <LinearLayout
android:id="@+id/image"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerHorizontal="true" android:layout_marginBottom="10dp"
android:layout_centerVertical="true" android:background="#FF000000"
android:background="@android:color/background_dark" android:orientation="vertical"
android:padding="20dp" android:padding="30dp" >
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/image"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:text="@string/srv"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/text"
android:layout_centerHorizontal="true"
android:layout_margin="10dp"
android:gravity="center_horizontal"
android:text="@string/explain" />
<Button
android:id="@+id/killserverbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView1"
android:layout_centerHorizontal="true"
android:text="@string/killserver" />
<ImageButton <ImageButton
android:id="@+id/startvideo" android:id="@+id/startServer"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentRight="true" android:src="@drawable/ic_hardware_phone"
android:layout_alignParentTop="true" />
android:layout_margin="10dp" </LinearLayout>
android:src="@drawable/ic_device_access_video" />
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="30dp"
android:background="#FF000000"
android:gravity="center" >
<ImageButton
android:id="@+id/startClient"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
<EditText
android:id="@+id/ipAddressEditText"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:background="#FFC0C0C0"
android:layout_margin="10dp" >
<requestFocus />
</EditText>
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,62 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:background="@android:color/background_dark"
android:padding="20dp"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/port"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/image"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:text="port"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="@+id/killserverbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView1"
android:layout_centerHorizontal="true"
android:text="@string/killserver" />
<ImageButton
android:id="@+id/startvideo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_margin="10dp"
android:src="@drawable/ic_device_access_video" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@+id/port"
android:layout_margin="10dp"
android:gravity="center_horizontal"
android:text="@string/explain" />
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/image"
android:layout_centerHorizontal="true"
android:layout_marginBottom="20dp"
android:text="@string/srv"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>

View File

@ -5,5 +5,7 @@
<string name="srv">Server started</string> <string name="srv">Server started</string>
<string name="explain">Exiting with HOME key will keep the server running. To exit completly press BACK or use the button below.</string> <string name="explain">Exiting with HOME key will keep the server running. To exit completly press BACK or use the button below.</string>
<string name="killserver">Kill server</string> <string name="killserver">Kill server</string>
<string name="drive">Activate accelerometer drive</string>
<string name="api_requirement_not_satisfied">You need at least Android 3.1 for this feature.</string>
</resources> </resources>

View File

@ -16,10 +16,9 @@
along with AndroidExplorerbotServer. If not, see <http://www.gnu.org/licenses/>. along with AndroidExplorerbotServer. If not, see <http://www.gnu.org/licenses/>.
*/ */
package it.danieleverducci.explorerbotserver; package it.danieleverducci.explorerbot;
public class AppConfiguration { public class AndroidAppConfiguration extends AppConfiguration {
public static final int PORT=6787; //The default server port
public static final boolean LOG_ENABLED=false; public static final boolean LOG_ENABLED=false;
public static final String DEFAULT_IPCAMERA_APP_PACKAGENAME="com.pas.webcam"; public static final String DEFAULT_IPCAMERA_APP_PACKAGENAME="com.pas.webcam";
} }

View File

@ -0,0 +1,43 @@
package it.danieleverducci.explorerbot;
import it.danieleverducci.explorerbot.client.ClientActivity;
import it.danieleverducci.explorerbot.server.ServerActivity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.startClient).setOnClickListener(this);
findViewById(R.id.startServer).setOnClickListener(this);
}
@Override
public void onClick(View v) {
Intent i;
switch(v.getId()){
case R.id.startClient:
String ipAddress = ((EditText)findViewById(R.id.ipAddressEditText)).getText().toString();
i = new Intent(this, ClientActivity.class);
i.putExtra(ClientActivity.IP_ADDRESS_INTENT_EXTRA, ipAddress);
startActivity(i);
break;
case R.id.startServer:
if(android.os.Build.VERSION.SDK_INT>=12) {
i = new Intent(this, ServerActivity.class);
startActivity(i);
} else Toast.makeText(this, R.string.api_requirement_not_satisfied, Toast.LENGTH_SHORT).show();
break;
}
}
}

View File

@ -0,0 +1,61 @@
package it.danieleverducci.explorerbot.client;
import it.danieleverducci.explorerbot.interfaces.OnControllerPolledListener;
import it.danieleverducci.explorerbot.objects.GamepadPosition;
import android.app.Service;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
public class AccelerometerPoller implements SensorEventListener {
private Context context;
private SensorManager sensorManager;
private Sensor accelerometer;
private OnControllerPolledListener onControllerPolledListener;
private GamepadPosition pos;
public AccelerometerPoller(Context context) {
this.context = context;
this.pos = new GamepadPosition();
sensorManager = (SensorManager)this.context.getSystemService(Service.SENSOR_SERVICE);
accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
// sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_UI);
}
@Override
public void onSensorChanged(SensorEvent event) {
pos.setX(normalize(event.values[1]));
pos.setY(normalize(event.values[0]));
onControllerPolledListener.onControllerPolled(pos);
}
/**
* Takes an accelerometer @param f (force) in m/s2 and converts to a float between 1 and -1
* @return
*/
private float normalize(float f) {
//The acceleration on earth is 9,8m/s, but we want the two edges to be easily reachable, so divide for 9,0
f = f/9f;
if(f<=1.0f && f>=-1.0f) return f;
else if(f>1.0f) return 1.0f;
else return -1.0f;
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {}
public void onResume() {
sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_UI);
}
public void onPause() {
sensorManager.unregisterListener(this);
}
public void setOnControllerPolledListener(OnControllerPolledListener onControllerPolledListener) {
this.onControllerPolledListener = onControllerPolledListener;
}
}

View File

@ -0,0 +1,93 @@
package it.danieleverducci.explorerbot.client;
import it.danieleverducci.explorerbot.R;
import it.danieleverducci.explorerbot.interfaces.OnControllerPolledListener;
import it.danieleverducci.explorerbot.objects.GamepadPosition;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ToggleButton;
public class ClientActivity extends Activity implements OnControllerPolledListener, OnCheckedChangeListener, OnClickListener {
public static final String IP_ADDRESS_INTENT_EXTRA = "ipAddress";
private AccelerometerPoller accelPoller;
private ClientNetworkCommunicationThread net;
private ToggleButton drive;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Draw view and set listeners
setContentView(R.layout.activity_client);
drive = (ToggleButton)findViewById(R.id.drive);
drive.setOnCheckedChangeListener(this);
findViewById(R.id.exit).setOnClickListener(this);
//Retrieve user-provided IP address
String ipAddress = getIntent().getStringExtra(IP_ADDRESS_INTENT_EXTRA);
//Initialize accelerometer poller
accelPoller = new AccelerometerPoller(this);
accelPoller.setOnControllerPolledListener(this);
//Initialize network communication thread
net = new ClientNetworkCommunicationThread(ipAddress);
net.start();
}
@Override
protected void onResume() {
super.onResume();
ToggleButton transmitting = (ToggleButton)findViewById(R.id.drive);
if(accelPoller!=null && transmitting.isChecked()) accelPoller.onResume();
}
@Override
protected void onPause() {
super.onPause();
if(accelPoller!=null) accelPoller.onPause();
}
@Override
public void onControllerPolled(GamepadPosition position) {
// Notify network thread
net.setLastKnownPosition(position);
}
@Override
protected void onDestroy() {
if(net!=null) net.setMustExit(true);
super.onDestroy();
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) {
if(accelPoller!=null) accelPoller.onResume();
drive.setBackgroundColor(Color.parseColor("#FFFF0000"));
}
else {
if(accelPoller!=null) accelPoller.onPause();
drive.setBackgroundColor(Color.parseColor("#FFC0C0C0"));
}
}
@Override
public void onClick(View v) {
accelPoller.onPause();
net.setMustExit(true);
finish();
}
}

View File

@ -1,44 +0,0 @@
/*
Copyright 2014 Daniele Verducci
This file is part of AndroidExplorerbotServer.
AndroidExplorerbotServer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
AndroidExplorerbotServer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with AndroidExplorerbotServer. If not, see <http://www.gnu.org/licenses/>.
*/
package it.danieleverducci.explorerbot.objects;
import java.io.Serializable;
/**
* Object representing the gamepad's analog stick position
*/
public class GamepadPosition implements Serializable {
private static final long serialVersionUID = 8066726751180370259L;
private float x;
private float y;
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
}

View File

@ -16,8 +16,9 @@
along with AndroidExplorerbotServer. If not, see <http://www.gnu.org/licenses/>. along with AndroidExplorerbotServer. If not, see <http://www.gnu.org/licenses/>.
*/ */
package it.danieleverducci.explorerbotserver; package it.danieleverducci.explorerbot.server;
import it.danieleverducci.explorerbot.AndroidAppConfiguration;
import it.danieleverducci.explorerbot.objects.GamepadPosition; import it.danieleverducci.explorerbot.objects.GamepadPosition;
import java.io.IOException; import java.io.IOException;
@ -34,15 +35,15 @@ public class SerialCommunication {
private boolean connected=false; private boolean connected=false;
private UsbSerialDriver driver; private UsbSerialDriver driver;
public SerialCommunication(MainActivity context) { public SerialCommunication(Context context) {
if(AppConfiguration.LOG_ENABLED) Log.d(this.getClass().toString(),"Searcing for Arduino: "); if(AndroidAppConfiguration.LOG_ENABLED) Log.d(this.getClass().toString(),"Searcing for Arduino: ");
//Find first port //Find first port
UsbManager manager = (UsbManager)context.getSystemService(Context.USB_SERVICE); UsbManager manager = (UsbManager)context.getSystemService(Context.USB_SERVICE);
driver = UsbSerialProber.acquire(manager); driver = UsbSerialProber.acquire(manager);
if(driver!=null){ if(driver!=null){
if(AppConfiguration.LOG_ENABLED) Log.d(this.getClass().toString(),"Found arduino on port"+driver.getDevice().getDeviceName()); if(AndroidAppConfiguration.LOG_ENABLED) Log.d(this.getClass().toString(),"Found arduino on port"+driver.getDevice().getDeviceName());
connected=true; connected=true;
try { try {
driver.setBaudRate(9600); driver.setBaudRate(9600);
@ -50,7 +51,7 @@ public class SerialCommunication {
e.printStackTrace(); e.printStackTrace();
} }
} else { } else {
if(AppConfiguration.LOG_ENABLED) Log.d(this.getClass().toString(),"Arduino not found!"); if(AndroidAppConfiguration.LOG_ENABLED) Log.d(this.getClass().toString(),"Arduino not found!");
connected=false; connected=false;
} }
} }
@ -66,7 +67,7 @@ public class SerialCommunication {
data[0] = (byte)((pos.getX()+1)*63);//x data[0] = (byte)((pos.getX()+1)*63);//x
data[1] = (byte)((pos.getY()+1)*63);//y data[1] = (byte)((pos.getY()+1)*63);//y
driver.write(data, 80); driver.write(data, 80);
if(AppConfiguration.LOG_ENABLED) Log.e("DANY", "Written "+pos.getX()+" "+pos.getY()); if(AndroidAppConfiguration.LOG_ENABLED) Log.e("DANY", "Written "+pos.getX()+" "+pos.getY());
} }
/** /**

View File

@ -16,8 +16,11 @@
along with AndroidExplorerbotServer. If not, see <http://www.gnu.org/licenses/>. along with AndroidExplorerbotServer. If not, see <http://www.gnu.org/licenses/>.
*/ */
package it.danieleverducci.explorerbotserver; package it.danieleverducci.explorerbot.server;
import it.danieleverducci.explorerbot.AndroidAppConfiguration;
import it.danieleverducci.explorerbot.R;
import it.danieleverducci.explorerbot.interfaces.OnControllerPolledListener;
import it.danieleverducci.explorerbot.objects.GamepadPosition; import it.danieleverducci.explorerbot.objects.GamepadPosition;
import java.io.IOException; import java.io.IOException;
@ -28,15 +31,17 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.TextView;
public class MainActivity extends Activity implements OnControllerPolledListener, OnClickListener { public class ServerActivity extends Activity implements OnControllerPolledListener, OnClickListener {
private SerialCommunication serial; private SerialCommunication serial;
private ServerNetworkCommunicationThread sct; private ServerNetworkCommunicationThread sct;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_server);
((TextView)findViewById(R.id.port)).setText(AndroidAppConfiguration.PORT+"");
//Initialize serial communication //Initialize serial communication
serial = new SerialCommunication(this); serial = new SerialCommunication(this);
@ -95,8 +100,8 @@ public class MainActivity extends Activity implements OnControllerPolledListener
* If the app is installed, start it. Otherwise, open the Android Market for download * If the app is installed, start it. Otherwise, open the Android Market for download
*/ */
private void launchStreamingApp() { private void launchStreamingApp() {
Intent launchIntent = getPackageManager().getLaunchIntentForPackage(AppConfiguration.DEFAULT_IPCAMERA_APP_PACKAGENAME); Intent launchIntent = getPackageManager().getLaunchIntentForPackage(AndroidAppConfiguration.DEFAULT_IPCAMERA_APP_PACKAGENAME);
if(launchIntent==null) launchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + AppConfiguration.DEFAULT_IPCAMERA_APP_PACKAGENAME)); if(launchIntent==null) launchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + AndroidAppConfiguration.DEFAULT_IPCAMERA_APP_PACKAGENAME));
startActivity( launchIntent ); startActivity( launchIntent );
} }

View File

@ -1,27 +0,0 @@
/*
Copyright 2014 Daniele Verducci
This file is part of AndroidExplorerbotServer.
AndroidExplorerbotServer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
AndroidExplorerbotServer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with AndroidExplorerbotServer. If not, see <http://www.gnu.org/licenses/>.
*/
package it.danieleverducci.explorerbotserver;
import it.danieleverducci.explorerbot.objects.GamepadPosition;
public interface OnControllerPolledListener {
public void onControllerPolled(GamepadPosition position);
}

View File

@ -1,64 +0,0 @@
/*
Copyright 2014 Daniele Verducci
This file is part of AndroidExplorerbotServer.
AndroidExplorerbotServer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
AndroidExplorerbotServer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with AndroidExplorerbotServer. If not, see <http://www.gnu.org/licenses/>.
*/
package it.danieleverducci.explorerbotserver;
import it.danieleverducci.explorerbot.objects.GamepadPosition;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerNetworkCommunicationThread extends Thread {
private OnControllerPolledListener listener;
private boolean mustExit=false;
@Override
public void run() {
try {
ServerSocket server = new ServerSocket(AppConfiguration.PORT);
System.out.println("Server started on port "+AppConfiguration.PORT);
Socket client = server.accept();
System.out.println("Client connected");
server.close(); //Once the client is connected, closing the server denies other clients connections
InputStream is = client.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
while(!mustExit){
//Read object and notify new controller position (readObject will return only when there is something to read)
GamepadPosition pos = (GamepadPosition)ois.readObject();
listener.onControllerPolled(pos);
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public void setOnControllerPolledListener(OnControllerPolledListener listener) {
this.listener = listener;
}
public void setMustExit(boolean mustExit) {
this.mustExit = mustExit;
}
}

View File

@ -64,10 +64,12 @@ void loop(){
} }
boolean readGamepadPositionFromSerial(){ boolean readGamepadPositionFromSerial(){
if(Serial.available()>1){ //Bytes received in pairs if(Serial.available()==2){ //Bytes received in pairs
gamepadPosition[0] = Serial.read(); gamepadPosition[0] = Serial.read();
gamepadPosition[1] = Serial.read(); gamepadPosition[1] = Serial.read();
return true; return true;
} else { //Data corruption: even bits!
Serial.readBytes(NULL, Serial.available());
} }
return false; return false;
} }

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ExplorerBotCommonLib</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -53,7 +53,10 @@ public class ClientNetworkCommunicationThread extends Thread {
//Send to network //Send to network
try{ try{
oos.writeObject(lastKnownPosition); oos.writeObject(lastKnownPosition);
oos.flush();
System.out.println(lastKnownPosition.getX()+" - "+lastKnownPosition.getY());
lastKnownPosition=null; lastKnownPosition=null;
oos.reset();
}catch(SocketException e){ }catch(SocketException e){
System.out.println("Connection interrupted by server. Exiting."); System.out.println("Connection interrupted by server. Exiting.");
System.exit(0); System.exit(0);

0
bin/start_client.sh Normal file → Executable file
View File

0
bin/start_server.sh Normal file → Executable file
View File