blob: 6a402e9c658683ae1e67579680a6e96d480906dc [file] [log] [blame]
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.businesscard;
import android.content.ContentResolver;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
/**
* This abstract class defines SDK-independent API for communication with
* Contacts Provider. The actual implementation used by the application depends
* on the level of API available on the device. If the API level is Cupcake or
* Donut, we want to use the {@link ContactAccessorSdk3_4} class. If it is
* Eclair or higher, we want to use {@link ContactAccessorSdk5}.
*/
public abstract class ContactAccessor {
/**
* Static singleton instance of {@link ContactAccessor} holding the
* SDK-specific implementation of the class.
*/
private static ContactAccessor sInstance;
public static ContactAccessor getInstance() {
if (sInstance == null) {
String className;
/*
* Check the version of the SDK we are running on. Choose an
* implementation class designed for that version of the SDK.
*
* Unfortunately we have to use strings to represent the class
* names. If we used the conventional ContactAccessorSdk5.class.getName()
* syntax, we would get a ClassNotFoundException at runtime on pre-Eclair SDKs.
* Using the above syntax would force Dalvik to load the class and try to
* resolve references to all other classes it uses. Since the pre-Eclair
* does not have those classes, the loading of ContactAccessorSdk5 would fail.
*/
@SuppressWarnings("deprecation")
int sdkVersion = Integer.parseInt(Build.VERSION.SDK); // Cupcake style
if (sdkVersion < Build.VERSION_CODES.ECLAIR) {
className = "com.example.android.businesscard.ContactAccessorSdk3_4";
} else {
className = "com.example.android.businesscard.ContactAccessorSdk5";
}
/*
* Find the required class by name and instantiate it.
*/
try {
Class<? extends ContactAccessor> clazz =
Class.forName(className).asSubclass(ContactAccessor.class);
sInstance = clazz.newInstance();
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
return sInstance;
}
/**
* Returns the {@link Intent#ACTION_PICK} intent configured for the right authority: legacy
* or current.
*/
public abstract Intent getPickContactIntent();
/**
* Loads contact data for the supplied URI. The actual queries will differ for different APIs
* used, but the result is the same: the {@link #mDisplayName} and {@link #mPhoneNumber}
* fields are populated with correct data.
*/
public abstract ContactInfo loadContact(ContentResolver contentResolver, Uri contactUri);
}