С некоторых пор PayPal предлагает возможность добавления функционала, связанного с оплатой, непосредственно в Android-приложения. Пользователям, в этом случае, нет необходимости заходить на сайт PayPal, все происходит непосредственно в программе. Для этих целей доступен SDK. О том, как его использовать я расскажу в этот раз.

Настройка приложения

Для начала качаем SDK с официального сайта.

Затем создаем Android-приложение в Eclipse.

В архиве с PayPal SDK есть jar-файл PayPal_MPL.jar, который нам необходимо положить в подкаталог lib внутри каталога с исходным кодом нашего приложения (подкаталог lib создаем руками, никто за нас автоматически этого не сделает).

Затем идем в настройки проекта в раздел Java Build Path и на вкладке Libraries с помощью кнопки Add JARs… добавляем эту библиотеку в список используемых в нашем проекте.

В созданном приложении в манифесте необходимо добавить следующие строки:

<activity android:name="com.paypal.android.MEP.PayPalActivity"
                    android:theme="@android:style/Theme.Translucent.NoTitleBar"
                    android:configChanges="keyboardHidden|orientation"/>

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

После этого можно приступать к написанию кода.

Кодинг

SDK позволяет создавать брендированные кнопки для вызова окна оплаты. И вот при создании activity (в методе onCreate()) мы создадим такую кнопку и добавим в layout.

private static final String PAYPAL_APP_ID = "APP-80W284485P519543T";
PayPal mPayPal;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    mPayPal = PayPal.initWithAppID(
				MainActivity.this.getBaseContext(),
				PAYPAL_APP_ID,
				PayPal.ENV_SANDBOX);
    CheckoutButton payButton = mPayPal.getPaymentButton(PayPal.BUTTON_278x43, this, PayPal.PAYMENT_TYPE_HARD_GOODS);
   payButton.setOnClickListener(mPayButtonListener);
   LinearLayout mainLayout = (LinearLayout)findViewById(R.id.main_layout);
   mainLayout.addView(payButton,
       		new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
}

Как видно из кода, у нас используется строка с PayPal Application ID. В примере используется тестовый ID приложения. Его можно посмотреть на странице аккаунта разработчика после регистрации на X.com.

Также хотелось бы отметить, что PayPal позволяет тестировать приложения с использованием “песочницы” (sandbox), а уже после тестирования можно настроить все так, чтобы приложение работало с реальным сайтом. В тестовом приложении мы указываем тип подключения PayPal.ENV_SANDBOX, который указывает что мы используем “песочницу”.

После того, как мы выполнили указанные выше действия, у нас должно получиться что-то вроде этого:

Отлично, кнопку мы добавили, но это всего лишь кнопка, она ничего не делает. Для того, чтобы она что-то делала, необходимо к ней добавить обработчик нажатия:

OnClickListener mPayButtonListener = new OnClickListener() {

		@Override
		public void onClick(View v) {
			PayPalPayment newPayment = new PayPalPayment();

			newPayment.setAmount("5.00");
			newPayment.setCurrency("USD");
			newPayment.setRecipient("zombie_1285772993_biz@wxwidgets.info");
			newPayment.setItemDescription("My Super Item");
			newPayment.setMerchantName("John Doe");

			Intent paypalIntent = new Intent(MainActivity.this, PayPalActivity.class);
			paypalIntent.putExtra(PayPalActivity.EXTRA_PAYMENT_INFO, newPayment);
			MainActivity.this.startActivityForResult(paypalIntent, 1);
		}
	};

E-mail получателя платежа можно получить в песочнице, предварительно создав аккаунт продавца в разделе Test Accounts.

После нажатия на кнопку на экране появляется activity, в которой можно произвести оплату:

E-mail отправителя платежа можно также получитьв “песочнице” после создания тестового аккаунта.

После завершения оплаты нам необходимо как-то узнать результат (оплата может быть отменена пользователем, может произойти ошибка отправки средств и т.д.). Для этого нам необходимо реализовать метод onActivityResult():

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    	String label = "";
    	String transactionID = data.getStringExtra(PayPalActivity.EXTRA_TRANSACTION_ID);
    	switch(resultCode) {
    		case Activity.RESULT_OK:
    			label = "OK";
    			break;
    		case Activity.RESULT_CANCELED:
    			label = "Cancelled";
    			break;
    		case PayPalActivity.RESULT_FAILURE:
    			label = "Failure";
    			break;
      	}
    	TextView resultLabelView = (TextView)findViewById(R.id.result_label);
    	resultLabelView.setText(label + ": " + transactionID);
}

Вместе с SDK поставляется неплохая документация, так что все вопросы решаются довольно быстро. В принципе, работа с PayPal MPL оставила только положительные ощущения, все просто и понятно, не глючит. Примеры, которые идут в поставке тоже работают нормально. Видно что SDK – цельный продукт.

Ну вот, собственно и все.

Напоследдок несколько ссылок:

Исходные коды тестового приложения.

Previous ArticleNext Article
Технический директор IT-Dimension, компании-разработчика кросс-платформенного программного обеспечения

Leave a Reply

Your email address will not be published. Required fields are marked *

A.

ActionBarSherlock – Удобная реализация UI-паттерна ActionBar для Android-приложений – Часть I

Что-то пауза с постами у нас получается совсем нечеловеческая. Попробуем еще разок возобновить публикации.
И сегодня мы познакомимся с библиотекой, реализующей UI-паттерн Action Bar для Android-приложений.

Разработчики библиотеки позиционируют ее как расширение к Compatibility Library, которое для создания ActionBar использует нативную реализацию, если это поддерживается системой, или же вручную дублирует нужный функционал.

Библиотека является open-source проектом и доступна для загрузки на GitHub.

Начало

Начать пользоваться библиотекой довольно просто. Нужно сделать вот что:

  • Унаследовать активити от SherlockActivity (или SherlockListActivity)
  • Переопределить метод onCreateOptionsMenu() и в нем заполнить объект Menu информацией о кнопках
  • В onCreate() или в манифесте указать что используется тема Theme_Sherlock

В итоге код получится приблизительно таким:

package ru.mobiledeveloper.actionbarsherlocktest;

import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;

import android.os.Bundle;
import ru.mobiledeveloper.actionbarsherlocktest.R;

public class ActionBarSherlockTestActivity extends SherlockActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
    	setTheme(R.style.Theme_Sherlock);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add("Save")
            .setIcon(R.drawable.ic_compose)
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);

        menu.add("Search")
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | 
                MenuItem.SHOW_AS_ACTION_WITH_TEXT);

        return true;
    }
}

В результате получим такой внешний вид окна приложения:

Режим действия

ActionBar Sherlock поддерживает возможность отображения контекстно-зависимого содержания. Такая возможность называется режим действий (ActionMode). режим действий можно использовать, например, для отображения контекстного “меню” при длинном нажатии на єлемент списка.
Для того, чтобі добавить возможность отображать режим действий в приложение, нужно сделать следующее:

  • Создать класс, производный от ActionMode.Callback
  • Реализовать в этом классе метод onCreateActionMode(), в котором добавить нужные команды.
  • Реализовать в этом классе метод onActionItemClicked(), в котором написать код, обрабатывающий нажатия на кнопки в ActionBar
  • Для перехода в режим действий вызвать метод startActionMode() и в качестве параметра передать ему объект выше указанного класса

В коде это выглядит приблизительно так:

public class ActionBarSherlockTestActivity extends SherlockActivity {
	
	ActionMode mMode;
	
	private final class ActionModeA implements ActionMode.Callback {

        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            menu.add("Save")
                .setIcon(R.drawable.ic_compose)
                .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
            menu.add("Search")
                .setIcon(R.drawable.ic_search)
                .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
            return true;
        }

		public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
			// TODO Auto-generated method stub
			return false;
		}

		public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
			Toast.makeText(ActionBarSherlockTestActivity.this, 
                            "Got click: " + item, Toast.LENGTH_SHORT).show();
            mode.finish();
			return true;
		}

		public void onDestroyActionMode(ActionMode mode) {
			// TODO Auto-generated method stub
			
		}
        
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
    	setTheme(R.style.Theme_Sherlock);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        Button btnTest = (Button)findViewById(R.id.btnTest);
        if(btnTest != null) {
        	btnTest.setOnClickListener(new OnClickListener() {
				
				public void onClick(View v) {
					mMode = startActionMode(new ActionModeA());
				}
			});
        }
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add("Save")
            .setIcon(R.drawable.ic_compose)
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);

        menu.add("Search")
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | 
                MenuItem.SHOW_AS_ACTION_WITH_TEXT);
        return true;
    }
}

И в результате получаем такое:

Существует, также, возможность отображать ActionBar только в режиме Action Mode и скрывать ее в остальное время работы приложения. Для этого в onCreate() надо вызвать requestWindowFeature(Window.FEATURE_NO_TITLE).

Провайдеры действий

ActionBar Sherlock поддерживает работу с провайдерами действий (Action Provider), которые позволяют реализовать отображение собственных виджетов в ActionBar и добавить более гибкое взаимодействие с пользователем. Action Provier можно повторно использовать в нескольких активитях.
Есть две возможности указать Action Provider для элемента – прописать его в XML файле для пункта меню или указать в коде с помощью setActionProvider().
Рассмотрим реализацию Action Provider’а, который по нажатию на кнопку в ActionBar открывает системные настройки:

public static class SettingsActionProvider extends ActionProvider {
	private static final Intent sSettingsIntent = new Intent(Settings.ACTION_SETTINGS);

	private final Context mContext;

    public SettingsActionProvider(Context context) {
        super(context);
        mContext = context;
    }

    @Override
    public View onCreateActionView() {
        LayoutInflater layoutInflater = LayoutInflater.from(mContext);
        View view = layoutInflater.inflate(R.layout.settings_action_provider, null);
        ImageButton button = (ImageButton) view.findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                mContext.startActivity(sSettingsIntent);
            }
        });
        return view;
    }

    @Override
    public boolean onPerformDefaultAction() {
        mContext.startActivity(sSettingsIntent);
        return true;
    }
}
...
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Этот элемент будет отображен в ActionBar
    menu.add("Settings")
        .setActionProvider(new SettingsActionProvider(
        		ActionBarSherlockTestActivity.this))
        .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | 
        		MenuItem.SHOW_AS_ACTION_WITH_TEXT);
        
    // Этот элемент будет отображен в стандартном меню
    menu.add("Settings")
        .setActionProvider(new SettingsActionProvider(
        		ActionBarSherlockTestActivity.this))
        .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
    return true;
}

XML-файл для кнопки:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:focusable="true"
    android:addStatesFromChildren="true"
    android:background="?attr/actionBarItemBackground"
    style="?attr/actionButtonStyle">
    <ImageButton android:id="@+id/button"
        android:background="@drawable/ic_launcher_settings"
        android:layout_width="32dip"
        android:layout_height="32dip"
        android:layout_gravity="center"
        android:scaleType="fitCenter"
        android:adjustViewBounds="true" />
</LinearLayout>

После создания провайдера действий и добавления его к пунктам меню получим такое:

Collapsible Actions

Есть возможность, при нажатии на пункт меню, отображать собственный контрол на всю ширину ActionBar. Например, для поиска можно отображать текстовое поле. Сделать это можно, указав дайаут с помощью setActionView() и стиль MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW.

public boolean onCreateOptionsMenu(Menu menu) {
    boolean isLight = SampleList.THEME == R.style.Theme_Sherlock_Light;
    menu.add("Search")
        .setIcon(isLight ? R.drawable.ic_search_inverse : R.drawable.ic_search)
        .setActionView(R.layout.collapsible_edittext)
        .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | 
                MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
    return true;
}

При нажатии на пункт в ActionBar будет отображен контрол из XML файла collapsible_edittext.xml.

Полезные функции

Индикатор прогресса
Есть возможность отобразить индикатор прогресса в ActionBar. Такая возможность может быть полезна для отображения прогресса длительной операции. Сделать это можно с помощью метода setSupportProgressBarIndeterminateVisibility().
Оверлей
Можно отображать ActionBar поверх контента при скроллинге. Очень полезная возможность, например, при просмотре текстов. Перевести ActinBar в режим оверлея можно с помощью метода requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY).

Различные типы активитей

В ActionBar Sherlock помимо обычной активити есть классы для отображения активитей со списками, активитей настройки, диалогов.
SherlockPreferenceActivity
Этот класс используется для отображения окон настройки. Функционал аналогичен PreferenceActivity из Android SDK.

SherlockListActivity и SherlockExpandableListActivity
Это активити, производные от ListActivity и ExpandableListActivity соответственно, в которую добавлен функционал по работе с ActionBar.
Диалоги
Есть возможность отображать активити в виде диалогов. Для этого надо указать соответствующую тему в манифесте (необходимо указывать тему именно в манифесте).

<activity
    android:name=".Dialog"
    android:label="@string/dialog"
    android:theme="@style/Theme.Sherlock.Dialog">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="com.actionbarsherlock.sample.demos.EXAMPLE" />
    </intent-filter>
</activity>

На вид выглядит так:

Пара слов о навигации

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

Более подробно реализацию навигации рассмотрим в следующей части статьи.

A.

Android OS – Реальный OpenSource! (теперь в новой упаковке) ;)

Сегодня Джейсон Чен (Jason Chen) в блоге Android Developers Blog анонсировал что Open Handset Alliance опубликовали исходный код платформы Android. Загрузить исходный код, а также ознакомиться с инструкцией по сборке под управлением различных ОС, можно вот по этому адресу (специальный сайт завели для этого, надо же ;)).

Ура, товарищи!