Программирование приложений на android
Создана: 31 Октября 2011 Пон 13:25:33.
Раздел: "Компьютерный раздел"
Сообщений в теме: 223, просмотров: 35235
-
-
Вот проект на java, управление AR.DRONE с помощью джойстика
Ознакомиться
[внешняя ссылка]
Скачать исходный файлы
[внешняя ссылка] -
Алгоритм получения данных с ARDrone. Например : заряд аккумулятора, скорость, высота и так далее
1. Отправляем 4 байта {0x01, 0x00, 0x00, 0x00} на порт 5554
2. Отправляем команду AT*CONFIG=" + 1 + ",\"general:navdata_demo\",\"TRUE\" на порт 5556
3. Принимаем данные и выбираем из них нужные. Данные структурированы
Код: /*
* Принимаем данные NavData
*/
import java.net.*;
import java.util.*;
public class Test {
/**
* @param args
*/
static final int NAVDATA_PORT = 5554;
static final int AT_PORT = 5556;
//NavData offset
static final int NAVDATA_STATE = 4;
static final int NAVDATA_BATTERY = 24;
static final int NAVDATA_ALTITUDE = 40;
int seq = 1; //Send AT command with sequence number 1 will reset the counter
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
InetAddress inet_addr;
DatagramSocket socket_at;
DatagramSocket socket_nav;
int cnt = 0;
// Создаем значение для переменной ip_addr
String ip = "192.168.1.1";
StringTokenizer st = new StringTokenizer(ip, ".");
byte[] ip_bytes = new byte[4];
if (st.countTokens() == 4){
for (int i = 0; i < 4; i++){
ip_bytes[i] = (byte)Integer.parseInt(st.nextToken());
}
}
inet_addr = InetAddress.getByAddress(ip_bytes);
socket_at = new DatagramSocket(AT_PORT);
socket_at.setSoTimeout(3000);
socket_nav = new DatagramSocket(NAVDATA_PORT);
socket_nav.setSoTimeout(3000);
try {
// создаем содержимое пакета для отправки на NAVDATA_PORT
byte[] buf_snd = {0x01, 0x00, 0x00, 0x00};
// создаем пакет
DatagramPacket packet_snd = new DatagramPacket(buf_snd, buf_snd.length, inet_addr, NAVDATA_PORT);
// отправляем пакет
socket_nav.send(packet_snd);
System.out.println("Sent trigger flag to UDP port " + NAVDATA_PORT);
// создаем новый пакет для отправки на AT_PORT
String at_cmd="AT*CONFIG=" + 1 + ",\"general:navdata_demo\",\"TRUE\"";
byte[] buf_snd_1 = (at_cmd + "\r").getBytes();
DatagramPacket packet_snd_1 = new DatagramPacket(buf_snd_1, buf_snd_1.length, inet_addr, AT_PORT);
socket_at.send(packet_snd_1);
// Получаем сообщение с NAVDATA_PORT
byte[] buf_rcv = new byte[10240];
DatagramPacket packet_rcv = new DatagramPacket(buf_rcv, buf_rcv.length);
while(true) {
try {
socket_nav.receive(packet_rcv);
cnt++;
if (cnt >= 2) {
cnt = 0;
System.out.println("NavData Received: " + packet_rcv.getLength() + " bytes");
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 4; i++) {
String tmp = Integer.toHexString(((int) buf_rcv[NAVDATA_BATTERY + i]) & 0xFF);
for(int t = tmp.length();t<2;t++)
{
sb.append("0");
}
sb.append(tmp);
sb.append(" ");
}
int tmp_1 = 0, n = 0;
System.out.println("get_int(): data = " + sb);
for (int i=3; i>=0; i—) {
n <<= 8;
tmp_1 = buf_rcv[NAVDATA_BATTERY + i] & 0xFF;
n |= tmp_1;
}
System.out.println("Battery: " + n);
}
} catch(SocketTimeoutException ex3) {
System.out.println("socket_nav.receive(): Timeout");
} catch(Exception ex1) {
ex1.printStackTrace();
}
}
} catch(Exception ex2) {
ex2.printStackTrace();
}
}
}
В этой теме есть обсуждение принимаемых данных
[внешняя ссылка] -
Есть два случая когда счетчик номера команд (sequence counter) должен быть сброшен клиентом drone
1. drone не получает трафика в течение более 50 мс, будет установлен бит ARDRONE_COM_WATCHDOG_MASK в поле ardrone_state (2-е поле) пакета navdata. Чтобы выйти из этого режима, клиент должен послать AT-команду AT * COMWDG.
2. drone не получает трафика более чем 2000 мс, будет остановлена связь с клиентом, и установлен бит ARDRONE_COM_LOST_MASK. Клиент должен повторно инициализировать связь с drone.
ARDrone_Developer_Guide, стр. 40 -
Вот эта программа умеет принимать данные и летать
Осталось джойстик добавить для android
Author: MAPGPS, я только немного отредактировал
Код: import java.awt.Frame;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.*;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.*;
public class Test1 extends Frame implements KeyListener{
/**
* @param args
*/
static final int NAVDATA_PORT = 5554;
static final int AT_PORT = 5556;
//NavData offset
static final int NAVDATA_STATE = 4;
static final int NAVDATA_BATTERY = 24;
static final int NAVDATA_PITCH = 28;
static final int NAVDATA_ROLL = 32;
static final int NAVDATA_YAW = 36;
static final int NAVDATA_ALTITUDE = 40;
static final int NAVDATA_VX = 44;
static final int NAVDATA_VY = 48;
static final int NAVDATA_VZ = 52;
static final int MYKONOS_TRIM_COMMAND_MASK = 1 << 7; /*!< Trim command ACK : (0) None, (1) one received */
static final int MYKONOS_TRIM_RUNNING_MASK = 1 << 8; /*!< Trim running : (0) none, (1) running */
static final int MYKONOS_TRIM_RESULT_MASK = 1 << 9; /*!< Trim result : (0) failed, (1) succeeded */
static final int MYKONOS_ANGLES_OUT_OF_RANGE = 1 << 19; /*!< Angles : (0) Ok, (1) out of range */
static final int MYKONOS_WIND_MASK = 1 << 20; /*!< Wind : (0) Ok, (1) too much to fly */
static final int MYKONOS_ULTRASOUND_MASK = 1 << 21; /*!< Ultrasonic sensor : (0) Ok, (1) deaf */
static final int MYKONOS_CUTOUT_MASK = 1 << 22; /*!< Cutout system detection : (0) Not detected, (1) detected */
static final int MYKONOS_COM_WATCHDOG_MASK = 1 << 30; /*!< Communication Watchdog : (1) com problem, (0) Com is ok */
static final int MYKONOS_EMERGENCY_MASK = 1 << 31; /*!< Emergency landing : (0) no emergency, (1) emergency */
static InetAddress inet_addr;
static String at_cmd_last = "";
static int seq = 1; //Send AT command with sequence number 1 will reset the counter
final static int INTERVAL = 100;
float speed = (float)0.1;
boolean shift = false;
FloatBuffer fb;
IntBuffer ib;
boolean space_bar = false; //true = Takeoff, false = Landing
static float attitude_pitch, attitude_roll, attitude_yaw;
static DatagramSocket socket_at;
static DatagramSocket socket_nav;
public Test1(String name, String args[], InetAddress inet_addr) throws Exception {
super(name);
System.out.println("Speed: " + speed);
addKeyListener(this);
setSize(320, 160);
setVisible(true);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
int cnt = 0;
// Создаем значение для переменной ip_addr
String ip = "192.168.1.1";
StringTokenizer st = new StringTokenizer(ip, ".");
byte[] ip_bytes = new byte[4];
if (st.countTokens() == 4){
for (int i = 0; i < 4; i++){
ip_bytes[i] = (byte)Integer.parseInt(st.nextToken());
}
}
inet_addr = InetAddress.getByAddress(ip_bytes);
socket_at = new DatagramSocket(AT_PORT);
socket_at.setSoTimeout(3000);
socket_nav = new DatagramSocket(NAVDATA_PORT);
socket_nav.setSoTimeout(3000);
try {
// создаем содержимое пакета для отправки на NAVDATA_PORT
byte[] buf_snd = {0x01, 0x00, 0x00, 0x00};
// создаем пакет
DatagramPacket packet_snd = new DatagramPacket(buf_snd, buf_snd.length, inet_addr, NAVDATA_PORT);
// отправляем пакет
socket_nav.send(packet_snd);
System.out.println("Sent trigger flag to UDP port " + NAVDATA_PORT);
Test1 ardrone = new Test1("ARDrone", args, inet_addr);
// создаем новый пакет для отправки на AT_PORT
String at_cmd="AT*CONFIG=" + 1 + ",\"general:navdata_demo\",\"TRUE\"";
byte[] buf_snd_1 = (at_cmd + "\r").getBytes();
DatagramPacket packet_snd_1 = new DatagramPacket(buf_snd_1, buf_snd_1.length, inet_addr, AT_PORT);
socket_at.send(packet_snd_1);
// Получаем сообщение с NAVDATA_PORT
byte[] buf_rcv = new byte[10240];
DatagramPacket packet_rcv = new DatagramPacket(buf_rcv, buf_rcv.length);
while(true) {
try {
socket_nav.receive(packet_rcv);
int state = get_int(buf_rcv, NAVDATA_STATE);
if ((state & MYKONOS_COM_WATCHDOG_MASK) > 0) {
System.out.println("MYKONOS_COM_WATCHDOG_MASK");
send("AT*COMWDG=1");
Thread.sleep(30);
}
if ((state & MYKONOS_TRIM_COMMAND_MASK) > 0) {
System.out.println("MYKONOS_TRIM_COMMAND_MASK");
// send("AT*LED=1,4,1056964608,5");
// Thread.sleep(30);
}
if ((state & MYKONOS_TRIM_RESULT_MASK) > 0) {
System.out.println("MYKONOS_TRIM_RESULT_MASK");
}
if ((state & MYKONOS_ANGLES_OUT_OF_RANGE) > 0) {
System.out.println("MYKONOS_ANGLES_OUT_OF_RANGE");
}
if ((state & MYKONOS_WIND_MASK) > 0) {
System.out.println("MYKONOS_WIND_MASK");
}
if ((state & MYKONOS_ULTRASOUND_MASK) > 0) {
System.out.println("MYKONOS_ULTRASOUND_MASK");
}
if ((state & MYKONOS_CUTOUT_MASK) > 0) {
System.out.println("MYKONOS_CUTOUT_MASK");
}
if ((state & MYKONOS_EMERGENCY_MASK) > 0) {
System.out.println("MYKONOS_EMERGENCY_MASK");
}
int battery = get_int(buf_rcv, NAVDATA_BATTERY);
float altitude = ((float)get_int(buf_rcv, NAVDATA_ALTITUDE)/1000);
attitude_pitch = get_float(buf_rcv, NAVDATA_PITCH)/1000;
attitude_roll = get_float(buf_rcv, NAVDATA_ROLL)/1000;
attitude_yaw = get_float(buf_rcv, NAVDATA_YAW)/1000;
cnt++;
if (cnt >= 5) {
cnt = 0;
System.out.println("NavData Received: " + packet_rcv.getLength() + " bytes");
System.out.println("get_int(): data = " + byte2hex(buf_rcv, NAVDATA_BATTERY, 4));
System.out.println("Battery: " + battery);
System.out.println("Altitude: " + altitude);
System.out.println("Pitch: " + attitude_pitch);
System.out.println("Roll: " + attitude_roll);
System.out.println("Yaw: " + attitude_yaw);
}
} catch(SocketTimeoutException ex3) {
System.out.println("socket_nav.receive(): Timeout");
} catch(Exception ex1) {
ex1.printStackTrace();
}
}
} catch(Exception ex2) {
ex2.printStackTrace();
}
}
public static int get_int(byte[] data, int offset) {
int tmp = 0, n = 0;
for (int i=3; i>=0; i—) {
n <<= 8;
tmp = data[offset + i] & 0xFF;
n |= tmp;
}
return n;
}
public static void send(String msg) throws Exception {
byte[] bytes = (msg + "\r").getBytes();
DatagramPacket ds = new DatagramPacket(bytes, bytes.length, inet_addr, AT_PORT);
socket_at.send(ds);
}
public static float get_float(byte[] data, int offset) {
return Float.intBitsToFloat(get_int(data, offset));
}
public static String byte2hex(byte[] data, int offset, int len) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; i++) {
String tmp = Integer.toHexString(((int) data[offset + i]) & 0xFF);
for(int t = tmp.length();t<2;t++)
{
sb.append('0');
}
sb.append(tmp);
sb.append(' ');
}
return sb.toString();
}
public static synchronized int get_seq() {
return seq++;
}
public static synchronized void send_at_cmd(String at_cmd) throws Exception {
System.out.println("AT command: " + at_cmd);
at_cmd_last = at_cmd;
byte[] buf_snd = (at_cmd + "\r").getBytes();
DatagramPacket packet_snd = new DatagramPacket(buf_snd, buf_snd.length, inet_addr, AT_PORT);
socket_at.send(packet_snd);
/* AR.Drone does not send back ack message (like "OK")
byte[] buf_rcv = new byte[64];
DatagramPacket packet_rcv = new DatagramPacket(buf_rcv, buf_rcv.length);
socket_at.receive(packet_rcv);
System.out.println(new String(packet_rcv.getData(),0,packet_rcv.getLength()));
*/
}
public void keyTyped(KeyEvent e) {
;
}
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
try {
control(keyCode);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
//if (keyCode >= KeyEvent.VK_1 && keyCode <= KeyEvent.VK_9) speed = (float)0.1; //Reset speed
if (keyCode == KeyEvent.VK_SHIFT) shift = false;
}
//Control AR.Drone via AT commands per key code
public void control(int keyCode) throws Exception {
//System.out.println("Key: " + keyCode + " (" + KeyEvent.getKeyText(keyCode) + ")");
switch (keyCode) {
case KeyEvent.VK_1:
speed = (float)0.05;
break;
case KeyEvent.VK_2:
speed = (float)0.1;
break;
case KeyEvent.VK_3:
speed = (float)0.15;
break;
case KeyEvent.VK_4:
speed = (float)0.25;
break;
case KeyEvent.VK_5:
speed = (float)0.35;
break;
case KeyEvent.VK_6:
speed = (float)0.45;
break;
case KeyEvent.VK_7:
speed = (float)0.6;
break;
case KeyEvent.VK_8:
speed = (float)0.8;
break;
case KeyEvent.VK_9:
speed = (float)0.99;
break;
case KeyEvent.VK_SHIFT:
shift = true;
break;
case KeyEvent.VK_UP:
if (shift) {
System.out.println("Go Up (gaz+)");
send_pcmd(1, 0, 0, speed, 0);
} else {
System.out.println("Go Forward (pitch+)");
send_pcmd(1, speed, 0, 0, 0);
}
break;
case KeyEvent.VK_DOWN:
if (shift) {
System.out.println("Go Down (gaz-)");
send_pcmd(1, 0, 0, -speed, 0);
} else {
System.out.println("Go Backward (pitch-)");
send_pcmd(1, -speed, 0, 0, 0);
}
break;
case KeyEvent.VK_LEFT:
if (shift) {
System.out.println("Rotate Left (yaw-)");
send_pcmd(1, 0, 0, 0, -speed);
} else {
System.out.println("Go Left (roll-)");
send_pcmd(1, 0, -speed, 0, 0);
}
break;
case KeyEvent.VK_RIGHT:
if (shift) {
System.out.println("Rotate Right (yaw+)");
send_pcmd(1, 0, 0, 0, speed);
} else {
System.out.println("Go Right (roll+)");
send_pcmd(1, 0, speed, 0, 0);
}
break;
case KeyEvent.VK_SPACE:
// Операция Не равно "= !"
space_bar = !space_bar;
if (space_bar) {
System.out.println("Takeoff");
//send_at_cmd("AT*CONFIG=" + get_seq() + ",\"leds:leds_anim\",\"3,1073741824,2\"");
send_at_cmd("AT*REF=" + get_seq() + ",290718208");
} else {
System.out.println("Landing");
//send_at_cmd("AT*CONFIG=" + get_seq() + ",\"leds:leds_anim\",\"5,1073741824,2\"");
send_at_cmd("AT*REF=" + get_seq() + ",290717696");
}
break;
case KeyEvent.VK_PAUSE:
System.out.println("Hovering");
send_pcmd(1, 0, 0, 0, 0);
speed = (float)0.1; //Reset speed
break;
default:
break;
}
if (keyCode >= KeyEvent.VK_1 && keyCode <= KeyEvent.VK_9) System.out.println("Speed: " + speed);
}
public void send_pcmd(int enable, float pitch, float roll, float gaz, float yaw) throws Exception {
System.out.println("Speed: " + speed);
send_at_cmd("AT*PCMD=" + get_seq() + "," + enable + "," + intOfFloat(pitch) + "," + intOfFloat(roll)
+ "," + intOfFloat(gaz) + "," + intOfFloat(yaw));
}
public int intOfFloat(float f) {
fb.put(0, f);
return ib.get(0);
}
}
-
-
Рисуем джойстик на экране планшета
Рисуем круг и окружность вокруг него с одним центром. Круг может перемещаться внутри окружности и играет роль стека джойстика.
Также круг должен реагировать на касание пальцем внутри окружности и следить за перемещением пальца.
Информация о перемещении пальца используется для изменения газа и наклонов (углов Эйлера) -
Перед рисованием джойстика надо сделать не консольное приложение на ПК, а приложение на android
Программа Взлет/посадка состоит из 2 -х классов. На форме (activity) расположим две кнопки
Вот оформление из файла activity_main.xml
Код: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/hello_world"
tools:context=".MainActivity" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignRight="@+id/textView1"
android:layout_marginRight="40dp"
android:layout_marginTop="36dp"
android:text="Взлет"
android:onClick="onMyButtonClick" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="@+id/button1"
android:layout_below="@+id/button1"
android:layout_marginTop="30dp"
android:text="Посадка"
android:onClick="onMyButtonClick1" />
</RelativeLayout>
Файл формы (activity)
Код: package com.example.test3;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends Activity {
boolean app_running = true;
NavData navdata;
private static final String TAG = "ARDrone";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// navdata = new NavData(this);
// navdata.start();
}
public MainActivity() {
navdata = new NavData(this);
navdata.start();
}
public void destroyApp(boolean unconditional) {
app_running = false;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public void onMyButtonClick(View view)
{
// выводим сообщение
//Log.d(TAG, "msg");
try {
//navdata.send("AT*CONFIG=605,\"leds:leds_anim\",\"3,1073741824,2\"");
navdata.erbol = true;
} catch (Exception e)
{}
Toast.makeText(this, "Зачем вы нажали?", Toast.LENGTH_SHORT).show();
}
public void onMyButtonClick1(View view)
{
// выводим сообщение
navdata.satiga = true;
Toast.makeText(this, "Hello", Toast.LENGTH_SHORT).show();
}
}
А это класс с помощью которого взаимодействуем с drone
Код: package com.example.test3;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.StringTokenizer;
import android.util.Log;
public class NavData extends Thread{
static final int AT_PORT = 5556;
static InetAddress inet_addr;
static String at_cmd_last = "";
static int seq = 1; //Send AT command with sequence number 1 will reset the counter
FloatBuffer fb;
IntBuffer ib;
static DatagramSocket socket_at;
MainActivity mAct;
private static final String TAG = "ARDrone";
boolean erbol=false;
boolean satiga=false;
public NavData(MainActivity mAct) {
this.mAct = mAct;
}
public void run() {
try {
socket_at = new DatagramSocket(AT_PORT);
socket_at.setSoTimeout(3000);
} catch (Exception ex){}
int ch = 0;
while(mAct.app_running) {
ch++;
try {
if (erbol) {
//send("AT*CONFIG=605,\"leds:leds_anim\",\"3,1073741824,2\"");
send("AT*REF=605,290718208");
erbol=false;
}
if (satiga) {
send("AT*REF=606,290717696");
send("AT*CONFIG=606,\"leds:leds_anim\",\"4,1073741824,2\"");
//send_at_cmd("AT*REF=" + get_seq() + ",290717696");
satiga=false;
}
}
catch (Exception ex) {}
//if (ch>1) erbol=false ;
}
}
public int get_int(byte[] data, int offset) {
int tmp = 0, n = 0;
for (int i=3; i>=0; i—) {
n <<= 8;
tmp = data[offset + i] & 0xFF;
n |= tmp;
}
return n;
}
public void send(String msg) throws Exception {
byte[] bytes = (msg + "\r").getBytes();
String ip = "192.168.1.1";
StringTokenizer st = new StringTokenizer(ip, ".");
byte[] ip_bytes = new byte[4];
if (st.countTokens() == 4){
for (int i = 0; i < 4; i++){
ip_bytes[i] = (byte)Integer.parseInt(st.nextToken());
}
}
inet_addr = InetAddress.getByAddress(ip_bytes);
DatagramPacket ds = new DatagramPacket(bytes, bytes.length, inet_addr, 5556);
//Log.d(TAG, bytes.toString());
//Log.d(TAG, msg);
Log.d(TAG, inet_addr.toString());
socket_at.send(ds);
Log.d(TAG, inet_addr.toString());
}
public float get_float(byte[] data, int offset) {
return Float.intBitsToFloat(get_int(data, offset));
}
public String byte2hex(byte[] data, int offset, int len) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; i++) {
String tmp = Integer.toHexString(((int) data[offset + i]) & 0xFF);
for(int t = tmp.length();t<2;t++)
{
sb.append('0');
}
sb.append(tmp);
sb.append(' ');
}
return sb.toString();
}
public synchronized int get_seq() {
return seq++;
}
public static synchronized void send_at_cmd(String at_cmd) throws Exception {
//System.out.println("AT command: " + at_cmd);
at_cmd_last = at_cmd;
byte[] buf_snd = (at_cmd + "\r").getBytes();
DatagramPacket packet_snd = new DatagramPacket(buf_snd, buf_snd.length, inet_addr, AT_PORT);
socket_at.send(packet_snd);
/* AR.Drone does not send back ack message (like "OK")
byte[] buf_rcv = new byte[64];
DatagramPacket packet_rcv = new DatagramPacket(buf_rcv, buf_rcv.length);
socket_at.receive(packet_rcv);
System.out.println(new String(packet_rcv.getData(),0,packet_rcv.getLength()));
*/
}
}
-
Обработка событий "касания" в приложениях для android
[внешняя ссылка]
[внешняя ссылка]
Собственно все визуальные объекты, потомки объекта view, могут иметь эти события и обрабатывать их. Для того чтобы объект получил нужную информацию у него должен быть идентификатор (id).
Идентификатор объекта определяется в разделе ресурсов, в файле /res/layout/main.xml или сейчас /res/layout/activity_main.xml
Допустим для объекта Представление (view) SomeView, это делается так:
Код: 1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="schemas.android.com/apk/res/android"
3 android:orientation="vertical"
4 android:layout_width="fill_parent"
5 android:layout_height="fill_parent"
6 >
7 <com.example.MotionEventExample1.SomeView
8 android:layout_width="fill_parent"
9 android:layout_height="fill_parent"
10 android:id="@+id/sv"
11 />
12 </LinearLayout>
Поскольку у объекта есть id, android будет идентифицировать собственника происходящего события.
Далее , для обработки события объект должен иметь метод, для "Представления" (view) такой метод называется onTouchEvent(MotionEvent event).
Метод имеет один аргумент, экземпляр класса MotionEvent.
Каждый раз когда пользователь проводит пальцем по экрану или просто "щелкает" пальцем, создается последовательность экземпляров этого класса. Каждый экземпляр хранит в себе информацию о типе действия.
MotionEvent является хранилищем данных о прикосновениях к экрану.
Методы getX() и getY() возвращают координаты нажатия.
Метод getAction() возвращает тип нажатия пользователем, возможны следующие его значения:
-константа ACTION_DOWN : пользователь опускает палец на экран
-константа ACTION_UP : пользователь поднимает палец с экрана
-константа ACTION_MOVE : пользователь перемещает палец по экрану.
Класс "Представления" будет выглядеть так
Код:
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class SomeView extends View
{
//Сначала необходимо реализовать конструктор.
//Тут все просто - просто вызываем конструктор суперкласса
public SomeView(Context context, AttributeSet attrs)
{
super(context,attrs);
}
//Теперь приступаем непосредственно к обработке MotionEvent'ов.
//Для этого нужно переписать метод onTouchEvent
@Override
public boolean onTouchEvent(MotionEvent event)
{
Float X=(Float)event.getX();
Float Y=(Float)event.getY();
int Action=event.getAction();
String ActionString="";
switch(Action)
{
case MotionEvent.ACTION_DOWN: ActionString="ACTION_DOWN";break;
case MotionEvent.ACTION_MOVE: ActionString="ACTION_MOVE";break;
case MotionEvent.ACTION_UP: ActionString="ACTION_UP";break;
}
Log.v("MyTag","View OnTouchListener:\n"+"Coords: "+X.toString()+" x "+Y.toString()+"\nAction type: "+ActionString);
return true;
}
}
Вот содержание для формы (activity)
Код: import android.app.Activity;
import android.os.Bundle;
public class main extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
Android позволяет нам разделять обязанности по обработке touch event’ов на несколько слушателей.
MotionEvent должны возвращать логическое значение.
Для чего?
Дело в том, что у одного View может быть несколько слушателей (например onTouchEvent в самом View и OnTouch у внешнего слушателя) и они имеют некоторый приоритет: OnTouch вызывается первым (если он вообще имеется), а уже после него может вызываться onTouchEvent.
Вызов следующего по приоритету обработчика как раз зависит от возвращаемого текущим обработчиком значения (true — ничто не вызывается, false — вызывается следующий по приоритету, если есть). -
Кому лимон? Конкурс летающих роботов
[внешняя ссылка]
[внешняя ссылка]
Надо команду создать, а денежки пополам -
Как нарисовать окружность ?
Метод drawCircle рисует круг, метод drawRect рисует прямоугольник. Для того чтобы нарисовать окружность используем свойство Style метода и далее выбираем стиль STROKE
С помощью этого стиля рисования можно создать контур фигуры, ее обрис.
Например так
Код: Paint mPaint = new Paint();
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(0xFFFFFFFF);
Rect rect = new Rect(0, 0, 100, 50);
canvas.drawRect(rect, mPaint);
Можно еще задать толщину линии контура с помощью свойства setStrokeWidth
Код: paint1 = new Paint();
paint1.setColor(Color.BLUE);
paint1.setStyle(Paint.Style.STROKE);
paint1.setStrokeWidth(1f); -
Нашел две книжки хорошие по android
Android за 24 часа. Программирование приложений под операционную
систему Google/ ДэрсиЛ., КондерШ.
[внешняя ссылка]
Рето Майер - Android 2. Программирование приложений - 2011
[внешняя ссылка]