Форум программистов, компьютерный форум CyberForum.ru

Веб-сервер и Android-устройства - Программирование Android

Войти
Регистрация
Восстановить пароль
Другие темы раздела
Программирование Android Изменение View, не из того потока, в котором оно создано http://www.cyberforum.ru/android-dev/thread1147895.html
Использую библиотеку OpenCV. Активити реализует JavaCameraView из этой библиотеки. В JavaCameraView есть событие OnCameraFrame(Mat inputFrame) - получение кадра, от камеры устройства. При получении определённого кадра я хочу изменить виджет, например TextView, или ImageView. Но не могу этого сделать, так как выдается ошибка, что я пытаюсь изменить View, не из того потока, в котором оно было...
Программирование Android ProgressBar Подскажите как сделать так чтоб при запуске например AsyncTasc на экране у пользователя запускался крутящийся ProgressBar тем самым не давая пользователю делать ни каких действий, а после завершения AsyncTasc , progressBar исчезал тем самым давая пользователю продолжить работу? http://www.cyberforum.ru/android-dev/thread1147746.html
Программирование Android Что это за контрол
Здравствуйте! Видел его в играх некоторых. Обычно он статичный, в углу экрана. Используется для управления. Как джойстик. Водишь по нему и тем самым управляешь кем-то. Заранее спс!
Программирование Android Отрицательное значение id в SQLite
Добавляю запись в БД ContentValues cv = new ContentValues(); db = openOrCreateDatabase("myDB.db", SQLiteDatabase.OPEN_READWRITE, null); cv.put("name", textViewName.getText().toString()); cv.put("namenumb", name_numb); long rowID = db.insert("mytable", null, cv); showToast(String.valueOf(rowID)); // в этом месте Toast показывает -1 db.insert("mytable", null, cv);...
Программирование Android Ошибка при запуске Android Studio http://www.cyberforum.ru/android-dev/thread1147175.html
Скачал Android Studio с официального сайта. Установил, но при запуске выдает ошибку(см. вложение). Изначально он ругался на JAVA_HOME. Теперь ему не нравится путь. Кто сталкивался с такой проблемой? Win 8.1 Корпоративная
Программирование Android Не запускается приложение в эмуляторе Здравствуйте. Подскажите, пожалуйста причину. У меня не запускается приложение в эмуляторе(сам эмулятор запускается), и что самое интересное мои первые приложения запускаются(Hello World) и запускаются (просто описанные кнопки, текстовые поля). А вот с обработчиком кнопки не запускается(Unfortunatelly TEst5 has stoped) package com.example.test5; import android.app.Activity; import... подробнее

Показать сообщение отдельно
YuraAAA
1566 / 1308 / 269
Регистрация: 25.10.2009
Сообщений: 3,424
Записей в блоге: 2
14.04.2014, 17:20     Веб-сервер и Android-устройства
contedevel, сейчас будем разбираться

Добавлено через 23 минуты
contedevel, для начала часть первая.
Самый примитивный сервер. Я в качестве платформы буду использовать Node JS (backend на основе javascript).

Генерим шаблонный проект на базе express 3.5. Покажу только значимые куски:



Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var express = require('express');
//+ остальные подключаемые модули
 
var app = express();
 
// используем 3000 порт
app.set('port', process.env.PORT || 3000);
//остальное
app.use(express.bodyParser());
 
 
 
//А вот и наши пути.
// /register - post запрос
// /info это будет get запрос.
app.post('/register', registration.authenticate);
app.get('/info', user.info);
 
//запускаем сервер.
http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});
Рассмотрим
app.post('/register', registration.authenticate);
app.get('/info', user.info);

Это значит, что у нас будет модуль registratiion с методом authenticate и user модуль с методом info.

Именно ЭТИ методы будут вызываться при получении запроса node'ой.

user.js
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * GET users listing.
 */
 
exports.info = function(req, res){
    var header = req.header('X-Auth'); //Ищем заголовок X-Auth
    if (!header || header !== 'secret_key') { //Если его нет или он не равен secret_key отвечаем, что фиг вам.
        res.json({
            err:{
                code:403,
                message:'Permission denied'
            }
        })
    } else {
        res.json({
            some_info:'Oh my god! We got it!' //А тут всё ок, юзер как бы настоящий
        })
    }
};
authenticate.js

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
exports.authenticate = function (req, res) {
    
    var name = req.body.name; //Ищем name
    if (!name) {
        res.json({
            code: 403
        });
        return;
    } else {
        var password = req.body.password; //Ищем пароль
        if (!password || password != 'secret') { //Если пароля нет или он не secret возвращаем 403
            res.json({
                code: 403
            });
            return;
        }
    }
    res.json({ 
        status:'success',
        token:'secret_key' //Иначе всё ок.
    });
};
Собственно, всё. Давайте проверять из консольки это дело. Запускаем сервер и тыкаем в него палкой.

Код
D:\untitled>curl localhost:3000/register
Cannot GET /register
всё верно. Регистрация - POST

D:\untitled>curl localhost:3000/register -X POST
{
"code": 403
}
и опять же, всё ок. Мы не передали нужные параметры (name, password)

D:\untitled>curl localhost:3000/register -X POST --data name=cyberforum --data password=secret
{
"status": "success",
"token": "secret_key"
}
вот и всё отлично. Мы передали нужные данные - получили ответ, что всё хорошо.


Теперь попробуем потыкать в info.

Код
D:\untitled>curl localhost:3000/info
{
  "err": {
    "code": 403,
    "message": "Permission denied"
  }
}
Всё верно, мы не передали секретный ключ в заголовке. Сервер нас не может распознать.

Код
D:\untitled>curl localhost:3000/info -H X-Auth:secret_key
{
  "some_info": "Oh my god! We got it!"
}
Вот теперь всё ок. Мы передали в хэдере "секретный" ключик и сервак нас понял.

С сервером всё. Сейчас будем смотреть клиент на Android.

Добавлено через 27 минут
Со стороны клиента нам надо выделить две составных части:

Сторона асинхронной работы с вебом и сторона UI.
Почему асинхронной - потому что по умолчанию андроид запускает один поток, отвечающий за отображение элементов. Все тяжеловесные операции должны выполняться в другом потоке.

+ нам надо вернуть результат как-то.

Значит будут составляющие:

Вызов задачи из asyncTask -> Выполнение задачи -> Генерирование ответа обратно через интерфейс обратного вызова (Callback).

Приступим. Механизм асинхронного вызова. Ничего сложного нет, наследуемся от AsyncTask. Используем generic для универсальности.

i
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
mport android.os.AsyncTask;
 
public abstract class MyIncredibleAsyncTask<T> extends AsyncTask<Void, Void, T> { //Используем типизацию
    private CallbackInterface<T> callbackInterface;
    private Throwable t; //Сигнал об ошибке
 
    public MyIncredibleAsyncTask(CallbackInterface<T> callbackInterface) {
        this.callbackInterface = callbackInterface;
    }
 
    @Override
    protected T doInBackground(Void... voids) {
        try {
            return doAction(); //Этот метод мы будем переопределять
        } catch (Throwable throwable) {
            t = throwable; //Что-то произошло
        }
        return null;
    }
 
 
    @Override
    protected void onPostExecute(T t) {
        super.onPostExecute(t);
        generateCallback(t); //Генерируем ответ
    }
 
    public abstract T doAction() throws Throwable;
 
 
    private void generateCallback(T data) {
        if (callbackInterface == null) return; //Не передали интерфейс, пока
        if (data != null) { //Всё ок, данные приехали
            callbackInterface.onSuccess(data);
        } else if (t != null) { //Что-то случилось (IOException и прочее)
            callbackInterface.onFailure(t);
        } else {
            callbackInterface.onError("Some shit happens"); //Не понятно. Нет ни ошибки, не результата.
        }
    }
 
}
и интерфейс:

Java
1
2
3
4
5
6
7
8
9
10
public interface CallbackInterface<T> {
 
    void onSuccess(T data);
 
    void onError(String serverError);
 
    void onFailure(Throwable t);
 
 
}
Теперь описываем Singleton-менеджер работы.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
 
import java.util.LinkedList;
import java.util.List;
 
public class DataManager {
    private HttpClient httpClient;
    private static DataManager instance;
 
 
    public static DataManager getInstance() {
        if (instance == null) {
            instance = new DataManager();
        }
        return instance;
    }
 
    private DataManager(){
        httpClient = new DefaultHttpClient();
    }
 
    public void authorization(final String name, final String pwd, CallbackInterface<String> callbackInterface) {
        new MyIncredibleAsyncTask<String>(callbackInterface) {
            @Override
            public String doAction() throws Throwable {
                HttpPost post = new HttpPost("http://10.0.2.2:3000/register"); //Вот ПОСТ запрос
                List<BasicNameValuePair> pairs = new LinkedList<BasicNameValuePair>();
                pairs.add(new BasicNameValuePair("name", name));
                pairs.add(new BasicNameValuePair("password", pwd));  //А это его "мясо"
                post.setEntity(new UrlEncodedFormEntity(pairs));
                HttpResponse execute = httpClient.execute(post);
                return EntityUtils.toString(execute.getEntity());
            }
        }.execute();
    }
 
    public void info(CallbackInterface<String> callbackInterface) {
        new MyIncredibleAsyncTask<String>(callbackInterface) {
            @Override
            public String doAction() throws Throwable {
                HttpGet get = new HttpGet("http://10.0.2.2:3000/info"); //Вот GET запрос
                get.setHeader(new BasicHeader("X-Auth", "secret_key")); //А это наш суперсекретный HEADER
                HttpResponse execute = httpClient.execute(get);
                return EntityUtils.toString(execute.getEntity());
            }
        }.execute();
    }
}
А вот и всё
Вызов:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class MyActivity extends Activity {
    public static final String TAG = DataManager.class.getSimpleName();
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        DataManager.getInstance().authorization("user", "password", new CallbackInterface<String>() {
 
            @Override
            public void onSuccess(String data) {
                Log.d(TAG, data);
                requestInfo();
            }
 
            @Override
            public void onError(String serverError) {
                Log.e(TAG, serverError);
            }
 
            @Override
            public void onFailure(Throwable t) {
                Log.e(TAG, t.getMessage(), t);
            }
        });
    }
 
    void requestInfo() {
        DataManager.getInstance().info(new CallbackInterface<String>() {
            @Override
            public void onSuccess(String data) {
                Log.d(TAG, data);
            }
 
            @Override
            public void onError(String serverError) {
                Log.e(TAG, serverError);
            }
 
            @Override
            public void onFailure(Throwable t) {
                Log.e(TAG, t.getMessage(), t);
            }
        });
    }
}
Вот логи:

авторизация:

Код
04-14 09:11:59.230      863-863/com.example.untitled2 D/DataManager﹕ {
    "code": 403
    }
всё верно. Я передал кривой пароль.

Код
04-14 09:11:59.650      863-863/com.example.untitled2 D/DataManager﹕ {
    "some_info": "Oh my god! We got it!"
    }
Правильный хэдер - всё окей.

Ну в принципе это всё. Это самый простой пример работы клиент-сервер.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru