/android/export-contacts

To get this branch, use:
bzr branch http://bzr.ed.am/android/export-contacts

« back to all changes in this revision

Viewing changes to src/am/ed/exportcontacts/Exporter.java

  • Committer: edam
  • Date: 2010-07-04 14:54:18 UTC
  • Revision ID: edam@waxworlds.org-20100704145418-vcpya2sxsop0dlrq
- initial checkin
- copied intro and basic vcf-configure activities from import-contacts
- copied WizzardActivity class from import-contacts

Show diffs side-by-side

added added

removed removed

1
 
/*
2
 
 * Exporter.java
3
 
 *
4
 
 * Copyright (C) 2011 Tim Marston <tim@ed.am>
5
 
 *
6
 
 * This file is part of the Export Contacts program (hereafter referred
7
 
 * to as "this program"). For more information, see
8
 
 * http://ed.am/dev/android/export-contacts
9
 
 *
10
 
 * This program is free software: you can redistribute it and/or modify
11
 
 * it under the terms of the GNU General Public License as published by
12
 
 * the Free Software Foundation, either version 3 of the License, or
13
 
 * (at your option) any later version.
14
 
 *
15
 
 * This program is distributed in the hope that it will be useful,
16
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 
 * GNU General Public License for more details.
19
 
 *
20
 
 * You should have received a copy of the GNU General Public License
21
 
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 
 */
23
 
 
24
 
package am.ed.exportcontacts;
25
 
 
26
 
import java.util.ArrayList;
27
 
 
28
 
import android.content.SharedPreferences;
29
 
import android.os.Message;
30
 
 
31
 
 
32
 
public class Exporter extends Thread
33
 
{
34
 
        public final static int ACTION_ABORT = 1;
35
 
        public final static int ACTION_ALLDONE = 2;
36
 
 
37
 
        public final static int RESPONSE_NEGATIVE = 0;
38
 
        public final static int RESPONSE_POSITIVE = 1;
39
 
 
40
 
        public final static int RESPONSEEXTRA_NONE = 0;
41
 
        public final static int RESPONSEEXTRA_ALWAYS = 1;
42
 
 
43
 
        private Doit _doit;
44
 
        private int _response;
45
 
        private boolean _abort = false;
46
 
        private boolean _is_finished = false;
47
 
 
48
 
        /**
49
 
         * Data about a contact
50
 
         */
51
 
        public class ContactData
52
 
        {
53
 
                public final static int TYPE_HOME = 0;
54
 
                public final static int TYPE_WORK = 1;
55
 
                public final static int TYPE_MOBILE = 2;        // only used with phones
56
 
                public final static int TYPE_FAX_HOME = 3;      // only used with phones
57
 
                public final static int TYPE_FAX_WORK = 4;      // only used with phones
58
 
                public final static int TYPE_PAGER = 5;         // only used with phones
59
 
 
60
 
                class OrganisationDetail
61
 
                {
62
 
                        protected String _org;
63
 
                        protected String _title;
64
 
 
65
 
                        public OrganisationDetail( String org, String title )
66
 
                        {
67
 
                                _org = org != null && org.length() > 0? org : null;
68
 
                                _title = title != null && title.length() > 0? title : null;
69
 
                        }
70
 
 
71
 
                        public String getOrganisation()
72
 
                        {
73
 
                                return _org;
74
 
                        }
75
 
 
76
 
                        public String getTitle()
77
 
                        {
78
 
                                return _title;
79
 
                        }
80
 
                }
81
 
 
82
 
                class NumberDetail
83
 
                {
84
 
                        protected int _type;
85
 
                        protected String _num;
86
 
 
87
 
                        public NumberDetail( int type, String num )
88
 
                        {
89
 
                                _type = type;
90
 
                                _num = num != null && num.length() > 0? num : null;
91
 
                        }
92
 
 
93
 
                        public int getType()
94
 
                        {
95
 
                                return _type;
96
 
                        }
97
 
 
98
 
                        public String getNumber()
99
 
                        {
100
 
                                return _num;
101
 
                        }
102
 
                }
103
 
 
104
 
                class EmailDetail
105
 
                {
106
 
                        protected int _type;
107
 
                        protected String _email;
108
 
 
109
 
                        public EmailDetail( int type, String email )
110
 
                        {
111
 
                                _type = type;
112
 
                                _email = email != null && email.length() > 0? email : null;
113
 
                        }
114
 
 
115
 
                        public int getType()
116
 
                        {
117
 
                                return _type;
118
 
                        }
119
 
 
120
 
                        public String getEmail()
121
 
                        {
122
 
                                return _email;
123
 
                        }
124
 
                }
125
 
 
126
 
                class AddressDetail
127
 
                {
128
 
                        protected int _type;
129
 
                        protected String _addr;
130
 
 
131
 
                        public AddressDetail( int type, String addr )
132
 
                        {
133
 
                                _type = type;
134
 
                                _addr = addr != null && addr.length() > 0? addr : null;
135
 
                        }
136
 
 
137
 
                        public int getType()
138
 
                        {
139
 
                                return _type;
140
 
                        }
141
 
 
142
 
                        public String getAddress()
143
 
                        {
144
 
                                return _addr;
145
 
                        }
146
 
                }
147
 
 
148
 
                protected String _name = null;
149
 
                protected ArrayList< OrganisationDetail > _organisations = null;
150
 
                protected ArrayList< NumberDetail > _numbers = null;
151
 
                protected ArrayList< EmailDetail > _emails = null;
152
 
                protected ArrayList< AddressDetail > _addresses = null;
153
 
                protected ArrayList< String > _notes = null;
154
 
 
155
 
                public void setName( String name )
156
 
                {
157
 
                        _name = name != null && name.length() > 0? name : null;
158
 
                }
159
 
 
160
 
                public String getName()
161
 
                {
162
 
                        return _name;
163
 
                }
164
 
 
165
 
                public void addOrganisation( OrganisationDetail organisation )
166
 
                {
167
 
                        if( organisation.getOrganisation() == null ) return;
168
 
                        if( _organisations == null )
169
 
                                _organisations = new ArrayList< OrganisationDetail >();
170
 
                        _organisations.add( organisation );
171
 
                }
172
 
 
173
 
                public ArrayList< OrganisationDetail > getOrganisations()
174
 
                {
175
 
                        return _organisations;
176
 
                }
177
 
 
178
 
                public void addNumber( NumberDetail number )
179
 
                {
180
 
                        if( number.getNumber() == null ) return;
181
 
                        if( _numbers == null )
182
 
                                _numbers = new ArrayList< NumberDetail >();
183
 
                        _numbers.add( number );
184
 
                }
185
 
 
186
 
                public ArrayList< NumberDetail > getNumbers()
187
 
                {
188
 
                        return _numbers;
189
 
                }
190
 
 
191
 
                public void addEmail( EmailDetail email )
192
 
                {
193
 
                        if( email.getEmail() == null ) return;
194
 
                        if( _emails == null )
195
 
                                _emails = new ArrayList< EmailDetail >();
196
 
                        _emails.add( email );
197
 
                }
198
 
 
199
 
                public ArrayList< EmailDetail > getEmails()
200
 
                {
201
 
                        return _emails;
202
 
                }
203
 
 
204
 
                public void addAddress( AddressDetail address )
205
 
                {
206
 
                        if( address.getAddress() == null ) return;
207
 
                        if( _addresses == null )
208
 
                                _addresses = new ArrayList< AddressDetail >();
209
 
                        _addresses.add( address );
210
 
                }
211
 
 
212
 
                public ArrayList< AddressDetail > getAddresses()
213
 
                {
214
 
                        return _addresses;
215
 
                }
216
 
 
217
 
                public void addNote( String note )
218
 
                {
219
 
                        if( _notes == null )
220
 
                                _notes = new ArrayList< String >();
221
 
                        _notes.add( note );
222
 
                }
223
 
 
224
 
                public ArrayList< String > getNotes()
225
 
                {
226
 
                        return _notes;
227
 
                }
228
 
 
229
 
                public String getPrimaryIdentifier()
230
 
                {
231
 
                        if( _name != null )
232
 
                                return _name;
233
 
 
234
 
                        if( _organisations != null &&
235
 
                                _organisations.get( 0 ).getOrganisation() != null )
236
 
                                return _organisations.get( 0 ).getOrganisation();
237
 
 
238
 
                        if( _numbers!= null &&
239
 
                                _numbers.get( 0 ).getNumber() != null )
240
 
                                return _numbers.get( 0 ).getNumber();
241
 
 
242
 
                        if( _emails!= null &&
243
 
                                _emails.get( 0 ).getEmail() != null )
244
 
                                return _emails.get( 0 ).getEmail();
245
 
 
246
 
                        // no primary identifier
247
 
                        return null;
248
 
                }
249
 
        }
250
 
 
251
 
        @SuppressWarnings( "serial" )
252
 
        protected class AbortExportException extends Exception { };
253
 
 
254
 
        public Exporter( Doit doit )
255
 
        {
256
 
                _doit = doit;
257
 
        }
258
 
 
259
 
        @Override
260
 
        public void run()
261
 
        {
262
 
                try
263
 
                {
264
 
                        // update UI
265
 
                        setProgressMessage( R.string.doit_scanning );
266
 
 
267
 
                        // do the export
268
 
                        exportContacts();
269
 
 
270
 
                        // done!
271
 
                        finish( ACTION_ALLDONE );
272
 
                }
273
 
                catch( AbortExportException e )
274
 
                {}
275
 
 
276
 
                // flag as finished to prevent interrupts
277
 
                setIsFinished();
278
 
        }
279
 
 
280
 
        synchronized private void setIsFinished()
281
 
        {
282
 
                _is_finished = true;
283
 
        }
284
 
 
285
 
        protected void exportContacts() throws AbortExportException
286
 
        {
287
 
                // set up a contact reader
288
 
                Backend backend = null;
289
 
                if( Integer.parseInt( android.os.Build.VERSION.SDK ) >= 5 )
290
 
                        backend = new ContactsContractBackend( _doit, this );
291
 
                else
292
 
                        backend = new ContactsBackend( _doit, this );
293
 
 
294
 
                // check we have contacts
295
 
                int num_contacts = backend.getNumContacts();
296
 
                if( num_contacts == 0 )
297
 
                        showError( R.string.error_nothingtodo );
298
 
 
299
 
                // count the number of contacts and set the progress bar max
300
 
                setProgress( 0 );
301
 
                setProgressMax( num_contacts );
302
 
 
303
 
                checkAbort();
304
 
                preExport();
305
 
 
306
 
                // loop through contacts
307
 
                int count = 0;
308
 
                while( true ) {
309
 
                        checkAbort();
310
 
                        ContactData contact = new ContactData();
311
 
                        if( !backend.getNextContact( contact ) )
312
 
                                break;
313
 
 
314
 
                        // export this one
315
 
                        checkAbort();
316
 
                        if( exportContact( contact ) )
317
 
                                _doit._handler.sendEmptyMessage( Doit.MESSAGE_CONTACTWRITTEN );
318
 
                        else
319
 
                                _doit._handler.sendEmptyMessage( Doit.MESSAGE_CONTACTSKIPPED );
320
 
                        setProgress( count++ );
321
 
                }
322
 
                setProgress( num_contacts );
323
 
 
324
 
                postExport();
325
 
        }
326
 
 
327
 
        public void wake()
328
 
        {
329
 
                wake( 0 );
330
 
        }
331
 
 
332
 
        synchronized public void wake( int response )
333
 
        {
334
 
                _response = response;
335
 
                notify();
336
 
        }
337
 
 
338
 
        synchronized public boolean setAbort()
339
 
        {
340
 
                if( !_is_finished && !_abort ) {
341
 
                        _abort = true;
342
 
                        notify();
343
 
                        return true;
344
 
                }
345
 
                return false;
346
 
        }
347
 
 
348
 
        protected SharedPreferences getSharedPreferences()
349
 
        {
350
 
                return _doit.getSharedPreferences();
351
 
        }
352
 
 
353
 
        protected void showError( int res ) throws AbortExportException
354
 
        {
355
 
                showError( _doit.getText( res ).toString() );
356
 
        }
357
 
 
358
 
        synchronized protected void showError( String message )
359
 
                        throws AbortExportException
360
 
        {
361
 
                checkAbort();
362
 
                _doit._handler.sendMessage( Message.obtain(
363
 
                        _doit._handler, Doit.MESSAGE_ERROR, message ) );
364
 
                try {
365
 
                        wait();
366
 
                }
367
 
                catch( InterruptedException e ) { }
368
 
 
369
 
                // no need to check if an abortion happened during the wait, we are
370
 
                // about to finish anyway!
371
 
                finish( ACTION_ABORT );
372
 
        }
373
 
 
374
 
        protected void showFatalError( int res ) throws AbortExportException
375
 
        {
376
 
                showFatalError( _doit.getText( res ).toString() );
377
 
        }
378
 
 
379
 
        synchronized protected void showFatalError( String message )
380
 
                        throws AbortExportException
381
 
        {
382
 
                checkAbort();
383
 
                _doit._handler.sendMessage( Message.obtain(
384
 
                        _doit._handler, Doit.MESSAGE_ERROR, message ) );
385
 
                try {
386
 
                        wait();
387
 
                }
388
 
                catch( InterruptedException e ) { }
389
 
 
390
 
                // no need to check if an abortion happened during the wait, we are
391
 
                // about to finish anyway!
392
 
                finish( ACTION_ABORT );
393
 
        }
394
 
 
395
 
        protected boolean showContinue( int res ) throws AbortExportException
396
 
        {
397
 
                return showContinue( _doit.getText( res ).toString() );
398
 
        }
399
 
 
400
 
        synchronized protected boolean showContinue( String message )
401
 
                        throws AbortExportException
402
 
        {
403
 
                checkAbort();
404
 
                _doit._handler.sendMessage( Message.obtain(
405
 
                        _doit._handler, Doit.MESSAGE_CONTINUEORABORT, message ) );
406
 
                try {
407
 
                        wait();
408
 
                }
409
 
                catch( InterruptedException e ) { }
410
 
 
411
 
                // check if an abortion happened during the wait
412
 
                checkAbort();
413
 
 
414
 
                return _response == RESPONSE_POSITIVE;
415
 
        }
416
 
 
417
 
        protected void setProgressMessage( int res ) throws AbortExportException
418
 
        {
419
 
                checkAbort();
420
 
                _doit._handler.sendMessage( Message.obtain( _doit._handler,
421
 
                        Doit.MESSAGE_SETPROGRESSMESSAGE, getText( res ) ) );
422
 
        }
423
 
 
424
 
        protected void setProgressMax( int max_progress )
425
 
                        throws AbortExportException
426
 
        {
427
 
                checkAbort();
428
 
                _doit._handler.sendMessage( Message.obtain(
429
 
                        _doit._handler, Doit.MESSAGE_SETMAXPROGRESS,
430
 
                        Integer.valueOf( max_progress ) ) );
431
 
        }
432
 
 
433
 
        protected void setTmpProgress( int tmp_progress )
434
 
                throws AbortExportException
435
 
        {
436
 
                checkAbort();
437
 
                _doit._handler.sendMessage( Message.obtain(
438
 
                        _doit._handler, Doit.MESSAGE_SETTMPPROGRESS,
439
 
                        Integer.valueOf( tmp_progress ) ) );
440
 
        }
441
 
 
442
 
        protected void setProgress( int progress ) throws AbortExportException
443
 
        {
444
 
                checkAbort();
445
 
                _doit._handler.sendMessage( Message.obtain(
446
 
                        _doit._handler, Doit.MESSAGE_SETPROGRESS,
447
 
                        Integer.valueOf( progress ) ) );
448
 
        }
449
 
 
450
 
        protected void finish( int action ) throws AbortExportException
451
 
        {
452
 
                // update UI to reflect action
453
 
                int message;
454
 
                switch( action )
455
 
                {
456
 
                case ACTION_ALLDONE:    message = Doit.MESSAGE_ALLDONE; break;
457
 
                default:        // fall through
458
 
                case ACTION_ABORT:              message = Doit.MESSAGE_ABORT; break;
459
 
                }
460
 
                _doit._handler.sendEmptyMessage( message );
461
 
 
462
 
                // stop
463
 
                throw new AbortExportException();
464
 
        }
465
 
 
466
 
        protected CharSequence getText( int res )
467
 
        {
468
 
                return _doit.getText( res );
469
 
        }
470
 
 
471
 
        protected void skipContact() throws AbortExportException
472
 
        {
473
 
                checkAbort();
474
 
                _doit._handler.sendEmptyMessage( Doit.MESSAGE_CONTACTSKIPPED );
475
 
        }
476
 
 
477
 
        synchronized protected void checkAbort() throws AbortExportException
478
 
        {
479
 
                if( _abort ) {
480
 
                        // stop
481
 
                        throw new AbortExportException();
482
 
                }
483
 
        }
484
 
 
485
 
        protected void preExport() throws AbortExportException
486
 
        {
487
 
        }
488
 
 
489
 
        protected boolean exportContact( ContactData contact )
490
 
                throws AbortExportException
491
 
        {
492
 
                throw new UnsupportedOperationException();
493
 
        }
494
 
 
495
 
        protected void postExport() throws AbortExportException
496
 
        {
497
 
        }
498
 
 
499
 
}