2ec56e2442d1e960378f9869a1b339f9c3b8a12e
[fonbot.git] / src / ro / ieval / fonbot / FonBotMainActivity.java
1 package ro.ieval.fonbot;
2
3 import static ro.ieval.fonbot.R.string.logging_in;
4 import static ro.ieval.fonbot.Utils.toNonNull;
5
6 import java.io.InputStream;
7 import org.eclipse.jdt.annotation.Nullable;
8
9 import ro.ieval.fonbot.FonBotMainService.Binder;
10 import ro.ieval.fonbot.HttpCallExecutableRunnable.ResultCallback;
11 import ro.ieval.fonbot.Utils.OngoingEvent;
12 import android.app.ListActivity;
13 import android.content.BroadcastReceiver;
14 import android.content.ComponentName;
15 import android.content.Context;
16 import android.content.Intent;
17 import android.content.IntentFilter;
18 import android.os.Bundle;
19 import android.os.IBinder;
20 import android.support.v4.content.LocalBroadcastManager;
21 import android.view.LayoutInflater;
22 import android.view.Menu;
23 import android.view.MenuItem;
24 import android.view.View;
25 import android.view.View.OnClickListener;
26 import android.view.ViewGroup;
27 import android.widget.Button;
28 import android.widget.LinearLayout;
29 import android.widget.TextView;
30
31 /*
32 * Copyright © 2013 Marius Gavrilescu
33 *
34 * This file is part of FonBot.
35 *
36 * FonBot is free software: you can redistribute it and/or modify
37 * it under the terms of the GNU General Public License as published by
38 * the Free Software Foundation, either version 3 of the License, or
39 * (at your option) any later version.
40 *
41 * FonBot is distributed in the hope that it will be useful,
42 * but WITHOUT ANY WARRANTY; without even the implied warranty of
43 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
44 * GNU General Public License for more details.
45 *
46 * You should have received a copy of the GNU General Public License
47 * along with FonBot. If not, see <http://www.gnu.org/licenses/>.
48 */
49
50 /**
51 * Main Activity. Shows the login status and a list of ongoing events.
52 *
53 * @author Marius Gavrilescu <marius@ieval.ro>
54 */
55 public final class FonBotMainActivity extends ListActivity {
56 /**
57 * Adapter for the ongoing event list. Shows a list of ongoing events with cancel buttons.
58 *
59 * @author Marius Gavrilescu
60 */
61 private static final class ArrayAdapter extends android.widget.ArrayAdapter<OngoingEvent>{
62 /**
63 * Constructs an ArrayAdapter with a given list of events
64 *
65 * @param context Context instance
66 * @param objects the list of events
67 */
68 public ArrayAdapter(final Context context, final OngoingEvent[] objects) {
69 super(context, 0, 0, objects);
70 }
71
72 @Override
73 public View getView(final int position, final @Nullable View convertView, final @Nullable ViewGroup parent) {
74 final LayoutInflater inflater=(LayoutInflater) getContext().getSystemService(LAYOUT_INFLATER_SERVICE);
75 final View listItem;
76
77 if(convertView instanceof LinearLayout){
78 listItem=convertView;
79 } else
80 listItem=inflater.inflate(R.layout.ongoing_list_item, parent, false);
81
82 final Button button=(Button) listItem.findViewById(R.id.ongoingItemButton);
83 final TextView textView=(TextView) listItem.findViewById(R.id.ongoingItemTextView);
84 final OngoingEvent event=getItem(position);
85
86 textView.setText(event.resource);
87 button.setOnClickListener(new OnClickListener() {
88 @Override
89 public void onClick(final @Nullable View v) {
90 Heavy.cancelOngoing(toNonNull(getContext()), event);
91 }
92 });
93
94 return listItem;
95 }
96 }
97
98 /**
99 * ServiceConnection for getting the ongoing event list from {@link FonBotMainService}
100 *
101 * @author Marius Gavrilescu <marius@ieval.ro>
102 */
103 private final class ServiceConnection implements android.content.ServiceConnection{
104 /** Binder got from onServiceConnected */
105 private Binder binder;
106
107 @Override
108 public void onServiceDisconnected(final @Nullable ComponentName name) {
109 // do nothing
110 }
111
112 @Override
113 public void onServiceConnected(final @Nullable ComponentName name, final @Nullable IBinder service) {
114 if(service==null)
115 return;
116 binder=(Binder) service;
117 refreshAdapter();
118 }
119
120 /**
121 * Updates the list of ongoing events from the service.
122 */
123 public void refreshAdapter(){
124 if(binder==null)
125 return;
126 setListAdapter(new ArrayAdapter(FonBotMainActivity.this,
127 toNonNull(binder.getService().getOngoingEvents().toArray(new OngoingEvent[0]))));
128 }
129 }
130
131 /**
132 * BroadcastReceiver that refreshes the ongoing event list.
133 *
134 * @author Marius Gavrilescu <marius@ieval.ro>
135 */
136 private final class OngoingUpdateReceiver extends BroadcastReceiver{
137 @Override
138 public void onReceive(final @Nullable Context context, final @Nullable Intent intent) {
139 connection.refreshAdapter();
140 }
141 }
142
143 /**
144 * BroadcastReceiver that updates {@link #resultTextView}
145 *
146 * @author Marius Gavrilescu <marius@ieval.ro>
147 */
148 private final class LoginReceiver extends BroadcastReceiver {
149 @Override
150 public void onReceive(@Nullable final Context context, @Nullable final Intent intent) {
151 if(intent==null)
152 return;
153 resultTextView.setText(intent.getStringExtra(BroadcastResultCallback.EXTRA_RESPONSE_MESSAGE));
154 final int responseCode=intent.getIntExtra(BroadcastResultCallback.EXTRA_RESPONSE_CODE, 0);
155 if(responseCode>=200&&responseCode<300)
156 resultTextView.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.tick, 0, 0);
157 else
158 resultTextView.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.cross, 0, 0);
159 }
160 }
161
162 /**
163 * Implementation of <code>ResultCallback</code> that broadcasts a {@link #LOGIN_BROADCAST}
164 *
165 * @author Marius Gavrilescu
166 */
167 public final class BroadcastResultCallback implements ResultCallback{
168 /**
169 * Extra: the response message
170 */
171 public static final String EXTRA_RESPONSE_MESSAGE="response_message";
172 /**
173 * Extra: the response code
174 */
175 public static final String EXTRA_RESPONSE_CODE="response_code";
176
177 @Override
178 public void onResult(final int responseCode, final String responseMessage, final InputStream inputStream) {
179 final Intent intent=new Intent(LOGIN_BROADCAST);
180 intent.putExtra(EXTRA_RESPONSE_MESSAGE, responseMessage);
181 intent.putExtra(EXTRA_RESPONSE_CODE, responseCode);
182 sendBroadcast(intent);
183 }
184
185 @Override
186 public void onError(final String error) {
187 final Intent intent=new Intent(LOGIN_BROADCAST);
188 intent.putExtra(EXTRA_RESPONSE_MESSAGE, error);
189 sendBroadcast(intent);
190 }
191 }
192
193 /**
194 * The one instance of {@link OngoingUpdateReceiver}
195 */
196 private final BroadcastReceiver ongoingUpdateReceiver=new OngoingUpdateReceiver();
197 /**
198 * IntentFilter for {@link #ongoingUpdateReceiver}
199 */
200 private static final IntentFilter ONGOING_UPDATE_FILTER=new IntentFilter(FonBotMainService.ACTION_ONGOING_UPDATE);
201 /**
202 * The one instance of {@link LoginReceiver}
203 */
204 private final BroadcastReceiver loginReceiver=new LoginReceiver();
205 /**
206 * The broadcast sent by {@link HttpCallExecutableRunnable} when logging in.
207 */
208 private static final String LOGIN_BROADCAST="ro.ieval.fonbot.LOGIN_RESULT";
209 /**
210 * IntentFilter for {@link #loginReceiver}
211 */
212 private static final IntentFilter LOGIN_FILTER=new IntentFilter(LOGIN_BROADCAST);
213 /**
214 * The one instance of {@link BroadcastResultCallback}
215 */
216 private final BroadcastResultCallback broadcastResultCallback=new BroadcastResultCallback();
217 /**
218 * The one instance of {@link ServiceConnection}
219 */
220 private final ServiceConnection connection=new ServiceConnection();
221
222 /**
223 * TextView that tells the user whether logging in failed or succeded.
224 */
225 private TextView resultTextView;
226
227 @Override
228 protected void onCreate(@Nullable final Bundle icicle) {
229 super.onCreate(icicle);
230
231 setContentView(R.layout.main);
232
233 resultTextView=(TextView) findViewById(R.id.resultTextView);
234 }
235
236 @Override
237 protected void onStart() {
238 super.onStart();
239 resultTextView.setText(logging_in);
240 new HttpCallExecutableRunnable("/ok", null,
241 toNonNull(getApplicationContext()), toNonNull(broadcastResultCallback)).execute();
242 connection.refreshAdapter();
243 }
244
245 @Override
246 protected void onResume() {
247 super.onResume();
248 registerReceiver(loginReceiver, LOGIN_FILTER);
249 LocalBroadcastManager.getInstance(this).registerReceiver(ongoingUpdateReceiver, ONGOING_UPDATE_FILTER);
250 bindService(new Intent(this, FonBotMainService.class), connection, 0);
251 }
252
253 @Override
254 protected void onPause() {
255 super.onPause();
256 unregisterReceiver(loginReceiver);
257 LocalBroadcastManager.getInstance(this).unregisterReceiver(ongoingUpdateReceiver);
258 unbindService(connection);
259 }
260
261 @Override
262 public boolean onCreateOptionsMenu(@Nullable final Menu menu) {
263 getMenuInflater().inflate(R.menu.main, menu);
264 return true;
265 }
266
267 @Override
268 public boolean onOptionsItemSelected(@Nullable final MenuItem item) {
269 if(item==null)
270 return super.onOptionsItemSelected(item);
271 switch(item.getItemId()){
272 case R.id.prefsItem:
273 startActivity(new Intent(this, FonBotPreferenceActivity.class));
274 return true;
275 case R.id.localItem:
276 startActivity(new Intent(this, FonBotLocalActivity.class));
277 return true;
278 case R.id.helpItem:
279 startActivity(new Intent(this, FonBotHelpActivity.class));
280 return true;
281 default:
282 return super.onOptionsItemSelected(item);
283 }
284 }
285 }
This page took 0.029341 seconds and 3 git commands to generate.