需要的资料
javadrone api:
http://code.google.com/p/javadrone
使用
javadrone api的一个
Android demo(
ARDrone-on-Android-master
):
https://github.com/UnknownGuardian/ARDrone-on-Android
修改demo
Demo使用了
javadrone api中的ardrone、ardrone/comands、ardrone/video以及
ardrone/util的一部分api,
并使用了
http://code.google.com/p/javadrone
中javadrone-93e27c36a077.zip的中的3个.jar包(
具体哪3个包见
demo的.classpath文件
)。我的目的是修改该demo从而做到Android对ARDrone的基本控制。
Demo中,其实不需要使用
javadrone-93e27c36a077.zip的中的3个.jar包也能顺利build通过,所以直接在
demo
的.classpath文件中删除这3个包的路径,
这样demo和
javadrone-93e27c36a077.zip就没有依赖关系了;其次,
ardrone/util中BufferedImageVideoListener.java
引用了Android SDK的一个早期的包
java.awt.image.BufferedImage,所以该文件始终编译不过,由于目标app暂时不需要处理ardrone的video,所直接把
ardrone/util从demo从工程中删除。做完这些修改后build通过,手机上测试该demo,发现按下
连接ARDrone的按钮AnDrone有相应的反应(LED如代码中的闪烁),连接上后电池状态能获取到(说明Navadata读取正常),但
视频显示是没有的,起飞按钮也很少有效果(好像有效过1次)。
Demo中考虑了视频接收,并增加了一些进度条、图像等控件,这在我的目标里是不需要的,而这些代码可能会影响到控制命令的发送,所以我将demo作一些修改以去掉这些内容。首先修改app界面main.xml,
<?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:orientation= "vertical" >
<TextView
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android: text= "@string/hello"
android: id= "@+id/statusBar"
android:gravity= "center_horizontal"
android: background= "#B1DCFE"
android:textColor= "#000000">
</TextView>
< Button
android: id= "@+id/connectButton"
android: text= "Connect..."
android:layout_width= "match_parent"
android:layout_height= "wrap_content"></ Button>
< Button
android: id= "@+id/launchButton"
android: text= "Take off"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"></ Button>
< Button
android: id= "@+id/hoverButton"
android: text= "Hover"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"></ Button>
<LinearLayout
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:orientation= "horizontal" >
< Button
android: id= "@+id/frontButton"
android: text= "Front"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:layout_weight= "1"></ Button>
< Button
android: id= "@+id/backButton"
android: text= "Back"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:layout_weight= "1"></ Button>
</LinearLayout>
<LinearLayout
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:orientation= "horizontal" >
< Button
android: id= "@+id/leftButton"
android: text= "Left"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:layout_weight= "1"></ Button>
< Button
android: id= "@+id/rightButton"
android: text= "Right"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:layout_weight= "1"></ Button>
</LinearLayout>
<LinearLayout
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:orientation= "horizontal" >
< Button
android: id= "@+id/upButton"
android: text= "Up"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:layout_weight= "1"></ Button>
< Button
android: id= "@+id/downButton"
android: text= "Down"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:layout_weight= "1"></ Button>
</LinearLayout>
<LinearLayout
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:orientation= "horizontal" >
< Button
android: id= "@+id/spin_leftButton"
android: text= "Spin Left"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:layout_weight= "1"></ Button>
< Button
android: id= "@+id/spin_rightButton"
android: text= "Spin Right"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:layout_weight= "1"></ Button>
</LinearLayout>
<TextView
android: id= "@+id/batteryStatusText"
android:gravity= "center_horizontal"
android: text= "Battery Status"
android:textAppearance= "?android:attr/textAppearanceSmall"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"></TextView>
</LinearLayout>
<LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"
android:layout_width= "match_parent"
android:layout_height= "match_parent"
android:orientation= "vertical" >
<TextView
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android: text= "@string/hello"
android: id= "@+id/statusBar"
android:gravity= "center_horizontal"
android: background= "#B1DCFE"
android:textColor= "#000000">
</TextView>
< Button
android: id= "@+id/connectButton"
android: text= "Connect..."
android:layout_width= "match_parent"
android:layout_height= "wrap_content"></ Button>
< Button
android: id= "@+id/launchButton"
android: text= "Take off"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"></ Button>
< Button
android: id= "@+id/hoverButton"
android: text= "Hover"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"></ Button>
<LinearLayout
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:orientation= "horizontal" >
< Button
android: id= "@+id/frontButton"
android: text= "Front"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:layout_weight= "1"></ Button>
< Button
android: id= "@+id/backButton"
android: text= "Back"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:layout_weight= "1"></ Button>
</LinearLayout>
<LinearLayout
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:orientation= "horizontal" >
< Button
android: id= "@+id/leftButton"
android: text= "Left"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:layout_weight= "1"></ Button>
< Button
android: id= "@+id/rightButton"
android: text= "Right"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:layout_weight= "1"></ Button>
</LinearLayout>
<LinearLayout
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:orientation= "horizontal" >
< Button
android: id= "@+id/upButton"
android: text= "Up"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:layout_weight= "1"></ Button>
< Button
android: id= "@+id/downButton"
android: text= "Down"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:layout_weight= "1"></ Button>
</LinearLayout>
<LinearLayout
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:orientation= "horizontal" >
< Button
android: id= "@+id/spin_leftButton"
android: text= "Spin Left"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:layout_weight= "1"></ Button>
< Button
android: id= "@+id/spin_rightButton"
android: text= "Spin Right"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:layout_weight= "1"></ Button>
</LinearLayout>
<TextView
android: id= "@+id/batteryStatusText"
android:gravity= "center_horizontal"
android: text= "Battery Status"
android:textAppearance= "?android:attr/textAppearanceSmall"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"></TextView>
</LinearLayout>
修改后的界面比较简洁,除了一系列按钮就是2个文本框。接下来修改AndroidManifest.xml,
<?xml version=
"1.0" encoding=
"utf-8"?>
< !-- package= "com.codeminders.ardrone.examples" android:versionCode= "1" -->
<manifest xmlns:android= "http://schemas.android.com/apk/res/android"
package= "com.profusiongames" android:versionCode= "1"
android:versionName= "1.0">
<uses-sdk android:minSdkVersion= "8"/>
<application android: icon= "@drawable/icon" android: label= "@string/app_name">
<activity android:name= ".FusionDrone"
android: label= "@string/app_name"
android:configChanges= "orientation|keyboard"
android:screenOrientation= "portrait"
android: theme= "@android:style/Theme.Light.NoTitleBar.Fullscreen">
<intent-filter>
<action android:name= "android.intent.action.MAIN" />
<category android:name= "android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name= "android.permission.INTERNET" />
<uses-permission android:name= "android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name= "android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name= "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name= "android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name= "android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name= "android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name= "android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name= "android.permission.BATTERY_STATS" />
<uses-permission android:name= "android.permission.BLUETOOTH" />
<uses-permission android:name= "android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name= "android.permission.BROADCAST_STICKY" />
<uses-permission android:name= "android.permission.CALL_PHONE" />
<uses-permission android:name= "android.permission.CAMERA" />
<uses-permission android:name= "android.permission.CHANGE_CONFIGURATION" />
<uses-permission android:name= "android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name= "android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name= "android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name= "android.permission.CLEAR_APP_CACHE" />
<uses-permission android:name= "android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name= "android.permission.DUMP" />
<uses-permission android:name= "android.permission.EXPAND_STATUS_BAR" />
<uses-permission android:name= "android.permission.FLASHLIGHT" />
<uses-permission android:name= "android.permission.GET_ACCOUNTS" />
<uses-permission android:name= "android.permission.GET_PACKAGE_SIZE" />
<uses-permission android:name= "android.permission.GET_TASKS" />
<uses-permission android:name= "android.permission.INTERNET" />
<uses-permission android:name= "android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name= "android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name= "android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name= "android.permission.MOUNT_FORMAT_FILESYSTEMS" />
<uses-permission android:name= "android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name= "android.permission.PERSISTENT_ACTIVITY" />
<uses-permission android:name= "android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name= "android.permission.READ_CALENDAR" />
<uses-permission android:name= "android.permission.READ_CONTACTS" />
<uses-permission android:name= "android.permission.READ_LOGS" />
<uses-permission android:name= "android.permission.READ_PHONE_STATE" />
<uses-permission android:name= "android.permission.READ_SMS" />
<uses-permission android:name= "android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name= "android.permission.READ_SYNC_STATS" />
<uses-permission android:name= "android.permission.RECEIVE_MMS" />
<uses-permission android:name= "android.permission.RECEIVE_SMS" />
<uses-permission android:name= "android.permission.RECEIVE_WAP_PUSH" />
<uses-permission android:name= "android.permission.RECORD_AUDIO" />
<uses-permission android:name= "android.permission.REORDER_TASKS" />
<uses-permission android:name= "android.permission.SEND_SMS" />
<uses-permission android:name= "android.permission.SET_ALWAYS_FINISH" />
<uses-permission android:name= "android.permission.SET_ANIMATION_SCALE" />
<uses-permission android:name= "android.permission.SET_DEBUG_APP" />
<uses-permission android:name= "android.permission.SET_PROCESS_LIMIT" />
<uses-permission android:name= "android.permission.SET_TIME_ZONE" />
<uses-permission android:name= "android.permission.SET_WALLPAPER" />
<uses-permission android:name= "android.permission.SET_WALLPAPER_HINTS" />
<uses-permission android:name= "android.permission.SIGNAL_PERSISTENT_PROCESSES" />
<uses-permission android:name= "android.permission.SUBSCRIBED_FEEDS_READ" />
<uses-permission android:name= "android.permission.SUBSCRIBED_FEEDS_WRITE" />
<uses-permission android:name= "android.permission.USE_CREDENTIALS" />
<uses-permission android:name= "android.permission.VIBRATE" />
<uses-permission android:name= "android.permission.WAKE_LOCK" />
<uses-permission android:name= "android.permission.WRITE_APN_SETTINGS" />
<uses-permission android:name= "android.permission.WRITE_CALENDAR" />
<uses-permission android:name= "android.permission.WRITE_CONTACTS" />
<uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name= "android.permission.WRITE_SETTINGS" />
<uses-permission android:name= "android.permission.WRITE_SMS" />
<uses-permission android:name= "android.permission.WRITE_SYNC_SETTINGS" />
</manifest>
< !-- package= "com.codeminders.ardrone.examples" android:versionCode= "1" -->
<manifest xmlns:android= "http://schemas.android.com/apk/res/android"
package= "com.profusiongames" android:versionCode= "1"
android:versionName= "1.0">
<uses-sdk android:minSdkVersion= "8"/>
<application android: icon= "@drawable/icon" android: label= "@string/app_name">
<activity android:name= ".FusionDrone"
android: label= "@string/app_name"
android:configChanges= "orientation|keyboard"
android:screenOrientation= "portrait"
android: theme= "@android:style/Theme.Light.NoTitleBar.Fullscreen">
<intent-filter>
<action android:name= "android.intent.action.MAIN" />
<category android:name= "android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name= "android.permission.INTERNET" />
<uses-permission android:name= "android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name= "android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name= "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name= "android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name= "android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name= "android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name= "android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name= "android.permission.BATTERY_STATS" />
<uses-permission android:name= "android.permission.BLUETOOTH" />
<uses-permission android:name= "android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name= "android.permission.BROADCAST_STICKY" />
<uses-permission android:name= "android.permission.CALL_PHONE" />
<uses-permission android:name= "android.permission.CAMERA" />
<uses-permission android:name= "android.permission.CHANGE_CONFIGURATION" />
<uses-permission android:name= "android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name= "android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name= "android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name= "android.permission.CLEAR_APP_CACHE" />
<uses-permission android:name= "android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name= "android.permission.DUMP" />
<uses-permission android:name= "android.permission.EXPAND_STATUS_BAR" />
<uses-permission android:name= "android.permission.FLASHLIGHT" />
<uses-permission android:name= "android.permission.GET_ACCOUNTS" />
<uses-permission android:name= "android.permission.GET_PACKAGE_SIZE" />
<uses-permission android:name= "android.permission.GET_TASKS" />
<uses-permission android:name= "android.permission.INTERNET" />
<uses-permission android:name= "android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name= "android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name= "android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name= "android.permission.MOUNT_FORMAT_FILESYSTEMS" />
<uses-permission android:name= "android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name= "android.permission.PERSISTENT_ACTIVITY" />
<uses-permission android:name= "android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name= "android.permission.READ_CALENDAR" />
<uses-permission android:name= "android.permission.READ_CONTACTS" />
<uses-permission android:name= "android.permission.READ_LOGS" />
<uses-permission android:name= "android.permission.READ_PHONE_STATE" />
<uses-permission android:name= "android.permission.READ_SMS" />
<uses-permission android:name= "android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name= "android.permission.READ_SYNC_STATS" />
<uses-permission android:name= "android.permission.RECEIVE_MMS" />
<uses-permission android:name= "android.permission.RECEIVE_SMS" />
<uses-permission android:name= "android.permission.RECEIVE_WAP_PUSH" />
<uses-permission android:name= "android.permission.RECORD_AUDIO" />
<uses-permission android:name= "android.permission.REORDER_TASKS" />
<uses-permission android:name= "android.permission.SEND_SMS" />
<uses-permission android:name= "android.permission.SET_ALWAYS_FINISH" />
<uses-permission android:name= "android.permission.SET_ANIMATION_SCALE" />
<uses-permission android:name= "android.permission.SET_DEBUG_APP" />
<uses-permission android:name= "android.permission.SET_PROCESS_LIMIT" />
<uses-permission android:name= "android.permission.SET_TIME_ZONE" />
<uses-permission android:name= "android.permission.SET_WALLPAPER" />
<uses-permission android:name= "android.permission.SET_WALLPAPER_HINTS" />
<uses-permission android:name= "android.permission.SIGNAL_PERSISTENT_PROCESSES" />
<uses-permission android:name= "android.permission.SUBSCRIBED_FEEDS_READ" />
<uses-permission android:name= "android.permission.SUBSCRIBED_FEEDS_WRITE" />
<uses-permission android:name= "android.permission.USE_CREDENTIALS" />
<uses-permission android:name= "android.permission.VIBRATE" />
<uses-permission android:name= "android.permission.WAKE_LOCK" />
<uses-permission android:name= "android.permission.WRITE_APN_SETTINGS" />
<uses-permission android:name= "android.permission.WRITE_CALENDAR" />
<uses-permission android:name= "android.permission.WRITE_CONTACTS" />
<uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name= "android.permission.WRITE_SETTINGS" />
<uses-permission android:name= "android.permission.WRITE_SMS" />
<uses-permission android:name= "android.permission.WRITE_SYNC_SETTINGS" />
</manifest>
主要修改了
android:screenOrientation
项(landscape->portrait),使app界面从横屏变为竖屏。最后,修改的是响应控件的java代码FusionDrone.java,
package com.profusiongames
;
import java.io.IOException ;
import android.app.Activity ;
import android.hardware.Sensor ;
import android.hardware.SensorEvent ;
import android.hardware.SensorEventListener ;
import android.hardware.SensorManager ;
import android.os.AsyncTask ;
import android.os.Bundle ;
import android.util. Log ;
import android.view.View ;
import android.view.Window ;
import android.widget. Button ;
//import android.widget.ProgressBar ;
import android.widget.TextView ;
import com.codeminders.ardrone.ARDrone ;
import com.codeminders.ardrone.NavData ;
import com.codeminders.ardrone.NavDataListener ;
public class FusionDrone extends Activity implements NavDataListener,SensorEventListener {
private static FusionDrone fDrone ;
private static ARDrone drone ;
private static SensorManager sensorManager ;
private static boolean isConnected = false ;
private static boolean isFlying = false ;
private int batteryLife = 0 ;
public static int queueToShow = 0 ;
/* Components */
@SuppressWarnings( "unused")
private TextView statusBar ;
private Button connectionButton ;
private Button launchButton ;
private Button hoverButton ;
private Button frontButton ;
private Button backButton ;
private Button leftButton ;
private Button rightButton ;
private Button upButton ;
private Button downButton ;
private Button spin_leftButton ;
private Button spin_rightButton ;
private TextView batteryText ;
/* Components */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
requestWindowFeature(Window.FEATURE_NO_TITLE) ;
setContentView(R.layout.main) ;
fDrone = this ;
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE) ;
getUIComponents() ;
}
@Override
protected void onResume() {
super.onResume() ;
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), 3) ;
}
@Override
protected void onPause() {
super.onPause() ;
sensorManager.unregisterListener(this) ;
}
@Override
protected void onStop() {
super.onStop() ;
sensorManager.unregisterListener(this) ;
try {
if(drone != null)
{
drone.clearImageListeners() ;
drone.clearNavDataListeners() ;
drone.clearStatusChangeListeners() ;
drone.clearStatusChangeListeners() ;
drone.disconnect() ;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace() ;
}
}
private void getUIComponents() {
statusBar = (TextView) findViewById(R. id. statusBar) ;
connectionButton = ( Button) findViewById(R. id.connectButton) ;
connectionButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Connection button") ;
if ( !isConnected) {
connectionButton.setEnabled( false) ;
connectionButton.setText( "Connecting...") ;
(new DroneStarter()).execute(FusionDrone.drone) ;
} else {
if(isFlying) { try { drone.land(); Thread.sleep(400);}
import java.io.IOException ;
import android.app.Activity ;
import android.hardware.Sensor ;
import android.hardware.SensorEvent ;
import android.hardware.SensorEventListener ;
import android.hardware.SensorManager ;
import android.os.AsyncTask ;
import android.os.Bundle ;
import android.util. Log ;
import android.view.View ;
import android.view.Window ;
import android.widget. Button ;
//import android.widget.ProgressBar ;
import android.widget.TextView ;
import com.codeminders.ardrone.ARDrone ;
import com.codeminders.ardrone.NavData ;
import com.codeminders.ardrone.NavDataListener ;
public class FusionDrone extends Activity implements NavDataListener,SensorEventListener {
private static FusionDrone fDrone ;
private static ARDrone drone ;
private static SensorManager sensorManager ;
private static boolean isConnected = false ;
private static boolean isFlying = false ;
private int batteryLife = 0 ;
public static int queueToShow = 0 ;
/* Components */
@SuppressWarnings( "unused")
private TextView statusBar ;
private Button connectionButton ;
private Button launchButton ;
private Button hoverButton ;
private Button frontButton ;
private Button backButton ;
private Button leftButton ;
private Button rightButton ;
private Button upButton ;
private Button downButton ;
private Button spin_leftButton ;
private Button spin_rightButton ;
private TextView batteryText ;
/* Components */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
requestWindowFeature(Window.FEATURE_NO_TITLE) ;
setContentView(R.layout.main) ;
fDrone = this ;
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE) ;
getUIComponents() ;
}
@Override
protected void onResume() {
super.onResume() ;
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), 3) ;
}
@Override
protected void onPause() {
super.onPause() ;
sensorManager.unregisterListener(this) ;
}
@Override
protected void onStop() {
super.onStop() ;
sensorManager.unregisterListener(this) ;
try {
if(drone != null)
{
drone.clearImageListeners() ;
drone.clearNavDataListeners() ;
drone.clearStatusChangeListeners() ;
drone.clearStatusChangeListeners() ;
drone.disconnect() ;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace() ;
}
}
private void getUIComponents() {
statusBar = (TextView) findViewById(R. id. statusBar) ;
connectionButton = ( Button) findViewById(R. id.connectButton) ;
connectionButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Connection button") ;
if ( !isConnected) {
connectionButton.setEnabled( false) ;
connectionButton.setText( "Connecting...") ;
(new DroneStarter()).execute(FusionDrone.drone) ;
} else {
if(isFlying) { try { drone.land(); Thread.sleep(400);}
catch (Exception e) {e.printStackTrace();}
}
//if going to disconnect, but still flying, attempt to tell drone to land
connectionButton.setEnabled(
false)
;
connectionButton.setText( "Disconnecting...") ;
(new DroneEnder()).execute(FusionDrone.drone) ;
}
}
}) ;
launchButton = ( Button)findViewById(R. id.launchButton) ;
launchButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Launch button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone.land(); launchButton.setText("Takeoff"); isFlying = false;}
catch (IOException e) {e.printStackTrace();}
} else {
try { drone.takeOff(); launchButton.setText("Land"); isFlying = true;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
hoverButton = ( Button)findViewById(R. id.hoverButton) ;
hoverButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Hover button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone.hover() ;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
frontButton = ( Button)findViewById(R. id.frontButton) ;
frontButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Front button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone. move(( float) 0. 0,( float)- 0. 05,( float) 0. 0,( float) 0. 0) ;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
backButton = ( Button)findViewById(R. id.backButton) ;
backButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Back button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone. move(( float) 0. 0,( float) 0. 05,( float) 0. 0,( float) 0. 0) ;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
leftButton = ( Button)findViewById(R. id.leftButton) ;
leftButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Left button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone. move(( float)- 0. 05,( float) 0. 0,( float) 0. 0,( float) 0. 0) ;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
rightButton = ( Button)findViewById(R. id.rightButton) ;
rightButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Right button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone. move(( float) 0. 05,( float) 0. 0,( float) 0. 0,( float) 0. 0) ;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
upButton = ( Button)findViewById(R. id.upButton) ;
upButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Up button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone. move(( float) 0. 0,( float) 0. 0,( float) 0. 05,( float) 0. 0) ;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
downButton = ( Button)findViewById(R. id.downButton) ;
downButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Down button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone. move(( float) 0. 0,( float) 0. 0,( float)- 0. 05,( float) 0. 0) ;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
spin_leftButton = ( Button)findViewById(R. id.spin_leftButton) ;
spin_leftButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Spin Left button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone. move(( float) 0. 0,( float) 0. 0,( float) 0. 0,( float)- 0. 05) ;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
spin_rightButton = ( Button)findViewById(R. id.spin_rightButton) ;
spin_rightButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Spin Right button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone. move(( float) 0. 0,( float) 0. 0,( float) 0. 0,( float) 0. 05) ;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
batteryText = (TextView) findViewById(R. id.batteryStatusText) ;
}
/*public static ARDrone getARDrone() {
return drone;
}
public static FusionDrone getFusionDrone() {
return fDrone;
}*/
@Override
public void navDataReceived(NavData nd) {
//NavData.printState(nd) ;
// Log.v( "DRONE", nd.getVisionTags().toString()) ;
if(nd.getVisionTags() != null)
{
Log.v( "DRONE", nd.getVisionTags().toString()) ;
}
batteryLife = nd.getBattery() ;
runOnUiThread(new Runnable() {
public void run() {
batteryText.setText( "Battery Life: " + batteryLife + "%") ;
}
}) ;
}
/********************* The following is a must***********************/
private float sensorThreshold = 3 ;
private double startX = - 1f ;
private double startY = - 1f ;
private double startZ = - 1f ;
@Override
public void onSensorChanged(SensorEvent e) {
if(Math. random() < 1) return ;
Log.v( "DRONE", "sensor: " + e.sensor + ", x: " + MathUtil.trunk(e.values[ 0]) + ", y: " + MathUtil.trunk(e.values[ 1]) + ", z: " + MathUtil.trunk(e.values[ 2])) ;
if(startX == - 1f)
{
startX = e.values[ 0] ;
startY = e.values[ 1] ;
startZ = e.values[ 2] ;
}
float shortX = MathUtil.trunk(MathUtil.getShortestAngle(e.values[ 0],( float) startX)) ;
float shortY = MathUtil.trunk(MathUtil.getShortestAngle(e.values[ 1],( float) startY)) ;
float shortZ = MathUtil.trunk(MathUtil.getShortestAngle(e.values[ 2],( float) startZ)) ;
if( MathUtil. abs(shortX) < sensorThreshold) shortX = 0 ;// do nothing
if( MathUtil. abs(shortY) < sensorThreshold) shortY = 0 ;// do nothing
if( MathUtil. abs(shortZ) < sensorThreshold) shortZ = 0 ;// do nothing
Log.v( "DRONE", "sensor difference: x: " + shortX + ", y: " + shortY + ", z: " + shortZ) ;
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
// Log.v( "DRONE", "Accuracy changed: " + accuracy) ;
}
/*********************************************************************/
private class DroneStarter extends AsyncTask<ARDrone, Integer, Boolean> {
private static final int CONNECTION_TIMEOUT = 3000 ;
@Override
protected Boolean doInBackground(ARDrone... drones) {
ARDrone drone = drones[ 0] ;
try {
drone = new ARDrone() ;
FusionDrone.drone = drone ; // passing in null objects will not pass object refs
drone.connect() ;
drone.clearEmergencySignal() ;
drone.waitForReady(CONNECTION_TIMEOUT) ;
drone.playLED( 1, 10, 4) ;
drone.addNavDataListener(FusionDrone.fDrone) ;
//drone.selectVideoChannel(ARDrone.VideoChannel.HORIZONTAL_ONLY) ;
//try {
//drone.sendTagDetectionOnData() ;
//drone.sendVideoOnData() ;
//drone.enableAutomaticVideoBitrate() ;
//}
//catch(Exception e) { e.printStackTrace() ;}
Log.v( "DRONE", "Connected to ARDrone" + FusionDrone.drone) ;
return true ;
} catch (Exception e) {
e.printStackTrace() ;
try {
drone.clearEmergencySignal() ;
//drone.clearImageListeners() ;
drone.clearNavDataListeners() ;
drone.clearStatusChangeListeners() ;
drone.disconnect() ;
} catch (Exception e1) {
e1.printStackTrace() ;
}
Log.v( "DRONE", "Caught exception. Connection time out." + FusionDrone.drone) ;
}
return false ;
}
protected void onPostExecute(Boolean success) {
if (success.booleanValue()) {
connectionButton.setText( "Disconnect...") ;
} else {
connectionButton.setText( "Error 1. Retry?") ;
}
isConnected = success.booleanValue() ;
connectionButton.setEnabled( true) ;
//connectionWhirlProgress.setVisibility( Button.INVISIBLE) ;
}
}
private class DroneEnder extends AsyncTask<ARDrone, Integer, Boolean> {
@Override
protected Boolean doInBackground(ARDrone... drones) {
ARDrone drone = drones[ 0] ;
try {
drone.playLED( 2, 10, 4) ;
drone.clearEmergencySignal() ;
//drone.clearImageListeners() ;
drone.clearNavDataListeners() ;
drone.clearStatusChangeListeners() ;
drone.disconnect() ;
Log.v( "DRONE", "Disconnected to ARDrone" + FusionDrone.drone) ;
return true ;
} catch (Exception e) {
e.printStackTrace() ;
try {
drone.clearEmergencySignal() ;
//drone.clearImageListeners() ;
drone.clearNavDataListeners() ;
drone.clearStatusChangeListeners() ;
drone.disconnect() ;
} catch (Exception e1) {
e1.printStackTrace() ;
}
Log.v( "DRONE", "Caught exception. Disconnection error.") ;
}
return false ;
}
protected void onPostExecute(Boolean success) {
if (success.booleanValue()) {
connectionButton.setText( "Connect...") ;
connectionButton.setEnabled( true) ;
batteryText.setText( "Battery Status") ;
} else {
connectionButton.setText( "Error 2. Retry?") ;
}
isConnected = !success.booleanValue() ;
}
}
}
connectionButton.setText( "Disconnecting...") ;
(new DroneEnder()).execute(FusionDrone.drone) ;
}
}
}) ;
launchButton = ( Button)findViewById(R. id.launchButton) ;
launchButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Launch button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone.land(); launchButton.setText("Takeoff"); isFlying = false;}
catch (IOException e) {e.printStackTrace();}
} else {
try { drone.takeOff(); launchButton.setText("Land"); isFlying = true;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
hoverButton = ( Button)findViewById(R. id.hoverButton) ;
hoverButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Hover button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone.hover() ;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
frontButton = ( Button)findViewById(R. id.frontButton) ;
frontButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Front button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone. move(( float) 0. 0,( float)- 0. 05,( float) 0. 0,( float) 0. 0) ;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
backButton = ( Button)findViewById(R. id.backButton) ;
backButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Back button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone. move(( float) 0. 0,( float) 0. 05,( float) 0. 0,( float) 0. 0) ;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
leftButton = ( Button)findViewById(R. id.leftButton) ;
leftButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Left button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone. move(( float)- 0. 05,( float) 0. 0,( float) 0. 0,( float) 0. 0) ;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
rightButton = ( Button)findViewById(R. id.rightButton) ;
rightButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Right button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone. move(( float) 0. 05,( float) 0. 0,( float) 0. 0,( float) 0. 0) ;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
upButton = ( Button)findViewById(R. id.upButton) ;
upButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Up button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone. move(( float) 0. 0,( float) 0. 0,( float) 0. 05,( float) 0. 0) ;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
downButton = ( Button)findViewById(R. id.downButton) ;
downButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Down button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone. move(( float) 0. 0,( float) 0. 0,( float)- 0. 05,( float) 0. 0) ;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
spin_leftButton = ( Button)findViewById(R. id.spin_leftButton) ;
spin_leftButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Spin Left button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone. move(( float) 0. 0,( float) 0. 0,( float) 0. 0,( float)- 0. 05) ;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
spin_rightButton = ( Button)findViewById(R. id.spin_rightButton) ;
spin_rightButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.v( "DRONE", "Clicked Spin Right button") ;
if ( !isConnected) {
//do nothing
} else if(isFlying) {
try { drone. move(( float) 0. 0,( float) 0. 0,( float) 0. 0,( float) 0. 05) ;}
catch (IOException e) {e.printStackTrace() ;}
}
}
}) ;
batteryText = (TextView) findViewById(R. id.batteryStatusText) ;
}
/*public static ARDrone getARDrone() {
return drone;
}
public static FusionDrone getFusionDrone() {
return fDrone;
}*/
@Override
public void navDataReceived(NavData nd) {
//NavData.printState(nd) ;
// Log.v( "DRONE", nd.getVisionTags().toString()) ;
if(nd.getVisionTags() != null)
{
Log.v( "DRONE", nd.getVisionTags().toString()) ;
}
batteryLife = nd.getBattery() ;
runOnUiThread(new Runnable() {
public void run() {
batteryText.setText( "Battery Life: " + batteryLife + "%") ;
}
}) ;
}
/********************* The following is a must***********************/
private float sensorThreshold = 3 ;
private double startX = - 1f ;
private double startY = - 1f ;
private double startZ = - 1f ;
@Override
public void onSensorChanged(SensorEvent e) {
if(Math. random() < 1) return ;
Log.v( "DRONE", "sensor: " + e.sensor + ", x: " + MathUtil.trunk(e.values[ 0]) + ", y: " + MathUtil.trunk(e.values[ 1]) + ", z: " + MathUtil.trunk(e.values[ 2])) ;
if(startX == - 1f)
{
startX = e.values[ 0] ;
startY = e.values[ 1] ;
startZ = e.values[ 2] ;
}
float shortX = MathUtil.trunk(MathUtil.getShortestAngle(e.values[ 0],( float) startX)) ;
float shortY = MathUtil.trunk(MathUtil.getShortestAngle(e.values[ 1],( float) startY)) ;
float shortZ = MathUtil.trunk(MathUtil.getShortestAngle(e.values[ 2],( float) startZ)) ;
if( MathUtil. abs(shortX) < sensorThreshold) shortX = 0 ;// do nothing
if( MathUtil. abs(shortY) < sensorThreshold) shortY = 0 ;// do nothing
if( MathUtil. abs(shortZ) < sensorThreshold) shortZ = 0 ;// do nothing
Log.v( "DRONE", "sensor difference: x: " + shortX + ", y: " + shortY + ", z: " + shortZ) ;
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
// Log.v( "DRONE", "Accuracy changed: " + accuracy) ;
}
/*********************************************************************/
private class DroneStarter extends AsyncTask<ARDrone, Integer, Boolean> {
private static final int CONNECTION_TIMEOUT = 3000 ;
@Override
protected Boolean doInBackground(ARDrone... drones) {
ARDrone drone = drones[ 0] ;
try {
drone = new ARDrone() ;
FusionDrone.drone = drone ; // passing in null objects will not pass object refs
drone.connect() ;
drone.clearEmergencySignal() ;
drone.waitForReady(CONNECTION_TIMEOUT) ;
drone.playLED( 1, 10, 4) ;
drone.addNavDataListener(FusionDrone.fDrone) ;
//drone.selectVideoChannel(ARDrone.VideoChannel.HORIZONTAL_ONLY) ;
//try {
//drone.sendTagDetectionOnData() ;
//drone.sendVideoOnData() ;
//drone.enableAutomaticVideoBitrate() ;
//}
//catch(Exception e) { e.printStackTrace() ;}
Log.v( "DRONE", "Connected to ARDrone" + FusionDrone.drone) ;
return true ;
} catch (Exception e) {
e.printStackTrace() ;
try {
drone.clearEmergencySignal() ;
//drone.clearImageListeners() ;
drone.clearNavDataListeners() ;
drone.clearStatusChangeListeners() ;
drone.disconnect() ;
} catch (Exception e1) {
e1.printStackTrace() ;
}
Log.v( "DRONE", "Caught exception. Connection time out." + FusionDrone.drone) ;
}
return false ;
}
protected void onPostExecute(Boolean success) {
if (success.booleanValue()) {
connectionButton.setText( "Disconnect...") ;
} else {
connectionButton.setText( "Error 1. Retry?") ;
}
isConnected = success.booleanValue() ;
connectionButton.setEnabled( true) ;
//connectionWhirlProgress.setVisibility( Button.INVISIBLE) ;
}
}
private class DroneEnder extends AsyncTask<ARDrone, Integer, Boolean> {
@Override
protected Boolean doInBackground(ARDrone... drones) {
ARDrone drone = drones[ 0] ;
try {
drone.playLED( 2, 10, 4) ;
drone.clearEmergencySignal() ;
//drone.clearImageListeners() ;
drone.clearNavDataListeners() ;
drone.clearStatusChangeListeners() ;
drone.disconnect() ;
Log.v( "DRONE", "Disconnected to ARDrone" + FusionDrone.drone) ;
return true ;
} catch (Exception e) {
e.printStackTrace() ;
try {
drone.clearEmergencySignal() ;
//drone.clearImageListeners() ;
drone.clearNavDataListeners() ;
drone.clearStatusChangeListeners() ;
drone.disconnect() ;
} catch (Exception e1) {
e1.printStackTrace() ;
}
Log.v( "DRONE", "Caught exception. Disconnection error.") ;
}
return false ;
}
protected void onPostExecute(Boolean success) {
if (success.booleanValue()) {
connectionButton.setText( "Connect...") ;
connectionButton.setEnabled( true) ;
batteryText.setText( "Battery Status") ;
} else {
connectionButton.setText( "Error 2. Retry?") ;
}
isConnected = !success.booleanValue() ;
}
}
}
代码中,按键响应和Navadata接受保留下来并做扩充,视频和其他控件的内容一律删除掉。
这下,整个代码就整洁很多了,build通过后,在真机上测试,效果比原来demo好多了(demo只有连接ardrone按键比较灵敏,其他都基本没效果;现在按键基本都有相应的效果了)。
参考:
http://code.google.com/p/javadrone/source/browse/src/com/codeminders/ardrone/examples/RotationSnapshotTaker.java?r=faeae1f020fa6399b5261e8d3fd6e1a44be9f834(一个javadrone控制api的使用例子)