4
* Copyright (C) 2011 Tim Marston <tim@ed.am>
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
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.
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.
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/>.
24
package am.ed.exportcontacts;
26
import java.util.ArrayList;
28
import android.content.SharedPreferences;
29
import android.os.Message;
32
public class Exporter extends Thread
34
public final static int ACTION_ABORT = 1;
35
public final static int ACTION_ALLDONE = 2;
37
public final static int RESPONSE_NEGATIVE = 0;
38
public final static int RESPONSE_POSITIVE = 1;
40
public final static int RESPONSEEXTRA_NONE = 0;
41
public final static int RESPONSEEXTRA_ALWAYS = 1;
44
private int _response;
45
private boolean _abort = false;
46
private boolean _is_finished = false;
49
* Data about a contact
51
public class ContactData
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
60
class OrganisationDetail
62
protected String _org;
63
protected String _title;
65
public OrganisationDetail( String org, String title )
67
_org = org != null && org.length() > 0? org : null;
68
_title = title != null && title.length() > 0? title : null;
71
public String getOrganisation()
76
public String getTitle()
85
protected String _num;
87
public NumberDetail( int type, String num )
90
_num = num != null && num.length() > 0? num : null;
98
public String getNumber()
107
protected String _email;
109
public EmailDetail( int type, String email )
112
_email = email != null && email.length() > 0? email : null;
120
public String getEmail()
129
protected String _addr;
131
public AddressDetail( int type, String addr )
134
_addr = addr != null && addr.length() > 0? addr : null;
142
public String getAddress()
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;
155
public void setName( String name )
157
_name = name != null && name.length() > 0? name : null;
160
public String getName()
165
public void addOrganisation( OrganisationDetail organisation )
167
if( organisation.getOrganisation() == null ) return;
168
if( _organisations == null )
169
_organisations = new ArrayList< OrganisationDetail >();
170
_organisations.add( organisation );
173
public ArrayList< OrganisationDetail > getOrganisations()
175
return _organisations;
178
public void addNumber( NumberDetail number )
180
if( number.getNumber() == null ) return;
181
if( _numbers == null )
182
_numbers = new ArrayList< NumberDetail >();
183
_numbers.add( number );
186
public ArrayList< NumberDetail > getNumbers()
191
public void addEmail( EmailDetail email )
193
if( email.getEmail() == null ) return;
194
if( _emails == null )
195
_emails = new ArrayList< EmailDetail >();
196
_emails.add( email );
199
public ArrayList< EmailDetail > getEmails()
204
public void addAddress( AddressDetail address )
206
if( address.getAddress() == null ) return;
207
if( _addresses == null )
208
_addresses = new ArrayList< AddressDetail >();
209
_addresses.add( address );
212
public ArrayList< AddressDetail > getAddresses()
217
public void addNote( String note )
220
_notes = new ArrayList< String >();
224
public ArrayList< String > getNotes()
229
public String getPrimaryIdentifier()
234
if( _organisations != null &&
235
_organisations.get( 0 ).getOrganisation() != null )
236
return _organisations.get( 0 ).getOrganisation();
238
if( _numbers!= null &&
239
_numbers.get( 0 ).getNumber() != null )
240
return _numbers.get( 0 ).getNumber();
242
if( _emails!= null &&
243
_emails.get( 0 ).getEmail() != null )
244
return _emails.get( 0 ).getEmail();
246
// no primary identifier
251
@SuppressWarnings( "serial" )
252
protected class AbortExportException extends Exception { };
254
public Exporter( Doit doit )
265
setProgressMessage( R.string.doit_scanning );
271
finish( ACTION_ALLDONE );
273
catch( AbortExportException e )
276
// flag as finished to prevent interrupts
280
synchronized private void setIsFinished()
285
protected void exportContacts() throws AbortExportException
287
// set up a contact reader
288
Backend contact_reader = null;
289
if( Integer.parseInt( android.os.Build.VERSION.SDK ) >= 5 )
290
contact_reader = new ContactsContractBackend( _doit, this );
292
contact_reader = new ContactsBackend( _doit, this );
294
// check we have contacts
295
int num_contacts = contact_reader.getNumContacts();
296
if( num_contacts == 0 )
297
showError( R.string.error_nothingtodo );
299
// count the number of contacts and set the progress bar max
301
setProgressMax( num_contacts );
306
// loop through contacts
310
ContactData contact = new ContactData();
311
if( !contact_reader.getNextContact( contact ) )
316
if( exportContact( contact ) )
317
_doit._handler.sendEmptyMessage( Doit.MESSAGE_CONTACTWRITTEN );
319
_doit._handler.sendEmptyMessage( Doit.MESSAGE_CONTACTSKIPPED );
320
setProgress( count++ );
322
setProgress( num_contacts );
332
synchronized public void wake( int response )
334
_response = response;
338
synchronized public boolean setAbort()
340
if( !_is_finished && !_abort ) {
348
protected SharedPreferences getSharedPreferences()
350
return _doit.getSharedPreferences();
353
protected void showError( int res ) throws AbortExportException
355
showError( _doit.getText( res ).toString() );
358
synchronized protected void showError( String message )
359
throws AbortExportException
362
_doit._handler.sendMessage( Message.obtain(
363
_doit._handler, Doit.MESSAGE_ERROR, message ) );
367
catch( InterruptedException e ) { }
369
// no need to check if an abortion happened during the wait, we are
370
// about to finish anyway!
371
finish( ACTION_ABORT );
374
protected void showFatalError( int res ) throws AbortExportException
376
showFatalError( _doit.getText( res ).toString() );
379
synchronized protected void showFatalError( String message )
380
throws AbortExportException
383
_doit._handler.sendMessage( Message.obtain(
384
_doit._handler, Doit.MESSAGE_ERROR, message ) );
388
catch( InterruptedException e ) { }
390
// no need to check if an abortion happened during the wait, we are
391
// about to finish anyway!
392
finish( ACTION_ABORT );
395
protected boolean showContinue( int res ) throws AbortExportException
397
return showContinue( _doit.getText( res ).toString() );
400
synchronized protected boolean showContinue( String message )
401
throws AbortExportException
404
_doit._handler.sendMessage( Message.obtain(
405
_doit._handler, Doit.MESSAGE_CONTINUEORABORT, message ) );
409
catch( InterruptedException e ) { }
411
// check if an abortion happened during the wait
414
return _response == RESPONSE_POSITIVE;
417
protected void setProgressMessage( int res ) throws AbortExportException
420
_doit._handler.sendMessage( Message.obtain( _doit._handler,
421
Doit.MESSAGE_SETPROGRESSMESSAGE, getText( res ) ) );
424
protected void setProgressMax( int max_progress )
425
throws AbortExportException
428
_doit._handler.sendMessage( Message.obtain(
429
_doit._handler, Doit.MESSAGE_SETMAXPROGRESS,
430
new Integer( max_progress ) ) );
433
protected void setTmpProgress( int tmp_progress )
434
throws AbortExportException
437
_doit._handler.sendMessage( Message.obtain(
438
_doit._handler, Doit.MESSAGE_SETTMPPROGRESS,
439
new Integer( tmp_progress ) ) );
442
protected void setProgress( int progress ) throws AbortExportException
445
_doit._handler.sendMessage( Message.obtain(
446
_doit._handler, Doit.MESSAGE_SETPROGRESS,
447
new Integer( progress ) ) );
450
protected void finish( int action ) throws AbortExportException
452
// update UI to reflect action
456
case ACTION_ALLDONE: message = Doit.MESSAGE_ALLDONE; break;
457
default: // fall through
458
case ACTION_ABORT: message = Doit.MESSAGE_ABORT; break;
460
_doit._handler.sendEmptyMessage( message );
463
throw new AbortExportException();
466
protected CharSequence getText( int res )
468
return _doit.getText( res );
471
protected void skipContact() throws AbortExportException
474
_doit._handler.sendEmptyMessage( Doit.MESSAGE_CONTACTSKIPPED );
477
synchronized protected void checkAbort() throws AbortExportException
481
throw new AbortExportException();
485
protected void preExport() throws AbortExportException
489
protected boolean exportContact( ContactData contact )
490
throws AbortExportException
492
throw new UnsupportedOperationException();
495
protected void postExport() throws AbortExportException