Отправка http запросов из андроид приложения. HttpURLConnection: Подключаемся к URL

Скачать Viber 17.03.2019
Скачать Viber
2 октября 2011 в 23:17

F-Droid, сетевой репозиторий пакетов открытого ПО для Android, aka «Маркет» для тех, кто шлет патчи

Тема альтернативных источников программного обеспечения для Android и альтернативных «маркетов» в частности уже несколько раз поднималась на Хабре, но большинство их описываемых сайтов были откровенно варезными рассадниками (поэтому ссылки не даю). Здесь же я хотел бы рассказать о проекте F-Droid.org , который ставит своей целью собрать и сделать легко доступными для пользователей приложения с открытым исходным кодом (Open Source) и четкими лицензиями использования и изменения.

Маркет, шваркет и аппстор

Прежде чем переходить непосредственно к F-Droid, хотелось бы сказать несколько слово о феномене «Маркетов» и состоянии Open Source на платформе Android.

То, что нынче маркетологи окрестили «АппСторами» и «Маркетами», на самом деле было доступно уже более десятка лет для пользователей Linux и известно как «сетевой репозиторий пакетов». Концепций же менеджера пакетов вообще насчитывает десятки лет и является одной из сильнейших сторон Linux. Неудивительно, что эту концепция стала фактически «наилучшей практикой» (best practice) в области, так что даже Microsoft выпустил и продвигает свой менеджер пакетов.

Хорошо, здравые идеи победили, и для Android существует Android Marketplace. Казалось бы, пользоваться - не нарадоваться, как большинство пользователей, не знакомых ни с чем другим и делают. Но у Android Market есть ряд проблем:

  • Market - закрытый компонент в целом открытой платформы.
  • Из предыдущего пункта следует, что на устройствах, сделанных на основе кода AOSP (Android Open Source Project), Маркета нет, и это типичная ситуация для недорогих устройств (заметьте, независимо от того, дешевый ли это китайский Noname, Inc, или вендоры с именем, вроде Amazon)
  • Если пользователи сами хотят модифицировать Android и сделать его лучше (например, CyanogenMod), то они также не могут легально использовать в своей разработке Маркет
  • Качество ПО в Маркете оставляет желать лучшего. В том смысле, что очень много «мусора» и откровенно подозрительных программ.
  • Последний пункт усугубляется тем, что Google искусственно фильтрует доступность определенных программ для определенных групп пользователей (по географическому признаку или иному), так что качественные, платные программы зачастую недоступны.
  • Фильтрация производится и по другим признакам, например по типу устройства, с которого производится доступ, иными словами, Маркет с ног сбивается, чтобы быть умнее, чем пользователь (что, как известно, у компьютерных программ получается плохо)
  • Маркет не предоставляет достаточных возможностей поиска и категоризации, например, невозможности найти ПО, предлагаемой на условиях определенной лицензии.

Опять Open Source?

Существует несколько (множество?) проектов, призванных решить некоторые из проблем выше, но F-Droid призван решить их коренным образом, а именно передать контроль как над самим репозиторием, так и над ПО, доступным в нем, в руки самих пользователей (собственно, сообщество таких пользователей, которым важны вопросы выше, проект и представляет). Достигает он этого с помощью лицензий Open Source - как для самого программного обеспечения репозитория и менеджера пактов, так и для ПО, доступного в репозитории.

Для многих, кто знаком с Open Source понятно, почему это важно, для тех, кто знает больше понаслышке и «интуитивно» («Халява, Сэр!»), хотелось бы пояснить: Open Source это очень хороший способ гарантировать минимально допустимое качество ПО. Под «минимальным качеством» понимается отсутствие вредоносного кода и явных ошибок и недочетов. Это достигается просто - контролем самих пользователей за кодом. Разумеется, для конкретного пользователя такой контроль может быть сложно осуществить, но Open Source полностью основывается на концепции взаимопомогающего сообщества (а не на концепции потребитель/производитель). Именно поэтому в заголовок вынесена фраза «F-Droid - »Маркет" для тех, кто любит слать патчи".

F-Droid, бородатый робот с пристрастием к FOSS

Но довольно теории. Проект F-Droid был основан Ciaran Gultnieks в октябре 2010 года, т.е. ему нет и года. Это не слишком большой срок, но проект неплохо развился за это время. Итак, у него есть сайт и форум . Приложения, доступные в репозитории, можно посмотреть через веб-интерфейс . Приложений пока немного по меркам Маркета (набитого мусорной фриварью) и даже типичного Linux-дистрибутива: около ста наименований. С одной стороны это кажется очень малым количеством, но с другой стороны, емкость Open Source Android экосферы и так не велика (в 200-300 более-менее рабочих программ, на мой взгляд). Кроме того, даже 100 приложений вы вряд ли захотите установить одновременно на свое устройство, а несколько полезных программ вы там несомненно найдете.

Конечно, основная прелесть F-Droid в менеджере пакетов, работающем на устройстве. Его можно скачать с этой страницы (или прямая ссылка , QR-код в начале статьи). Скриншот основного окна показан ниже:

На трех вкладках представлены: ПО доступное для установки, уже установленное, и апдейты для установленного (кстати, сам менеджер обновляется так же). Поддерживается поиск по наименованию. О заинтересовавшем приложении можно получить более подробную информацию - описание, ссылка на домашнюю страницу, баг-трекер, репозиторий исходного кода, ссылку для donations. наконец, здесь же представлены версии приложения, доступные для установки. И здесь F-Droid имеет особенность, не всегда доступную даже для Linux-дистрибутивов: поддерживаются несколько версий приложения, что по достоинству оценят владельцы недорогих и «стареньких» устройств, вендоры которых отказались выпустить апгрейды для новых версий Android: если новейшая версия программы не работает, вы всегда можете попробовать одну из предыдущих.

F-Droid – репозиторий приложений для Android, который содержит исключительно бесплатные утилиты.

Каталог программ

Неофициальный магазин F-Droid предлагает возможность загружать свободно распространяемые программы. Здесь можно найти не только то, что доступно в Google Play, но и программы, не прошедшие модерацию в официальном маркете. Большую часть каталога составляют блокировщики рекламы, оффлайн словари, "хакерские" утилиты и прочее подобное ПО.

К сожалению, востребованных программ в F-Droid довольно мало, а игр вообще практически нет. Не слишком удобен и процесс установки - отображение запрашиваемых разрешений происходит уже после запуска процесса инсталляции. Установленные клиенты следует обновлять или удалять прямо из интерфейса. F-Droid самостоятельно отслеживает появление более актуальных версий и уведомляет о них пользователя. Важно отметить, что все программы из репозитория имеют открытый исходный код. Так что в их безопасности вы можете не сомневаться.

Использование

F-Droid не требует регистрации. Еще одним приятным плюсом использования этого маркета является возможность обновления приложений, установленных ранее из сторонних источников. Однако, при всех своих преимуществах магазин обладает одним достаточно весомым недостатком. Без получения прав суперпользователя (ROOT) использовать его нельзя.

Ключевые особенности

  • открывает доступ к каталогу приложений для устройств на базе Android;
  • предлагает исключительно бесплатные программы с открытым исходным кодом;
  • сообщает о наличии обновлений, но не умеет загружать их (загрузка выполняется из интерфейса приложений);
  • не требует предварительного создания учетной записи;
  • работает только при наличии ROOT прав;
  • имеет не слишком интуитивный интерфейс.

In Android HTTP POST & GET tutorial , I have explained how to send HTTP POST and GET requests programmatically in Android.

We can use org.apache.http.client.HttpClient class to make HTTP requests.

Send HTTP POST request

Follow the steps to send HTTP POST requests.

HttpClient httpClient = new DefaultHttpClient();

2. Create an object of HttpPost

HttpPost httpPost = new HttpPost("http://www.example.com");

3. Add POST parameters

List (2); nameValuePair.add(new BasicNameValuePair("username", "test_user")); nameValuePair.add(new BasicNameValuePair("password", "123456789"));

4. Encode POST data

We need to encode our data into valid URL format before making HTTP request.

//Encoding POST data try { httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair)); } catch (UnsupportedEncodingException e) { e.printStackTrace(); }

5. Finally making an HTTP POST request

Try { HttpResponse response = httpClient.execute(httpPost); // write response to log Log.d("Http Post Response:", response.toString()); } catch (ClientProtocolException e) { // Log exception e.printStackTrace(); } catch (IOException e) { // Log exception e.printStackTrace(); }

Make sure you add Internet permission to your app before making such requests else you might see some errors.

You can add Internet permissions by adding this line to your manifest file above application tag.

Android HTTP POST Example

package com.example.httprequestexample; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; 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.BasicNameValuePair; import android.app.Activity; import android.os.Bundle; import android.util.Log; public class HTTPPostActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); makePostRequest(); } private void makePostRequest() { HttpClient httpClient = new DefaultHttpClient(); // replace with your url HttpPost httpPost = new HttpPost("www.example.com"); //Post Data List nameValuePair = new ArrayList(2); nameValuePair.add(new BasicNameValuePair("username", "test_user")); nameValuePair.add(new BasicNameValuePair("password", "123456789")); //Encoding POST data try { httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair)); } catch (UnsupportedEncodingException e) { // log exception e.printStackTrace(); } //making POST request. try { HttpResponse response = httpClient.execute(httpPost); // write response to log Log.d("Http Post Response:", response.toString()); } catch (ClientProtocolException e) { // Log exception e.printStackTrace(); } catch (IOException e) { // Log exception e.printStackTrace(); } } }

Send HTTP GET Request

To send HTTP GET request follow the steps.
1. Create an object of HttpClient

HttpClient client = new DefaultHttpClient();

2. Create an object of HttpGet

HttpGet request = new HttpGet("http://www.example.com");

3. Finally make HTTP request

HttpResponse response; try { response = client.execute(request); Log.d("Response of GET request", response.toString()); } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }

Android HTTP GET Example

package com.example.httprequestexample; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; 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.BasicNameValuePair; import android.app.Activity; import android.os.Bundle; import android.util.Log; public class HTTPGETActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); makeGetRequest(); } private void makeGetRequest() { HttpClient client = new DefaultHttpClient(); HttpGet request = new HttpGet("http://www.example.com"); // replace with your url HttpResponse response; try { response = client.execute(request); Log.d("Response of GET request", response.toString()); } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

At a high level, you use Volley by creating a RequestQueue and passing it Request objects. The RequestQueue manages worker threads for running the network operations, reading from and writing to the cache, and parsing responses. Requests do the parsing of raw responses and Volley takes care of dispatching the parsed response back to the main thread for delivery.

This lesson describes how to send a request using the Volley.newRequestQueue convenience method, which sets up a RequestQueue for you. See the next lesson, for information on how to set up a RequestQueue yourself.

This lesson also describes how to add a request to a RequestQueue and cancel a request.

Add the INTERNET permission

To use Volley, you must add the permission to your app"s manifest. Without this, your app won"t be able to connect to the network.

Use newRequestQueue

Volley provides a convenience method Volley.newRequestQueue that sets up a RequestQueue for you, using default values, and starts the queue. For example:

Kotlin

val textView = findViewById(R.id.text) // ... // Instantiate the RequestQueue. val queue = Volley.newRequestQueue(this) val url = "http://www.google.com" // Request a string response from the provided URL. val stringRequest = StringRequest(Request.Method.GET, url, Response.Listener { response -> // Display the first 500 characters of the response string. textView.text = "Response is: ${response.substring(0, 500)}" }, Response.ErrorListener { textView.text = "That didn"t work!" }) // Add the request to the RequestQueue. queue.add(stringRequest)

Java

final TextView textView = (TextView) findViewById(R.id.text); // ... // Instantiate the RequestQueue. RequestQueue queue = Volley.newRequestQueue(this); String url ="http://www.google.com"; // Request a string response from the provided URL. StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener() { @Override public void onResponse(String response) { // Display the first 500 characters of the response string. textView.setText("Response is: "+ response.substring(0,500)); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { textView.setText("That didn"t work!"); } }); // Add the request to the RequestQueue. queue.add(stringRequest);

Volley always delivers parsed responses on the main thread. Running on the main thread is convenient for populating UI controls with received data, as you can freely modify UI controls directly from your response handler, but it"s especially critical to many of the important semantics provided by the library, particularly related to canceling requests.

See for a description of how to set up a RequestQueue yourself, instead of using the Volley.newRequestQueue convenience method.

Send a request

To send a request, you simply construct one and add it to the RequestQueue with add() , as shown above. Once you add the request it moves through the pipeline, gets serviced, and has its raw response parsed and delivered.

When you call add() , Volley runs one cache processing thread and a pool of network dispatch threads. When you add a request to the queue, it is picked up by the cache thread and triaged: if the request can be serviced from cache, the cached response is parsed on the cache thread and the parsed response is delivered on the main thread. If the request cannot be serviced from cache, it is placed on the network queue. The first available network thread takes the request from the queue, performs the HTTP transaction, parses the response on the worker thread, writes the response to cache, and posts the parsed response back to the main thread for delivery.

Note that expensive operations like blocking I/O and parsing/decoding are done on worker threads. You can add a request from any thread, but responses are always delivered on the main thread.

Figure 1 illustrates the life of a request:

Figure 1. Life of a request.

Cancel a request

To cancel a request, call cancel() on your Request object. Once cancelled, Volley guarantees that your response handler will never be called. What this means in practice is that you can cancel all of your pending requests in your activity"s method and you don"t have to litter your response handlers with checks for getActivity() == null , whether onSaveInstanceState() has been called already, or other defensive boilerplate.

To take advantage of this behavior, you would typically have to track all in-flight requests in order to be able to cancel them at the appropriate time. There is an easier way: you can associate a tag object with each request. You can then use this tag to provide a scope of requests to cancel. For example, you can tag all of your requests with the they are being made on behalf of, and call requestQueue.cancelAll(this) from . Similarly, you could tag all thumbnail image requests in a tab with their respective tabs and cancel on swipe to make sure that the new tab isn"t being held up by requests from another one.

Here is an example that uses a string value for the tag:

  1. Define your tag and add it to your requests.

    Kotlin

    val TAG = "MyTag" val stringRequest: StringRequest // Assume this exists. val requestQueue: RequestQueue? // Assume this exists. // Set the tag on the request. stringRequest.tag = TAG // Add the request to the RequestQueue. requestQueue?.add(stringRequest)

    Java

    public static final String TAG = "MyTag"; StringRequest stringRequest; // Assume this exists. RequestQueue requestQueue; // Assume this exists. // Set the tag on the request. stringRequest.setTag(TAG); // Add the request to the RequestQueue. requestQueue.add(stringRequest);
  2. In your activity"s method, cancel all requests that have this tag.

    Kotlin

    protected fun onStop() { super.onStop() requestQueue?.cancelAll(TAG) }

    Java

    @Override protected void onStop () { super.onStop(); if (requestQueue != null) { requestQueue.cancelAll(TAG); } }

    Take care when canceling requests. If you are depending on your response handler to advance a state or kick off another process, you need to account for this. Again, the response handler will not be called.



Рекомендуем почитать

Наверх