import working
[adBlock.git] / src / de / ub0r / android / adBlock / AdBlock.java
blob8ad1025a1ff87b5be7fb9b2948dbc87e99cc11d1
1 package de.ub0r.android.adBlock;
3 import java.io.BufferedReader;
4 import java.io.BufferedWriter;
5 import java.io.File;
6 import java.io.FileOutputStream;
7 import java.io.IOException;
8 import java.io.InputStreamReader;
9 import java.io.OutputStream;
10 import java.io.OutputStreamWriter;
11 import java.net.HttpURLConnection;
12 import java.net.MalformedURLException;
13 import java.net.URL;
14 import java.util.ArrayList;
16 import android.app.Activity;
17 import android.app.AlertDialog;
18 import android.app.Dialog;
19 import android.content.DialogInterface;
20 import android.content.Intent;
21 import android.content.SharedPreferences;
22 import android.os.AsyncTask;
23 import android.os.Bundle;
24 import android.preference.PreferenceManager;
25 import android.view.Menu;
26 import android.view.MenuInflater;
27 import android.view.MenuItem;
28 import android.view.View;
29 import android.view.View.OnClickListener;
30 import android.widget.AdapterView;
31 import android.widget.ArrayAdapter;
32 import android.widget.Button;
33 import android.widget.EditText;
34 import android.widget.ListView;
35 import android.widget.Toast;
36 import android.widget.AdapterView.OnItemClickListener;
38 /**
39 * Main Activity to controle ad blocking proxy.
41 * @author flx
43 public class AdBlock extends Activity implements OnClickListener,
44 OnItemClickListener {
46 /** Preferences: Port. */
47 static final String PREFS_PORT = "port";
48 /** Preferences: Filter. */
49 static final String PREFS_FILTER = "filter";
50 /** Preferences: import url. */
51 private static final String PREFS_IMPORT_URL = "importurl";
53 /** Filename for export of filter. */
54 private static final String FILENAME_EXPORT = "/sdcard/filter.txt";
56 /** ItemDialog: edit. */
57 private static final short ITEM_DIALOG_EDIT = 0;
58 /** ItemDialog: delete. */
59 private static final short ITEM_DIALOG_DELETE = 1;
61 /** Dialog: about. */
62 private static final int DIALOG_ABOUT = 0;
63 /** Dialog: import. */
64 private static final int DIALOG_IMPORT = 1;
66 /** Prefs. */
67 private SharedPreferences preferences;
68 /** Prefs. import URL. */
69 private String importUrl = null;
71 /** The filter. */
72 private ArrayList<String> filter = new ArrayList<String>();
73 /** The ArrayAdapter. */
74 private ArrayAdapter<String> adapter = null;
76 /** Editmode? */
77 private int itemToEdit = -1;
79 private class Importer extends AsyncTask<String, Boolean, Boolean> {
80 private String message = "";
82 @Override
83 protected final Boolean doInBackground(final String... dummy) {
84 try {
85 HttpURLConnection c = (HttpURLConnection) (new URL(
86 AdBlock.this.importUrl)).openConnection();
87 int resp = c.getResponseCode();
88 if (resp != 200) {
89 return false;
91 BufferedReader reader = new BufferedReader(
92 new InputStreamReader(c.getInputStream()));
93 AdBlock.this.filter.clear();
94 while (true) {
95 String s = reader.readLine();
96 if (s == null) {
97 break;
98 } else if (s.length() > 0) {
99 AdBlock.this.filter.add(s);
102 reader.close();
103 return true;
104 } catch (MalformedURLException e) {
105 e.printStackTrace();
106 this.message = e.toString();
107 return false;
108 } catch (IOException e) {
109 this.message = e.toString();
110 e.printStackTrace();
111 return false;
115 @Override
116 protected final void onPostExecute(final Boolean result) {
117 if (result.booleanValue()) {
118 Toast.makeText(AdBlock.this, "imported", Toast.LENGTH_LONG)
119 .show();
120 AdBlock.this.adapter.notifyDataSetChanged();
121 } else {
122 Toast.makeText(AdBlock.this, "failed: " + this.message,
123 Toast.LENGTH_LONG).show();
129 * Called when the activity is first created.
131 * @param savedInstanceState
132 * saved InstanceState
134 @Override
135 public final void onCreate(final Bundle savedInstanceState) {
136 super.onCreate(savedInstanceState);
137 this.setContentView(R.layout.main);
139 this.preferences = PreferenceManager.getDefaultSharedPreferences(this);
140 ((EditText) this.findViewById(R.id.port)).setText(this.preferences
141 .getString(PREFS_PORT, "8080"));
142 String f = this.preferences.getString(PREFS_FILTER, "");
143 for (String s : f.split("\n")) {
144 if (s.length() > 0) {
145 this.filter.add(s);
148 this.importUrl = this.preferences.getString(PREFS_IMPORT_URL, "");
150 ((Button) this.findViewById(R.id.start_service))
151 .setOnClickListener(this);
152 ((Button) this.findViewById(R.id.stop_service))
153 .setOnClickListener(this);
154 ((Button) this.findViewById(R.id.filter_add_)).setOnClickListener(this);
155 ListView lv = (ListView) this.findViewById(R.id.filter);
156 this.adapter = new ArrayAdapter<String>(this,
157 R.layout.simple_list_item_1, this.filter);
158 lv.setAdapter(this.adapter);
159 lv.setTextFilterEnabled(true);
160 lv.setOnItemClickListener(this);
163 /** Save Preferences. */
164 private void savePreferences() {
165 SharedPreferences.Editor editor = this.preferences.edit();
166 editor.putString(PREFS_PORT, ((EditText) this.findViewById(R.id.port))
167 .getText().toString());
168 StringBuilder sb = new StringBuilder();
169 for (String s : this.filter) {
170 if (s.indexOf("admob") < 0) { // won't block admob
171 sb.append(s + "\n");
174 editor.putString(PREFS_FILTER, sb.toString());
175 editor.putString(PREFS_IMPORT_URL, this.importUrl);
176 editor.commit();
179 /** Called on pause. */
180 @Override
181 public final void onPause() {
182 super.onPause();
183 this.savePreferences();
187 * OnClickListener.
189 * @param v
190 * view
192 @Override
193 public final void onClick(final View v) {
194 switch (v.getId()) {
195 case R.id.start_service:
196 this.savePreferences();
197 this.startService(new Intent(this, Proxy.class));
198 break;
199 case R.id.stop_service:
200 this.stopService(new Intent(this, Proxy.class));
201 case R.id.filter_add_:
202 EditText et = (EditText) this.findViewById(R.id.filter_add);
203 String f = et.getText().toString();
204 if (f.length() > 0) {
205 if (this.itemToEdit >= 0) {
206 this.filter.remove(this.itemToEdit);
207 this.itemToEdit = -1;
209 this.filter.add(f);
210 et.setText("");
211 this.adapter.notifyDataSetChanged();
213 break;
214 case R.id.cancel:
215 this.dismissDialog(DIALOG_IMPORT);
216 break;
217 case R.id.ok:
218 this.dismissDialog(DIALOG_IMPORT);
219 this.importUrl = ((EditText) v.getRootView().findViewById(
220 R.id.import_url)).getText().toString();
221 new Importer().execute((String[]) null);
222 break;
223 default:
224 break;
229 * Create menu.
231 * @param menu
232 * menu to inflate
233 * @return ok/fail?
235 @Override
236 public final boolean onCreateOptionsMenu(final Menu menu) {
237 MenuInflater inflater = this.getMenuInflater();
238 inflater.inflate(R.menu.menu, menu);
239 return true;
243 * Handles item selections.
245 * @param item
246 * menu item
247 * @return done?
249 public final boolean onOptionsItemSelected(final MenuItem item) {
250 switch (item.getItemId()) {
251 case R.id.item_about: // start about dialog
252 this.showDialog(DIALOG_ABOUT);
253 return true;
254 case R.id.item_import:
255 this.showDialog(DIALOG_IMPORT);
256 return true;
257 case R.id.item_export:
258 try {
259 // OutputStream os = this.openFileOutput(FILENAME_EXPORT,
260 // MODE_WORLD_READABLE);
261 File file = new File(FILENAME_EXPORT);
262 if (!file.createNewFile()) {
263 file.delete();
264 file.createNewFile();
266 OutputStream os = new FileOutputStream(file);
267 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
268 os));
269 for (String s : this.filter) {
270 if (s.indexOf("admob") < 0) { // won't block admob
271 bw.append(s + "\n");
274 bw.close();
275 os.close();
276 Toast.makeText(this, "exported to " + FILENAME_EXPORT,
277 Toast.LENGTH_LONG).show();
278 } catch (IOException e) {
279 e.printStackTrace();
280 Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();
282 return true;
283 default:
284 return false;
289 * Called to create dialog.
291 * @param id
292 * Dialog id
293 * @return dialog
295 @Override
296 protected final Dialog onCreateDialog(final int id) {
297 Dialog myDialog;
298 switch (id) {
299 case DIALOG_ABOUT:
300 myDialog = new Dialog(this);
301 myDialog.setContentView(R.layout.about);
302 myDialog.setTitle(this.getResources().getString(R.string.about_)
303 + " v"
304 + this.getResources().getString(R.string.app_version));
305 // ((Button) myDialog.findViewById(R.id.btn_donate))
306 // .setOnClickListener(this);
307 break;
308 case DIALOG_IMPORT:
309 myDialog = new Dialog(this);
310 myDialog.setContentView(R.layout.import_url);
311 myDialog.setTitle(this.getResources().getString(
312 R.string.import_url_));
313 ((EditText) myDialog.findViewById(R.id.import_url))
314 .setText(this.importUrl);
315 ((Button) myDialog.findViewById(R.id.ok)).setOnClickListener(this);
316 ((Button) myDialog.findViewById(R.id.cancel))
317 .setOnClickListener(this);
318 break;
319 default:
320 myDialog = null;
322 return myDialog;
326 * Handle clicked ListItem.
328 * @param parent
329 * parent AdapterView
330 * @param v
331 * View
332 * @param position
333 * Position
334 * @param id
335 * id
337 @Override
338 public final void onItemClick(final AdapterView<?> parent, final View v,
339 final int position, final long id) {
341 AlertDialog.Builder builder = new AlertDialog.Builder(this);
342 builder.setItems(
343 this.getResources().getStringArray(R.array.itemDialog),
344 new DialogInterface.OnClickListener() {
345 public void onClick(final DialogInterface dialog,
346 final int item) {
347 switch (item) {
348 case ITEM_DIALOG_EDIT:
349 AdBlock.this.itemToEdit = position;
350 ((EditText) AdBlock.this
351 .findViewById(R.id.filter_add))
352 .setText(AdBlock.this.adapter
353 .getItem(position));
354 break;
355 case ITEM_DIALOG_DELETE:
356 AdBlock.this.filter.remove(position);
357 AdBlock.this.adapter.notifyDataSetChanged();
358 break;
359 default:
360 break;
364 AlertDialog alert = builder.create();
365 alert.show();