본문 바로가기
Android 기법/# Study

[Android/안드로이드]간단한 위젯(Widget) 만들기[GitHub](android Widget)(multiple button)

by 퍼즐잎 2017. 2. 28.





간단하게 위젯을 만들어 보겠습니다.








프로젝트를 생성하고 MainActivity는 건들지 않고


아래 내용을 추가하면 됩니다.





[simple_widget.xml]


위젯의 내용을 구성하는 xml 입니다.


1
2
3
4
5
6
7
8
9
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
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:background="#55ffffff"
    tools:context="puzzleleaf.tistory.com.mywidgetex.MainActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal">
        <ImageView
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:src="@drawable/logo2"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/simpleWidget"
            android:textSize="30sp"
            android:textStyle="bold"
            android:textColor="#39b29c"
            android:text="PuzzleLeaf Blog" />
    </LinearLayout>
    <Button
        android:layout_width="wrap_content"
        android:background="#39b29c"
        android:text="Blog"
        android:layout_marginTop="5dp"
        android:textColor="#ffffff"
        android:textSize="20sp"
        android:id="@+id/simple_btn"
        android:layout_height="25dp" />
    <Button
        android:layout_width="wrap_content"
        android:background="#39b29c"
        android:layout_marginTop="10dp"
        android:text="Test"
        android:textColor="#ffffff"
        android:textSize="20sp"
        android:id="@+id/simple_btn2"
        android:layout_height="25dp" />
</LinearLayout>
 
cs




[widget_provider.xml]


res내부에 xml 폴더를 생성하고 추가해야 합니다.


1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
    android:initialLayout="@id/simpleWidget"
    android:minWidth="146dp"
    android:minHeight="72dp"
    android:updatePeriodMillis="600000"
    android:resizeMode="horizontal|vertical"
    xmlns:android="http://schemas.android.com/apk/res/android" />
cs



[My_Widget_Provider.java]


위젯을 추가하고 이벤트를 적용하기 위한 코드


onReceive를 처음 시작으로 아래 코드를 참고할 수 있습니다.



위젯은 화면에서 여러 개를 추가할 수 있는데


각 위젯마다 ID를 가지고 있습니다.



onReceive에서 위젯이 존재하는 경우 onUpdate를 호출하게 됩니다.


onUpdate 내부에서 각 appWidgetId에 대하여


즉, 각각의 위젯에 대하여 RemoteView를 할당하게 됩니다.




RemoteView는 buildView 함수를 통해서 할당이 되는데


이것은 buildURIIntent 함수와 buildToastIntent 함수에 의해서


PendingIntent가 onClick 이벤트로 추가가 됩니다.


(PendingIntent란 ? - 링크)


(RemoteView란 ? - 링크)




buildURIIntent 함수는 버튼을 클릭한 경우


지정한 링크로 이동하도록 하는 역할을 하고




buildToastIntent 함수는 자세히 보면


new Intent("Click1") 이 쓰여있는데


PendingIntent에서 getBroadCast()를 통해


Click1 이라는 Action을 발생시킨다.





onReceive 함수에서 Click1을 감지하는 경우


Toast를 출력하게 된다.


(AndroidManifest.xml 에서 따로 추가해야 한다.)




1
2
3
4
5
6
7
8
9
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
public class My_Widget_Provider extends AppWidgetProvider{
 
 
    @Override
    public void onReceive(Context context, Intent intent) {
        super.onReceive(context, intent);
 
        String action = intent.getAction();
        if(AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action))
        {
            Bundle extras = intent.getExtras();
            //Bundle 은 Key-Value 쌍으로 이루어진 일종의 해쉬맵 자료구조
            //한 Activity에서 Intent 에 putExtras로 Bundle 데이터를 넘겨주고,
            //다른 Activity에서 getExtras로 데이터를 참조하는 방식입니다.
            if(extras!=null)
            {
                int [] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
                if(appWidgetIds!=null && appWidgetIds.length>0)
                    this.onUpdate(context,AppWidgetManager.getInstance(context),appWidgetIds);
            }
        }//업데이트인 경우
        else if(action.equals("Click1"))
        {
            Toast.makeText(context,"Hello",Toast.LENGTH_SHORT).show();
        }
    }
 
 
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        super.onUpdate(context, appWidgetManager, appWidgetIds);
        final int N = appWidgetIds.length;
        for(int i=0;i<N;i++)
        {
            int appWidgetId = appWidgetIds[i];
            RemoteViews views = buildViews(context);
            appWidgetManager.updateAppWidget(appWidgetId,views);
        }
    }
 
    private PendingIntent buildURIIntent(Context context)
    {
        Intent intent = new Intent(Intent.ACTION_VIEW).setData(Uri.parse("http://puzzleleaf.tistory.com"));
        PendingIntent pi = PendingIntent.getActivity(context,0,intent,0);
        return pi;
    }
 
    //Click1 이라는 Action을 onReceive로 보낸다.
    private PendingIntent buildToastIntent(Context context)
    {
        Intent in = new Intent("Click1");
        PendingIntent pi = PendingIntent.getBroadcast(context,0,in,PendingIntent.FLAG_UPDATE_CURRENT);
        return pi;
    }
 
    //위젯에 멀티 버튼 추가하기
    private RemoteViews buildViews(Context context)
    {
        RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.simple_widget);
        views.setOnClickPendingIntent(R.id.simple_btn,buildURIIntent(context));
        views.setOnClickPendingIntent(R.id.simple_btn2,buildToastIntent(context));
 
        return views;
    }
}
cs




[AndroidManifest.xml]


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="puzzleleaf.tistory.com.mywidgetex">
 
    <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <receiver android:name=".My_Widget_Provider">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
                <action android:name="Click1"/>
            </intent-filter>
            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/widget_provider"/>
        </receiver>
 
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
 
</manifest>
cs








아래 예제를 통해 실행해볼 수 있습니다.





댓글