При
опробовании беспроводного тачпада Logitech в качестве альтернативы мыши
возникла мысль – ведь рядом лежит вполне готовый беспроводной тачпад –
смартфон. Мышь он, конечно, не заменит,
но кое-что сделать, комфортно развалившись
в кресле, вполне можно.
Идея
эта не нова, есть достаточно приложений для удаленного управления ПК с
андроид-устройства. Решил реализовать
минималистический андроид-тачпад с настройкой чувствительности по осям и
сглаживания движения, который в дальнейшем, при желании, можно наполнить
разнообразными возможностями удаленного управления.
В
качестве отправной точки используем ранее слепленную программу рисования
каракулей на экране. Только теперь эти каракули и прочие околоэкранные
конвульсии надо будет передать на ПК.
Серверную
часть можно посмотреть тут:
Двигаемся плавно и естественно.
Хочу
более подробно остановиться на эмуляции движения мыши на ПК. Для эмуляции мышиных бегов используем класс Robot
и его
методы mouseMove, mousePress, mouseRelease. Больше всего проблем возникло при
попытке заставить курсор мыши перемещаться достаточно быстро и плавно.
Опробовал
вот такие методы:
1. Просто mouseMove –
быстрые рывки, практически неприменимо.
2. Алгоритм Брезенхэма
– при использовании задержки 1мс на каждом шаге отрабатывает слишком медленно.
3. Вычисление
координат с использованием формулы отрезка прямой с заданным шагом – все равно
дергается курсор.
4. Еще один пошаговый
алгоритм с количеством шагов, вычисляемым как функция от кода сглаживания.
Использовал задержку 1 мс на каждом втором шаге.
Самый
лучший, но совсем не идеальный, результат получился при использовании варианта
4. Буду благодарен если кто-то подскажет более красивый вариант.
/**
* Compute mouse step to move
mouse
* @param len Move distance
* @param smooth Smoothing mode
* @return Mouse step
*/
private static int getMouseStep(double len, int smooth){
int a = 30;
switch (smooth)
{
case 1:
a = 30;
if (len < 5) a = 2;
break;
case 2:
a = 40;
if (len < 5) a = 2;
break;
case 3:
a = 50;
if (len < 5) a = 2;
break;
case 4:
a = 50;
if (len > 50) a =
70;
if (len < 5) a = 2;
break;
case 5:
a = 70;
if (len < 50) a =
50;
if (len < 5) a = 2;
break;
case 6:
a = 90;
if (len < 50) a =
70;
if (len < 5) a = 5;
break;
}
return a;
}
/**
* Move mouse (actual version)
* @param xstart Start X coordinate
* @param ystart Start Y coordinate
* @param xend Finish X coordinate
* @param yend Finish Y coordinate
* @param sm Smoothing
* @param rb Mouse Robot
*/
private static void MouseMove5(int xstart, int ystart, int xend, int yend, int sm, Robot rb) {
int a = 30;
boolean flag;
double len = Math.sqrt((xend-xstart)*(xend-xstart)+(yend-ystart)*(yend-ystart));
if (len < 3){
rb.mouseMove(xend, yend);
rb.delay(1);
}
a=getMouseStep(len,
sm);
flag = true;
for (int i = 0; i < a; i++) {
int mov_x = ((xend * i)
/ a) + (xstart * (a - i) / a);
int mov_y = ((yend * i)
/ a) + (ystart * (a - i) / a);
rb.mouseMove(mov_x,
mov_y);
if (flag){
rb.delay(1);
flag = false;
}
else flag = true;
}
rb.mouseMove(xend, yend);
}
Вопросы безопасности.
При
разработке или использовании систем удаленного управления надо помнить, что
желающие удаленно порулить чужим компьютером найдутся всегда.
При
подключении к серверу будем передавать
хеш-код пароля. Серверное приложение при первом старте (и в режиме настройки)
запросит ввод пароля и сохранит его хеш-код. Для вычисления хеш-кода используем
алгоритм MD5:
**
* Encrypt password
* Create MD5 hash
* @param input Input String
* @return MD5 Hash String
*/
public static String md5Encrypt(String input){
String md5 = null;
if (input == null)
return null;
try {
MessageDigest digest =
MessageDigest.getInstance("MD5");
digest.update(input.getBytes(),
0, input.length());
md5 = new BigInteger(1,
digest.digest()).toString(16);
}
catch(Exception e){
e.printStackTrace();
}
return md5;
}
В любом
случае, я бы рекомендовал использовать такую программу исключительно в домашней
wifi сети.