Android app updated (now the Android app acts even as client using the
device's accelerometers).
This commit is contained in:
parent
ecb44abd7a
commit
8aa13953ee
@ -1,14 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="it.danieleverducci.explorerbotserver"
|
||||
package="it.danieleverducci.explorerbot"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="14"
|
||||
android:minSdkVersion="1"
|
||||
android:targetSdkVersion="19" />
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
|
||||
<uses-permission android:name="android.permission.INTERNET" >
|
||||
</uses-permission>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
@ -16,19 +17,32 @@
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme" >
|
||||
<activity
|
||||
android:name="it.danieleverducci.explorerbotserver.MainActivity"
|
||||
android:label="@string/app_name" >
|
||||
android:name="it.danieleverducci.explorerbot.MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:screenOrientation="portrait" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</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
|
||||
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
|
||||
android:resource="@xml/device_filter" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name="it.danieleverducci.explorerbot.client.ClientActivity"
|
||||
android:label="@string/app_name"
|
||||
android:screenOrientation="landscape" >
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -1,14 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="it.danieleverducci.explorerbotserver"
|
||||
package="it.danieleverducci.explorerbot"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="14"
|
||||
android:minSdkVersion="1"
|
||||
android:targetSdkVersion="19" />
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
|
||||
<uses-permission android:name="android.permission.INTERNET" >
|
||||
</uses-permission>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
@ -16,19 +17,32 @@
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme" >
|
||||
<activity
|
||||
android:name="it.danieleverducci.explorerbotserver.MainActivity"
|
||||
android:label="@string/app_name" >
|
||||
android:name="it.danieleverducci.explorerbot.MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:screenOrientation="portrait" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</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
|
||||
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
|
||||
android:resource="@xml/device_filter" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name="it.danieleverducci.explorerbot.client.ClientActivity"
|
||||
android:label="@string/app_name"
|
||||
android:screenOrientation="landscape" >
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
Binary file not shown.
Binary file not shown.
BIN
AndroidExplorerbotServer/ic_launcher.png
Normal file
BIN
AndroidExplorerbotServer/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.8 KiB |
Binary file not shown.
3
AndroidExplorerbotServer/lint.xml
Normal file
3
AndroidExplorerbotServer/lint.xml
Normal file
@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<lint>
|
||||
</lint>
|
BIN
AndroidExplorerbotServer/res/drawable-hdpi/ic_hardware_phone.png
Normal file
BIN
AndroidExplorerbotServer/res/drawable-hdpi/ic_hardware_phone.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 568 B |
BIN
AndroidExplorerbotServer/res/drawable-mdpi/ic_hardware_phone.png
Normal file
BIN
AndroidExplorerbotServer/res/drawable-mdpi/ic_hardware_phone.png
Normal file
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 |
29
AndroidExplorerbotServer/res/layout/activity_client.xml
Normal file
29
AndroidExplorerbotServer/res/layout/activity_client.xml
Normal 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>
|
@ -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_height="match_parent" >
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image"
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="#FF000000"
|
||||
android:orientation="vertical"
|
||||
android:padding="30dp" >
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/startServer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_hardware_phone"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<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: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/text"
|
||||
android:layout_width="wrap_content"
|
||||
<EditText
|
||||
android:id="@+id/ipAddressEditText"
|
||||
android:layout_width="100dp"
|
||||
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" />
|
||||
android:background="#FFC0C0C0"
|
||||
android:layout_margin="10dp" >
|
||||
|
||||
<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" />
|
||||
<requestFocus />
|
||||
</EditText>
|
||||
|
||||
<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" />
|
||||
</LinearLayout>
|
||||
|
||||
<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" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
62
AndroidExplorerbotServer/res/layout/activity_server.xml
Normal file
62
AndroidExplorerbotServer/res/layout/activity_server.xml
Normal 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>
|
@ -5,5 +5,7 @@
|
||||
<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="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>
|
||||
|
@ -16,10 +16,9 @@
|
||||
along with AndroidExplorerbotServer. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package it.danieleverducci.explorerbotserver;
|
||||
package it.danieleverducci.explorerbot;
|
||||
|
||||
public class AppConfiguration {
|
||||
public static final int PORT=6787; //The default server port
|
||||
public class AndroidAppConfiguration extends AppConfiguration {
|
||||
public static final boolean LOG_ENABLED=false;
|
||||
public static final String DEFAULT_IPCAMERA_APP_PACKAGENAME="com.pas.webcam";
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -16,8 +16,9 @@
|
||||
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 java.io.IOException;
|
||||
@ -34,15 +35,15 @@ public class SerialCommunication {
|
||||
private boolean connected=false;
|
||||
private UsbSerialDriver driver;
|
||||
|
||||
public SerialCommunication(MainActivity context) {
|
||||
if(AppConfiguration.LOG_ENABLED) Log.d(this.getClass().toString(),"Searcing for Arduino: ");
|
||||
public SerialCommunication(Context context) {
|
||||
if(AndroidAppConfiguration.LOG_ENABLED) Log.d(this.getClass().toString(),"Searcing for Arduino: ");
|
||||
|
||||
//Find first port
|
||||
UsbManager manager = (UsbManager)context.getSystemService(Context.USB_SERVICE);
|
||||
driver = UsbSerialProber.acquire(manager);
|
||||
|
||||
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;
|
||||
try {
|
||||
driver.setBaudRate(9600);
|
||||
@ -50,7 +51,7 @@ public class SerialCommunication {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
@ -66,7 +67,7 @@ public class SerialCommunication {
|
||||
data[0] = (byte)((pos.getX()+1)*63);//x
|
||||
data[1] = (byte)((pos.getY()+1)*63);//y
|
||||
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());
|
||||
}
|
||||
|
||||
/**
|
@ -16,8 +16,11 @@
|
||||
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 java.io.IOException;
|
||||
@ -28,15 +31,17 @@ import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
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 ServerNetworkCommunicationThread sct;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle 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
|
||||
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
|
||||
*/
|
||||
private void launchStreamingApp() {
|
||||
Intent launchIntent = getPackageManager().getLaunchIntentForPackage(AppConfiguration.DEFAULT_IPCAMERA_APP_PACKAGENAME);
|
||||
if(launchIntent==null) launchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + 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=" + AndroidAppConfiguration.DEFAULT_IPCAMERA_APP_PACKAGENAME));
|
||||
startActivity( launchIntent );
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -64,10 +64,12 @@ void loop(){
|
||||
}
|
||||
|
||||
boolean readGamepadPositionFromSerial(){
|
||||
if(Serial.available()>1){ //Bytes received in pairs
|
||||
if(Serial.available()==2){ //Bytes received in pairs
|
||||
gamepadPosition[0] = Serial.read();
|
||||
gamepadPosition[1] = Serial.read();
|
||||
return true;
|
||||
} else { //Data corruption: even bits!
|
||||
Serial.readBytes(NULL, Serial.available());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
17
ExplorerBotCommonLib/.project
Normal file
17
ExplorerBotCommonLib/.project
Normal 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>
|
@ -53,7 +53,10 @@ public class ClientNetworkCommunicationThread extends Thread {
|
||||
//Send to network
|
||||
try{
|
||||
oos.writeObject(lastKnownPosition);
|
||||
oos.flush();
|
||||
System.out.println(lastKnownPosition.getX()+" - "+lastKnownPosition.getY());
|
||||
lastKnownPosition=null;
|
||||
oos.reset();
|
||||
}catch(SocketException e){
|
||||
System.out.println("Connection interrupted by server. Exiting.");
|
||||
System.exit(0);
|
0
bin/start_client.sh
Normal file → Executable file
0
bin/start_client.sh
Normal file → Executable file
0
bin/start_server.sh
Normal file → Executable file
0
bin/start_server.sh
Normal file → Executable file
Loading…
Reference in New Issue
Block a user