В этом примере мы увидим, как вы можете создать виджет Android на домашнем экране, который может открыть всплывающее диалоговое окно. Как вы знаете, Android Widgets — это небольшие приложения, которые в основном могут выполнять две функции. Запустите новое действие при нажатии или отобразите информацию, которая обновляется через определенный промежуток времени.
1. Введение
Виджеты используют RemoteViews
для отображения своего пользовательского интерфейса. RemoteViews
может быть выполнен другим процессом с теми же разрешениями, что и в исходном приложении. Таким образом, виджет работает с разрешениями своего определяющего приложения. Это форма официальной документации Android: « RemoteView
— это класс, который описывает иерархию представлений, которая может отображаться в другом процессе. Иерархия раздувается из файла ресурсов макета, и этот класс предоставляет некоторые основные операции для изменения содержимого раздутой иерархии ».
Пользовательский интерфейс виджета определяется BroadcastReceiver
. Этот BroadcastReceiver
раздувает макет в RemoteViews
виджета. Затем RemoteViews
доставляется на Android, который обновляет пользовательский интерфейс приложения на домашнем экране.
Виджеты имеют ограниченную функциональность и стили по сравнению с Activities
. Поэтому вам, возможно, придется обойтись, чтобы сделать более сложные вещи, как мы хотим. Итак, чтобы запустить всплывающий диалог из нашего виджета, вот что мы делаем: когда щелкаем виджет, мы просто запускаем новое действие с android:theme="@android:style/Theme.Dialog"
установленное в конфигурации Activity
в AndroidManifest.xml
.
Подводя итог основным шагам, мы собираемся:
- Создать виджет Android.
- Создайте
Intent
которое при отправке вBroadcastReceiver
помечает запуск нового действия. - Зарегистрируйте
ClickListener
для виджета. Таким образом, при нажатии виджета вышеупомянутоеIntent
будет отправлено вBroadcastReceiver
. - Когда это
Intent
получено, будет запущено новое действие, которое будет выглядеть как всплывающее диалоговое окно.
Посмотрим, как это делается.
2. Создайте новый Android-виджет
В этом руководстве мы будем использовать следующие инструменты на 64-битной платформе Windows:
- JDK 1,7
- Eclipse 4.3 Kepler
- Android SKD 4.3
2.1 Создание нового проекта Android
Откройте Eclipse IDE и перейдите в Файл -> Создать -> Проект -> Android -> Проект приложения Android.
Вы должны указать Имя приложения, Имя проекта и Имя пакета в соответствующих текстовых полях и затем нажать Далее.
В следующем окне снимите флажок «Создать действие», так как позже мы создадим PopUpActivity
.
Нажмите «Готово».
2.2 Определите пользовательскую форму фона для виджета
Перейдите в проводник пакетов и откройте папки /res/drawable-*
.
Щелкните правой кнопкой /res/drawble-hdpi
по одной из папок (я выбрал /res/drawble-hdpi
) -> Создать -> Другое -> Android -> Android XML File
Из списка «Root Element» выберите форму и дайте файлу имя custom_shape.xml:
Теперь откройте этот файл и вставьте следующий код, описывающий макет простой фигуры.
custom_shape.xml:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
<? xml version = "1.0" encoding = "UTF-8" ?> android:shape = "rectangle" > < gradient android:angle = "90" android:endColor = "#333" android:startColor = "#333" /> < corners android:bottomLeftRadius = "2dp" android:bottomRightRadius = "2dp" android:topLeftRadius = "2dp" android:topRightRadius = "2dp" /> < stroke android:width = "2dp" android:color = "#333" /> </ shape > |
2.3 Определите простой макет для виджета
Перейдите к папке res/layout
в Package Explorer. Щелкните правой кнопкой мыши папку -> «Создать» -> «Другое» -> Android -> Android XML Layout File. Создайте файл с именем widget_layout
.
И вставьте следующий код:
widget_layout.xml
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<? xml version = "1.0" encoding = "utf-8" ?> android:id = "@+id/linearLayout" android:layout_width = "match_parent" android:layout_height = "match_parent" android:layout_margin = "8dip" android:background = "@drawable/custom_shape" > < TextView android:id = "@+id/myText" style = "@android:style/TextAppearance.Medium" android:layout_width = "match_parent" android:layout_height = "match_parent" android:layout_gravity = "center" android:layout_margin = "4dip" android:gravity = "center_horizontal|center_vertical" android:text = "Press Me" android:textColor = "#FFF" > </ TextView > </ LinearLayout > |
2.4 Создайте файл описания AppWidgetProvider
XML.
Перейдите в Файл -> Создать -> Другое -> Android -> Файл Android XML. В списке «Тип ресурса» выберите «Поставщик AppWidget» и назовите файл widget_provider.xml.
Вы найдете файл во вновь созданной папке /res/xml
:
Откройте файл и вставьте следующий код, который в основном представляет собой метаданные для AppWidgetProvider.
widget_provider.xml:
1
2
3
4
5
6
7
|
<? xml version = "1.0" encoding = "utf-8" ?> android:initialLayout = "@layout/widget_layout" android:minHeight = "50dp" android:minWidth = "120dp" > </ appwidget-provider > |
2.5 Создайте класс AppWidgetProvider
Теперь создайте новый класс, который расширяет AppWidgetProvider
, в пакете com.javacodegeeks.android.androidwidgetdialog
. Это будет BroadcastReceiver
виджета.
AndroidWidget.java:
01
02
03
04
05
06
07
08
09
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
57
58
59
60
61
62
63
64
65
66
67
68
|
package com.javacodegeeks.android.androidwidgetdialog; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.widget.RemoteViews; public class AndroidWidget extends AppWidgetProvider { private static final String SHOW_POPUP_DIALOG_ACTION = "com.javacodegeeks.android.showpopupdialog" ; @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int [] appWidgetIds) { ComponentName thisWidget = new ComponentName(context, AndroidWidget. class ); // Obtain all instances of our widget // Remember that you can have as many instances of the same widget as you want on the home screen int [] allWidgetInstancesIds = appWidgetManager.getAppWidgetIds(thisWidget); for ( int widgetId : allWidgetInstancesIds) { RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout); // Create an intent that when received will launch the PopUpActivity Intent intent = new Intent(context, AndroidWidget. class ); intent.setAction(SHOW_POPUP_DIALOG_ACTION); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0 , intent, PendingIntent.FLAG_UPDATE_CURRENT); // Set up the onClickListener of the widget // Now, when the widget is pressed the pendingIntent will be sent remoteViews.setOnClickPendingIntent(R.id.myText, pendingIntent); appWidgetManager.updateAppWidget(widgetId, remoteViews); } super .onUpdate(context, appWidgetManager, appWidgetIds); } @Override public void onReceive( final Context context, Intent intent) { // If the intent is the one that we've defined to launch the pop up dialog // then create and launch the PopUpActivity if (intent.getAction().equals(SHOW_POPUP_DIALOG_ACTION)) { Intent popUpIntent = new Intent(context, PopUpActivity. class ); popUpIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(popUpIntent); } super .onReceive(context, intent); } } |
Как видите, мы используем экземпляр PendingIntent
. PendingIntent
— это описание намерения и целевого действия, которое необходимо выполнить с ним. Когда вы передаете PendingIntent
другому приложению, вы предоставляете ему право выполнять указанную вами операцию с теми же разрешениями и идентичностью. И поэтому вы должны быть осторожны с тем, как вы используете PendingIntent
. В этом примере мы получили экземпляр getBroadcast
вызывающий метод getBroadcast
. Этот метод будет извлекать PendingIntent
который будет выполнять широковещательную передачу, например, вызывая Context.sendBroadcast()
.
Теперь поток выполнения выглядит так:
- Как определено, метод
onUpdate
выполняется только один раз, когда виджет установлен на домашнем экране. Вы можете установить временной интервал для выполнения методаonUpdate
, определив свойствоandroid:updatePeriodMillis
в файлеwidget_provider.xml
. Поэтому, когда методonUpdate
выполняется, сначала мы получаем все идентификаторы экземпляра виджета, который пользователь установил на домашнем экране. - Затем мы создаем новое
Intent
с действиемcom.javacodegeeks.android.showpopupdialog
. Получить новую трансляциюPendingIntent
- Зарегистрируйте прослушиватель
OnClickPendingIntent
дляRemoteView
каждого виджета. - Теперь, когда пользователь нажимает на виджет, будет
com.javacodegeeks.android.showpopupdialog
Intent
с действиемcom.javacodegeeks.android.showpopupdialog
. Это намерение, созданное в строке 32 приведенного выше кода (также используется для создания экземпляраPendingIntent
). - Намерение будет получено, и
onReceive
будет выполнен. Если полученноеIntent
имеет действиеPopUpActivity
будет запущен классPopUpActivity
.
Теперь давайте посмотрим код PopUpActivity.
3. Создайте PopUpActivity
PopUpActivity
— это простой класс Activity
который будет запущен в виде диалогового окна.
Перейдите в проводник пакетов и щелкните правой кнопкой мыши на пакете com.javacodegeeks.android.androidwidgetdialog
-> Создать -> Другое -> Android -> Активность Android.
Установите имя «PopUpActivity». Как вы можете видеть, файл макета этого действия будет автоматически создан с именем «activity_pop_up.xml».
Чтобы установить макет действия, откройте файл /res/layout/activity_pop_up.xml
и вставьте следующий код.
activity_pop_up.xml:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<? xml version = "1.0" encoding = "utf-8" ?> android:layout_width = "220dp" android:layout_height = "wrap_content" android:gravity = "center_horizontal" android:orientation = "vertical" > < TextView android:id = "@+id/mytxt" android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:layout_marginBottom = "10dp" android:layout_marginLeft = "0dp" android:layout_marginRight = "0dp" android:layout_marginTop = "5dp" android:gravity = "center_horizontal" android:textColor = "#FFF" android:textSize = "13sp" /> < Button android:id = "@+id/closBtn" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "Close" /> </ LinearLayout > |
Это код класса PopUpActivity
.
PopUpActivity.java:
01
02
03
04
05
06
07
08
09
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
|
package com.javacodegeeks.android.androidwidgetdialog; import java.util.Random; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.view.Window; import android.widget.Button; import android.widget.TextView; public class PopUpActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_pop_up); String dialogText = "Dialog Box : " + ( new Random().nextInt( 100 )); TextView txt = (TextView) findViewById(R.id.mytxt); txt.setText(dialogText); Button dismissbutton = (Button) findViewById(R.id.closBtn); dismissbutton.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { PopUpActivity. this .finish(); } }); } } |
Ничего особенного в приведенном выше коде. Мы просто устанавливаем значение mytxt
TextView
. И мы регистрируем ClickListener
для кнопки отклонения. Когда кнопка нажата, PopUpActivity
прекращается.
4. Конфигурация AndroidManifest.xml
Это очень важный шаг урока. Откройте файл AndroidManifest.xml
и вставьте следующий код:
AndroidManifest.xml:
01
02
03
04
05
06
07
08
09
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
|
<? xml version = "1.0" encoding = "utf-8" ?> package = "com.javacodegeeks.android.androidwidgetdialog" android:versionCode = "1" android:versionName = "1.0" > < uses-sdk android:minSdkVersion = "8" android:targetSdkVersion = "18" /> < application android:allowBackup = "true" android:icon = "@drawable/ic_launcher" android:label = "@string/app_name" android:theme = "@style/AppTheme" > < receiver android:name = ".AndroidWidget" android:icon = "@drawable/ic_launcher" android:label = "Android Custom Widget" > < intent-filter > < action android:name = "com.javacodegeeks.android.showpopupdialog" /> < action android:name = "android.appwidget.action.APPWIDGET_UPDATE" /> </ intent-filter > < meta-data android:name = "android.appwidget.provider" android:resource = "@xml/widget_provider" /> </ receiver > < activity android:name = "com.javacodegeeks.android.androidwidgetdialog.PopUpActivity" android:label = "@string/title_activity_pop_up" android:theme = "@android:style/Theme.Dialog" > </ activity > </ application > </ manifest > |
Как вы можете видеть, мы настроили приемник, который регистрирует наш код> AppWidgetProvider для нашего приложения, который может принимать широковещательные сообщения.
- <action android: name = ”com.javacodegeeks.android.showpopupdialog” />
- <action android: name = ”android.appwidget.action.APPWIDGET_UPDATE» />
Первый — это Намерение, которое мы зарегистрировали сами. Второй — это намерение, отправленное Android. Мы также предоставляем метаданные для AppWidgetProvider
, указывая на widget_provider.xml
ресурса widget_provider.xml
который мы создали ранее.
Важный бит находится в строке 34, где мы определяем тему приложения как android:theme="@android:style/Theme.Dialog"
. Это создаст активность с всплывающей диалоговой темой.
Посмотрим, как это выглядит на эмуляторе.
5. Запустите приложение
После запуска приложения и запуска эмулятора перейдите на кнопку «Приложения» на главном экране:
Нажмите на «Виджеты». Перетащите свой виджет на главный экран
Вот:
Теперь, когда вы нажимаете на виджет:
Вот и все.
Скачать проект Eclipse
Это был пример Android о том, как создать модальное диалоговое окно (всплывающее окно) из виджета Android. Загрузите проект Eclipse этого руководства: AndroidWidgetDialog.zip