Arduino

Wifi 스마트 콘센트 3 + 앱 위젯

[혜안] 2017. 12. 10. 12:25
728x90

앱 위젯에 설정화면을 넣고, 각 설정에 따라 다르게 동작하도록 하려면,

앱 위젯을 설정위젯으로 변경해주어야 한다.

그 전에, 우선 설정화면용 Activity를 만든다.

버튼 두 개만 있는 단순한 Activity이다.


layout

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="300dp"
    android:layout_height="200dp"
    tools:context="home.viewise.com.plugwidget.PlugWidgetOptionDialog">
 
    <Button
        android:id="@+id/btnPlug1"
        android:layout_width="116dp"
        android:layout_height="90dp"
        android:text="Lan Plug" />
 
    <Button
        android:id="@+id/btnPlug2"
        android:layout_width="116dp"
        android:layout_height="90dp"
        android:text="Wifi Plug" />
</LinearLayout>
cs


class

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
public class PlugWidgetOptionDialog extends Activity {
 
    private static int mAppWidgetId;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_dialog_select_btn);
 
        Bundle mExtras = getIntent().getExtras();
        if (mExtras != null) {
            mAppWidgetId = mExtras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
        }
 
        Button btnPlug1 = (Button)findViewById(R.id.btnPlug1);
        btnPlug1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("위젯""[PlugWidgetOptionDialog] setOnClickListener.LanPlug");
                final Context context = getApplicationContext();
                Intent intent = new Intent(context, PlugWidget.class);
                intent.setAction(context.getResources().getString(R.string.SELECT_PLUG));
                intent.putExtra("WIDGET_ID", mAppWidgetId);
                intent.putExtra("PLUG_ID", R.string.ACTION_LANPLUG);
                sendBroadcast(intent);
 
                Intent resultValue = new Intent();
                resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
                setResult(RESULT_OK, resultValue);
                finish();
            }
        });
 
        Button btnPlug2 = (Button)findViewById(R.id.btnPlug2);
        btnPlug2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("위젯""[PlugWidgetOptionDialog] setOnClickListener.WifiPlug");
                final Context context = getApplicationContext();
                Intent intent = new Intent(context, PlugWidget.class);
                intent.setAction(context.getResources().getString(R.string.SELECT_PLUG));
                intent.putExtra("WIDGET_ID", mAppWidgetId);
                intent.putExtra("PLUG_ID", R.string.ACTION_WIFIPLUG);
                sendBroadcast(intent);
 
                Intent resultValue = new Intent();
                resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
                setResult(RESULT_OK, resultValue);
                finish();
            }
        });
    }
}
cs

위젯 설정용 Activity에서 주의할 부분은 두 가지...

onCreate 이벤트에서 위젯 ID를 가져와서 저장한다.

        Bundle mExtras = getIntent().getExtras();
        if (mExtras != null) {
            mAppWidgetId = mExtras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
        }


그리고, 종료 전에 결과값을 리턴한다.

                Intent resultValue = new Intent();
                resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
                setResult(RESULT_OK, resultValue);
                finish();


선택된 위젯과 그 위젯이 해야할 Action은 저장하기 나름이다.

나는 브로드케스트로 위젯에 날려보내서 위젯에서 저장, 관리하도록 했다.

                Intent intent = new Intent(context, PlugWidget.class);
                intent.setAction(context.getResources().getString(R.string.SELECT_PLUG));
                intent.putExtra("WIDGET_ID", mAppWidgetId);
                intent.putExtra("PLUG_ID", R.string.ACTION_WIFIPLUG);
                sendBroadcast(intent);


그 다음, 생성한 Activity를 위젯 info xml에 설정용 Activity로 등록한다.

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialKeyguardLayout="@layout/plug"
    android:initialLayout="@layout/plug"
    android:minHeight="30dp"
    android:minWidth="30dp"
    android:previewImage="@drawable/plugon"
    android:resizeMode="horizontal|vertical"
    android:updatePeriodMillis="86400000"
    android:configure="home.viewise.com.plugwidget.PlugWidgetOptionDialog"
    android:widgetCategory="home_screen"></appwidget-provider>
cs


여기까지만 하면 위젯을 추가하여 화면에 배치하는 순간 설정화면 Activity가 뜨게된다.

그리고 lanplug와 wifiplug 중 선택을하면 화면은 사라지고, SELECT_PLUG 메시지가 브로드케스팅 된다.


이제, 위젯에서 SELECT_PLUG 브로드케스팅 메시지를 리시버에 추가하자.

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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
 
    @Override
    public void onReceive(Context context, Intent intent){
 
        Log.d(TAG, "[PlugWidget] " + intent.getAction());
 
        boolean state_wifiplug = false;
        boolean state_lan_plug = false;
        RequestPI requestPi = null;
        String sActions = intent.getAction();
        int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0);
 
        if(sActions.equals(context.getResources().getString(R.string.ACTION_CLICK))){
 
            if(getPlugId(context, appWidgetId) == R.string.ACTION_LANPLUG) {
                requestPi = new RequestPI(strPlugTog);
            } else {
                requestPi = new RequestPI(strWifiPlugTog);
            }
            requestPi.start();
        } else if(sActions.equals(context.getResources().getString(R.string.ACTION_UPDATE))) {
 
            requestPi = new RequestPI(strPlugStat);
            requestPi.start();
        } else if(sActions.equals(context.getResources().getString(R.string.ACTION_PUSH))) {
 
            state_lan_plug = intent.getStringExtra("state0").equals("on");
            state_wifiplug = intent.getStringExtra("state1").equals("on");
 
        } else if(sActions.equals(context.getResources().getString(R.string.ACTION_REG))) {
 
            regid = null;
            registerInBackground(context);
        } else if(sActions.equals(context.getResources().getString(R.string.ACTION_WIFIPLUG))){
 
            requestPi = new RequestPI(strWifiPlugTog);
            requestPi.start();
        } else if(sActions.equals(context.getResources().getString(R.string.SELECT_PLUG))) {
            //최초 앱위젯 배치 시...
            int widget_id = intent.getIntExtra("WIDGET_ID"0);
            int plug_id = intent.getIntExtra("PLUG_ID", R.string.ACTION_LANPLUG);
            setPlugId(context, widget_id, plug_id);
        }
 
        if( sActions.equals(context.getResources().getString(R.string.ACTION_UPDATE)) ||
                  sActions.equals(context.getResources().getString(R.string.ACTION_PUSH))
          ) {
 
            Log.d(TAG, "[PlugWidget] onReceive.Icon : " + String.valueOf(isOn));
 
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.plug);
            AppWidgetManager manager = AppWidgetManager.getInstance(context);
 
            int[] appWidgetIds = manager.getAppWidgetIds(new ComponentName(context, getClass()));
            Log.d(TAG, "[PlugWidget] onReceive.appWidgetIds.length: " + String.valueOf(appWidgetIds.length));
            for(int id:appWidgetIds) {
                //Log.d(TAG, "onReceive.appWidgetId : " + String.valueOf(id));
                if(sActions.equals(context.getResources().getString(R.string.ACTION_PUSH)) &&
                        getPlugId(context, id) == R.string.ACTION_LANPLUG) {
                    Log.d(TAG, "[PlugWidget] onReceive.state_lan_plug: " + state_lan_plug);
                    if (state_lan_plug)
                        views.setImageViewResource(R.id.imgBtn, R.drawable.plugon);
                    else
                        views.setImageViewResource(R.id.imgBtn, R.drawable.plugoff);
                } else if(sActions.equals(context.getResources().getString(R.string.ACTION_PUSH)) &&
                        getPlugId(context, id) == R.string.ACTION_WIFIPLUG) {
                    Log.d(TAG, "[PlugWidget] onReceive.state_wifiplug: " + state_wifiplug);
                    if (state_wifiplug)
                        views.setImageViewResource(R.id.imgBtn, R.drawable.wifiplugon3);
                    else
                        views.setImageViewResource(R.id.imgBtn, R.drawable.wifiplugoff3);
                }
 
                updateAppWidget(context, manager, id);//클릭이벤트 재등록
                manager.updateAppWidget(id, views);//ImageViewResource 변경 UI반영
            }
 
            regid = getRegistrationId(context);
 
            if (regid.isEmpty()) {
                registerInBackground(context);
                Log.d(TAG, "[PlugWidget] Issue gcm regid : " + regid);
            }
        }
 
        super.onReceive(context, intent);
    }
 
    private static int getPlugId(Context context, int widget_id) {
        SharedPreferences prefs = context.getSharedPreferences(PlugWidget.class.getSimpleName(), Activity.MODE_PRIVATE);
        int plug_id = prefs.getInt(String.valueOf(widget_id), 0);
        if(plug_id == 0) {
            Log.e(TAG, "[PlugWidget] getPlugId.plug_id is 0!!!");
        }
        Log.d(TAG, "[PlugWidget] getPlugId: " + String.valueOf(widget_id) + "-" + String.valueOf(plug_id));
        return plug_id;
    }
 
    private void setPlugId(Context context, int widget_id, int plug_id) {
        Log.d(TAG, "[PlugWidget] setPlugId: " + String.valueOf(widget_id) + "-" + String.valueOf(plug_id));
        SharedPreferences prefs = context.getSharedPreferences(PlugWidget.class.getSimpleName(), Context.MODE_PRIVATE);
 
        SharedPreferences.Editor editor = prefs.edit();
        editor.putInt(String.valueOf(widget_id), plug_id);
 
        editor.apply();
    }
cs


SELECT_PLUG 메시지를 받으면 SharedPreferences에 현재 추가된 위젯 ID와 호출할 Plug ID 를 저장한다.

        } else if(sActions.equals(context.getResources().getString(R.string.SELECT_PLUG))) {
            //최초 앱위젯 배치 시...
            int widget_id = intent.getIntExtra("WIDGET_ID"0);
            int plug_id = intent.getIntExtra("PLUG_ID", R.string.ACTION_LANPLUG);
            setPlugId(context, widget_id, plug_id);
        }

이와 같이 하면, 앞으로 추가되는 모든 새로운 Plug에 대해 위젯 추가 시 설정 만으로 구분하여 동작하도록 할 수 있다.


첫줄의 if 문이, 호출된 위젯 클릭 이벤트에 대해 위젯 ID로 Plug ID 를 결정하는 구문이다.

        if(sActions.equals(context.getResources().getString(R.string.ACTION_CLICK))){
 
            if(getPlugId(context, appWidgetId) == R.string.ACTION_LANPLUG) {
                requestPi = new RequestPI(strPlugTog);
            } else {
                requestPi = new RequestPI(strWifiPlugTog);
            }
            requestPi.start();
        }


시험해보자!!


728x90