SELECT * FROM Vzakladke.net

Статьи об автоматизации и программировании


Простой пример отправки данных формы POST-запросом на Android

 

 

Отправка данных формы через Андроид не так сложна, как может показаться это на первый взгляд. У многих начинающих могут возникнуть проблемы с тем, что приложение падает после вызова функции отправки сообщения, так как в сети очень распространены примеры, которые не являются рабочими. Основная причина многих ошибок в том, что люди забывают, что для Андроид приложения нужен асинхронный метод отправки данных через AsyncTask.

Предлагаю рассмотреть вариант с отправкой данных из приложения на Android с данными из двух полей на заранее подготовленный сервер, где будет обрабатываться наш запрос. Для начала необходимо воссоздать макет страницы. Пусть кнопка отправки сообщений будет вверху, нам так удобнее при работе с приложением, и добавим два поля EditText и один ProgressBar (который в приложении при загрузке сначала должен быть невидимым, я укажу это в коде активити).

 

Теперь нарисуем разметку activity_main.xml:

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
     
    <Button
        android:text="Send"
        android:id="@+id/sendButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
    />
        
    <EditText
        android:id="@+id/titleTextField"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="Your Title"
    />
    
    
    <EditText
        android:id="@+id/msgTextField"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="5"
            android:lines="5" 
            android:singleLine="false"        
        android:hint="Your Message"
        android:inputType="textMultiLine">
        <requestFocus />
    </EditText>
        
    <ProgressBar
        android:id="@+id/progressBar1"
  	android:layout_width="match_parent"
    android:layout_height="match_parent"
 	android:layout_margin="100px"
    android:layout_centerInParent="true" />
      
</LinearLayout>

 

Android Post Form

После того как мы добавили разметку нашему приложению хотелось бы сразу оговорить и права доступа приложения к интернету, иначе понятно что ничего работать не будет. Поэтому сразу после блока <uses-sdk ... /> добавим разрешение нашему приложению:

<uses-permission android:name="android.permission.INTERNET"/>

 

Дальше нам понадобится модуль apache. Так как программа разрабатывалась в Eclipse ADT - проблем с поиском этого модуля не было. Сначала пропишем все необходимые модули для нашего приложения:

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.os.AsyncTask;
import java.io.IOException;
import org.apache.http.client.ClientProtocolException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import android.widget.Toast;

 

Теперь рассмотрим JAVA код нашего приложения в MainActivity.java, которое по нашей задумке должно отправлять данные на сервер.

Первое что необходимо выделить отдельно, так это наши переменные связанные с серверной стороной, поскольку так будет легче в будущем контролировать код на клиенте и на сервере в случае необходимости проведения каких то изменений, например SERVER_URL - это адрес нашего скрипта на сервере, SERVER_TITLE - это заголовок нашей статьи и SERVER_MESSAGE - текст нашей статьи, который мы будем "постить" через форму из Андроид-приложения. Далее по коду мы в методе doInBackground сделаем вызов нашей функции асинхронной отправки данных на сервер и в методе onPostExecute оставим уведомление о том, что информация была направлена после нажатия кнопки отправки и очистим нашу форму.

 

public class MainActivity extends Activity {

    String SERVER_URL = "http://asksql.org/";
    String SERVER_TITLE = "title";
    String SERVER_MESSAGE = "message";
    
    Button sendButton;
    EditText title_param, msg_param;
    ProgressBar pb;
    
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
        sendButton = (Button) findViewById(R.id.sendButton);
        title_param = (EditText)findViewById(R.id.titleTextField);
        msg_param = (EditText)findViewById(R.id.msgTextField);
        pb = (ProgressBar)findViewById(R.id.progressBar1);
        pb.setVisibility(View.GONE); 
        
       // String  titleToSend = titleTextField.getText().toString(); 
        sendButton.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
					if(msg_param.getText().toString().length()<1){
						// out of range				 
						 Toast.makeText(MainActivity.this, "Please enter message", Toast.LENGTH_LONG).show();
					}else{
						pb.setVisibility(View.VISIBLE); 
						new MyAsyncTask().execute(title_param.getText().toString(), msg_param.getText().toString());	
					}
				
				}
			}); 		
		
	    }
	
	
    	private class MyAsyncTask extends AsyncTask<String, Integer, Double>{   		 
    		@Override
    		protected Double doInBackground(String... params) {
    			// TODO Auto-generated method stub
    			postData(params[0],params[1]);
    			return null;
    		}
     
    		protected void onPostExecute(Double result){
    			pb.setVisibility(View.GONE);
    			Toast.makeText(getApplicationContext(), "Info sent", Toast.LENGTH_LONG).show();
    			title_param.setText(""); //reset the message text field title_param, msg_param;
    			msg_param.setText("");
    		}
    		protected void onProgressUpdate(Integer... progress){
    			pb.setProgress(progress[0]);
    		}
     
    		public void postData(String titleToSend, String msgToSend) {
    			// Create a new HttpClient and Post Header
    			HttpClient httpclient = new DefaultHttpClient();
    			HttpPost httppost = new HttpPost(SERVER_URL);
     
    			try {
    				// Add your data
    				List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);    		 
    				
    			    nameValuePairs.add(new BasicNameValuePair(SERVER_TITLE, titleToSend));
    				nameValuePairs.add(new BasicNameValuePair(SERVER_MESSAGE, msgToSend));
    	    		
    				 httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, HTTP.UTF_8));
     
    				// Execute HTTP Post Request
    				HttpResponse response = httpclient.execute(httppost);      
    			} catch (ClientProtocolException e) {
    				// TODO Auto-generated catch block
    				Toast.makeText(getBaseContext(),"Client Protocol Exception",Toast.LENGTH_SHORT).show();
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				Toast.makeText(getBaseContext(),"IO Exception",Toast.LENGTH_SHORT).show();
    			}

    		}     				
	}

		
	///// MENU ========================================
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    switch (item.getItemId()) {
	    case R.id.menuClose:
	    	MainActivity.this.finish();
	    	System.exit(0);
	        return true;
	}
	    return super.onOptionsItemSelected(item);
	} 
	
}

 

Считайте, что бонусом здесь указана кнопка закрытия для окна нашего приложения, поэтому в res/values/strings.xml добавим нашу переменную с обозначением нашей кнопки:

<string name="title_close">Close</string>

и разметка самого меню будет выглядеть таким образом, где android:showAsAction="always|withText" скажет нашему приложению чтобы кнопка отображалась как текст, а не в выпадающем списке.

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:id="@+id/menuClose"
        android:orderInCategory="110"
        android:showAsAction="always|withText"
        android:title="@string/title_close"/>
</menu>

 

Чтобы принять это сообщение на стороне сервера в качестве примера приведем php-скрипт, в первом варианте для сохранения в базе данных: 

 <?php
 $hostname = "localhost";
 $username = "имя";
 $password = "пароль";
 $dbName = "имя базы";
 $userstable = "имя таблицы";
 
 mysql_connect($hostname,$username,$password)
 or die("Не могу создать соединение ");

 mysql_select_db($dbName) or die(mysql_error()); 
 $msg = $_POST["message"]; $title = $_POST["title"];
 $query = "INSERT INTO $userstable (`title`, `msg`) VALUES('$title', '$msg')"; 
 mysql_query($query) or die(mysql_error());
 mysql_close();
 ?>

Другой вариант - сохранение в файл submittedmsg.html, выбирайте какой Вам способ больше нравится для теста.

<?php
$title=$_POST["title"]; 
$message=$_POST["message"]; 
$filename="submittedmsg.html";
file_put_contents($filename,$title." - ".$message." (From Android)",FILE_APPEND);
$androidmessages=file_get_contents($filename);
echo $androidmessages;
?>

 

Дата публикации: 2016-07-12 09:57:23

Android

1

Отзывы:

Ваше имя:

Ваш e-mail (необязательно):

Сообщение:

Captcha