Android-приложение Android работает на эмуляторе, но не на моих телефонах
Я боролся с android в течение последних нескольких недель и получил себе первое работающее приложение... на моем эмуляторе только к сожалению. Я действительно надеюсь, что кто-то может помочь мне заставить его работать на моем устройстве Android. Эмулятор работает под управлением v2.2, мои устройства 2.3+.
У меня есть одноэлементный класс websiteservice, который создается классом, расширяющим "Application". Класс websiteservice создает 1 потокобезопасный менеджер соединений и содержит "CookieStore". Каждый HTTPGet/Post создает новый HTTPClient с присоединенным к нему threadsafeconn.manager. Каждый раз, когда я делаю пост или получаю, я пытаюсь прикрепить куки, если они есть. Файлы cookie устанавливаются один раз и только при входе на защищенную часть веб-сайта. Вместе с EntitityUtils.ToString и Jsoup я анализирую каждый HTML-результат моей "защищенной" части веб-сайта. При входе в систему я создаю таблицу sqllite в Android, в которой я храню только 1 простую запись - пользователь, который вошел в систему.
Когда я запускаю это на моем эмуляторе, все работает так, как мне бы хотелось, но на моем устройстве что-то идет ужасно неправильно. Я подключил отладчик к своему телефону. Вход в систему, кажется, идет хорошо, и куки устанавливаются. Бит sqllite, вероятно, тоже подходит, так как я не вижу ошибок. После загрузки страницы профиля я вижу, что HTTPGet-действие get - это cookie-файлы, прикрепленные к CookieStore, но HTML-результат / документ, который я получаю, составляет 95% от времени входа в систему.
Я говорю 95%, потому что я попадал на страницу своего профиля один или два раза на своем рутированном Desire HD, но на другом Desire HD я этого не делал, и на моем Sensation XE тоже нет. Когда я загружал страницу профиля (пользовательский список с хэш-картой в качестве входных данных), я не мог начать какое-либо действие. Они сразу же прервались, и, вероятно, у них возникла та же проблема (в результате была получена страница входа).
Есть ли какие-то разрешения, которые я забыл, есть что-то, что я должен проверить, или у вас есть идея, что это может быть? Я действительно смущен прямо сейчас.
Небольшое обновление
Я только что перезагрузил свой телефон. Когда я запускаю программу, при первом входе в систему загружается страница моего профиля. Кажется, мое действие "детали" работает. Это действие не подключается к Интернету или около того, оно просто отображает информацию, которую я хранил в классе. Мои другие 2 действия (копирование и удаление) не работают (в результате я, вероятно, получаю "страницу входа"). Когда я переворачиваю экран (ориентация меняется), страница "перезагружается", и она пытается снова загрузить страницу профиля. Список очищается, и я не получаю обратно страницу своего профиля (которая является списком рекламы).
Обновление 2 - 08-03 Мой файл манифеста содержит только интернет-разрешение, кроме регистрации моих действий. Небольшое "странное" дополнение. Кажется, мой "резервный" код почти совпадает с моим кодом, размещенным здесь. Кажется, что каждый раз он прикрепляет мои куки, но все равно ничего с этим не делает:(. Кроме того, вчера я немного поиграл с телефоном, несколько раз менял orentiation (что автоматически перезагружает активность), и вдруг у меня один или два раза появился мой профиль впереди. Я не мог ничего с ним сделать, но мой класс, содержащий информацию, был доступен и заполнен. PS. Сейчас, в 8.15, я снова смог загрузить свой профиль после переключения ориентация 4-5 раз.
Обновление 08-03-2012 Вечером я ломал голову и много чего перепробовал, и теперь я даже вернул свою версию эмулятора обратно в квадрат 1. Получил резервную копию, так что np, но я думаю, что не использую свой http-клиент правильно. Я удалил весь предыдущий код, вот мой текущий код, который я использую для моего "websiteservice", и мой "Webclient", который я создаю для каждого get/post, просто присоединяя менеджер соединений.
private static WebsiteService instance;
ThreadSafeClientConnManager manager;
HttpContext localContext;
CookieStore cookies;
public String returnCode = "";
public HttpPost httpPost = null;
public HttpGet httpGet = null;
public static WebsiteService getInstance()
{
// Return the instance
return instance;
}
private WebsiteService()
{
DefaultHttpClient client = new DefaultHttpClient();
ClientConnectionManager mgr = client.getConnectionManager();
HttpParams params = client.getParams();
manager = new ThreadSafeClientConnManager(params,mgr.getSchemeRegistry());
localContext = new BasicHttpContext();
cookies = new BasicCookieStore();
localContext.setAttribute(ClientContext.COOKIE_STORE, cookies);
}
public static void initInstance()
{
if (instance == null)
instance = new WebsiteService();
}
public WebsiteClient postPage(String url, List<NameValuePair> nvps)
{
return postPage(url, nvps, true);
}
public WebsiteClient getPage(String url) {
WebsiteClient client = new WebsiteClient(manager);
DefaultHttpClient httpClient = client.httpClient;
httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
//HttpProtocolParams.setContentCharset(httpClient.getParams(), "CP1250");
if(cookies != null)
httpClient.setCookieStore(cookies);
httpGet = new HttpGet(url);
try {
client.response = httpClient.execute(httpGet,localContext);
} catch (ClientProtocolException e) {
System.out.println("HTTPService : ClientProtocolException : "+e.getMessage());
return null;
} catch (IOException e) {
System.out.println("HTTPService : IOException : "+e);
return null;
}
//cookies = httpClient.getCookieStore();
return client;
}
public WebsiteClient postPage(String url, List<NameValuePair> nvps, boolean autoRedirect) {
WebsiteClient client = new WebsiteClient(manager);
DefaultHttpClient httpClient = client.httpClient;
httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
if(cookies != null)
httpClient.setCookieStore(cookies);
if(!autoRedirect)
{
HttpParams params = httpClient.getParams();
HttpClientParams.setRedirecting(params, false);
}
httpPost = new HttpPost(url);
client.response = null;
//
httpPost.setHeader("User-Agent", "Mozilla/5.0 (X11; U; Linux " +
"i686; en-US; rv:1.8.1.6) Gecko/20061201 Firefox/2.0.0.6 (Ubuntu-feisty)");
httpPost.setHeader("Accept", "text/html,application/xml," +
"application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
try {
if(nvps != null)
httpPost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.ISO_8859_1));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
System.out.println("HTTPHelp : UnsupportedEncodingException : "+e);
}
//httpPost.setEntity(tmp);
try {
client.response = httpClient.execute(httpPost, localContext);
} catch (ClientProtocolException e) {
System.out.println("HTTPService : ClientProtocolException : "+e.getMessage());
return null;
} catch (IOException e) {
System.out.println("HTTPService : IOException : "+e);
return null;
}
cookies = httpClient.getCookieStore();
return client;
}
}
Мой сайт-клиент:
public DefaultHttpClient httpClient;
public HttpResponse response = null;
public WebsiteClient(ThreadSafeClientConnManager manager)
{
DefaultHttpClient client = new DefaultHttpClient();
HttpParams params = client.getParams();
httpClient = new DefaultHttpClient(manager, params);
}
Я должен делать что-то не так с куки, или не должен использовать тот же Httpget/Httppost или около того. Надеюсь, я смогу решить это с ясным разумом снова завтра.
Идеи и отзывы приветствуются!
1 ответ
Я смог решить эту очень неудобную проблему и опубликую решение ниже. К сожалению, я не знаю точную причину, но это, безусловно, сочетание вещей.
Вместо того, чтобы снова создавать DefaultHttpClient каждый раз с моим менеджером соединений, я создал только 1 DefaultHttpClient, который я использую все время. Кроме того, каждый раз, когда я делаю сообщение или получаю, я создаю новый HTTPGet / HTTPPost, вместо того, чтобы повторно использовать / воссоздавать его из существующего.
Окончательный конструктор для моего сайта service-class:
private WebsiteService()
{
CookieManager.getInstance().setAcceptCookie(true);
httpclient = new DefaultHttpClient();
ClientConnectionManager mgr = httpclient.getConnectionManager();
HttpParams params = httpclient.getParams();
manager = new ThreadSafeClientConnManager(params,mgr.getSchemeRegistry());
localContext = new BasicHttpContext();
cookies = new BasicCookieStore();
localContext.setAttribute(ClientContext.COOKIE_STORE, cookies);
}
Простой вызов GetPage теперь выглядит так:
httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
if(cookies != null)
httpClient.setCookieStore(cookies);
HttpGet httpGet = new HttpGet(url);
try {
client.response = httpClient.execute(httpGet,localContext);
} catch (ClientProtocolException e) {
System.out.println("HTTPService : ClientProtocolException : "+e.getMessage());
return null;
} catch (IOException e) {
System.out.println("HTTPService : IOException : "+e);
return null;
}
Я не уверен на 100%, но я думаю, что я могу даже опустить бит setCookies. Файлы cookie в моей ситуации являются частным объявленным CookieStore, который я заполняю после публикации.
Последняя часть, которая раздражала, состоит в том, что после вращения она воссоздает действие. Чтобы решить эту проблему, я расширил класс, который расширяет "Приложение". В этом классе я положил список своих объектов. В моем "OnCreate" я проверяю, существует ли список объектов, и использую этот список, если он доступен. После выхода из системы или обновления я воссоздаю этот список. Уловка была только этими несколькими строками: (я пропустил часть, которую я добавил в классе 'extends Application'):
if(((ApplicationInstance)getApplication()).getProfile() == null)
this.initProfileItems();
else
{
this.ProfileItems =((ApplicationInstance)getApplication()).getProfile();
this.initListView();
}
ApplicationInstance - это мой класс, который расширяет Application. Мой initList обрабатывает объекты. Мой initProfileItems получает фактические данные:-)
Надеюсь, я спас кого-то от головной боли:), и спасибо за ваше время, @androidnoob!