Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
API de calendário
Um novo conjunto de APIs de calendário introduzido no Android 4 oferece suporte a aplicativos projetados para ler ou gravar dados no provedor de calendário. Essas APIs oferecem suporte a uma variedade de opções de interação com dados de calendário, incluindo a capacidade de ler e gravar eventos, participantes e lembretes. Usando o provedor de calendário em seu aplicativo, os dados adicionados por meio da API aparecerão no aplicativo de calendário interno que vem com o Android 4.
Adicionando permissões
Ao trabalhar com as novas APIs de calendário em seu aplicativo, a primeira coisa que você precisa fazer é adicionar as permissões apropriadas ao manifesto do Android. As permissões que você precisa adicionar são android.permisson.READ_CALENDAR e android.permission.WRITE_CALENDAR, dependendo se você estiver lendo e/ou gravando dados de calendário.
Usando o contrato de calendário
Depois de definir as permissões, você pode interagir com os dados do calendário usando a CalendarContract classe. Essa classe fornece um modelo de dados que os aplicativos podem usar quando interagem com o provedor de calendário. O CalendarContract permite que os aplicativos resolvam o Uris para entidades de calendário, como calendários e eventos. Ele também fornece uma maneira de interagir com vários campos em cada entidade, como o nome e a ID de um calendário ou a data de início e término de um evento.
Vejamos um exemplo que usa a API do Calendário. Neste exemplo, examinaremos como enumerar calendários e seus eventos, bem como adicionar um novo evento a um calendário.
Listando calendários
Primeiro, vamos examinar como enumerar os calendários que foram registrados no aplicativo de calendário. Para fazer isso, podemos instanciar um CursorLoaderarquivo . Introduzido no Android 3.0 (API 11), CursorLoader é a maneira preferida de consumir um ContentProviderarquivo . No mínimo, precisaremos especificar o Uri de conteúdo para calendários e as colunas que queremos retornar; Essa especificação de coluna é conhecida como projeção.
Chamar o CursorLoader.LoadInBackground método nos permite consultar um provedor de conteúdo para obter dados, como o provedor de calendário.
LoadInBackground Executa a operação de carregamento real e retorna um Cursor com os resultados da consulta.
O CalendarContract nos auxilia na especificação tanto do conteúdo Uri quanto da projeção. Para obter o conteúdo Uri para consultar calendários, podemos simplesmente usar a CalendarContract.Calendars.ContentUri propriedade assim:
var calendarsUri = CalendarContract.Calendars.ContentUri;
Usar o para especificar quais colunas de CalendarContract calendário queremos é igualmente simples. Apenas adicionamos campos na CalendarContract.Calendars.InterfaceConsts classe a uma matriz. Por exemplo, o código a seguir inclui a ID do calendário, o nome para exibição e o nome da conta:
string[] calendarsProjection = {
CalendarContract.Calendars.InterfaceConsts.Id,
CalendarContract.Calendars.InterfaceConsts.CalendarDisplayName,
CalendarContract.Calendars.InterfaceConsts.AccountName
};
O Id é importante incluir se você estiver usando um SimpleCursorAdapter para vincular os dados à interface do usuário, como veremos em breve. Com o Uri de conteúdo e a projeção no lugar, instanciamos o CursorLoader método e chamamos para CursorLoader.LoadInBackground retornar um cursor com os dados do calendário, conforme mostrado abaixo:
var loader = new CursorLoader(this, calendarsUri, calendarsProjection, null, null, null);
var cursor = (ICursor)loader.LoadInBackground();
A interface do usuário deste exemplo contém um ListView, com cada item na lista representando um único calendário. O XML a seguir mostra a marcação que inclui o ListView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="@android:id/android:list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Além disso, precisamos especificar a interface do usuário para cada item de lista, que colocamos em um arquivo XML separado da seguinte maneira:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/calDisplayName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16dip" />
<TextView android:id="@+id/calAccountName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12dip" />
</LinearLayout>
A partir deste ponto, é apenas código normal do Android vincular os dados do cursor à interface do usuário. Usaremos um SimpleCursorAdapter da seguinte maneira:
string[] sourceColumns = {
CalendarContract.Calendars.InterfaceConsts.CalendarDisplayName,
CalendarContract.Calendars.InterfaceConsts.AccountName };
int[] targetResources = {
Resource.Id.calDisplayName, Resource.Id.calAccountName };
SimpleCursorAdapter adapter = new SimpleCursorAdapter (this,
Resource.Layout.CalListItem, cursor, sourceColumns, targetResources);
ListAdapter = adapter;
No código acima, o adaptador pega sourceColumns as colunas especificadas na matriz e as grava nos elementos da interface do usuário na targetResources matriz para cada entrada de calendário no cursor. A Atividade usada aqui é uma subclasse de ListActivity, ela inclui a propriedade para a ListAdapter qual definimos o adaptador.
Aqui está uma captura de tela mostrando o resultado final, com as informações do calendário exibidas no ListView:
Listando eventos do calendário
Em seguida, veremos como enumerar os eventos de um determinado calendário. Com base no exemplo acima, apresentaremos uma lista de eventos quando o usuário selecionar um dos calendários. Portanto, precisaremos manipular a seleção de itens no código anterior:
ListView.ItemClick += (sender, e) => {
int i = (e as ItemEventArgs).Position;
cursor.MoveToPosition(i);
int calId =
cursor.GetInt (cursor.GetColumnIndex (calendarsProjection [0]));
var showEvents = new Intent(this, typeof(EventListActivity));
showEvents.PutExtra("calId", calId);
StartActivity(showEvents);
};
Neste código, estamos criando uma Intenção para abrir uma Atividade do tipo EventListActivity, passando a ID do calendário na Intenção. Precisaremos do ID para saber qual calendário consultar para eventos. EventListActivityNo método 'sOnCreate, podemos recuperar o Intent ID do como mostrado abaixo:
_calId = Intent.GetIntExtra ("calId", -1);
Agora vamos consultar eventos para essa ID de calendário. O processo para consultar eventos é semelhante à maneira como consultamos uma lista de calendários anteriormente, só que desta vez trabalharemos com a CalendarContract.Events classe. O código a seguir cria uma consulta para recuperar eventos:
var eventsUri = CalendarContract.Events.ContentUri;
string[] eventsProjection = {
CalendarContract.Events.InterfaceConsts.Id,
CalendarContract.Events.InterfaceConsts.Title,
CalendarContract.Events.InterfaceConsts.Dtstart
};
var loader = new CursorLoader(this, eventsUri, eventsProjection,
String.Format ("calendar_id={0}", _calId), null, "dtstart ASC");
var cursor = (ICursor)loader.LoadInBackground();
Neste código, primeiro obtemos o conteúdo Uri para eventos da CalendarContract.Events.ContentUri propriedade. Em seguida, especificamos as colunas de eventos que queremos recuperar na matriz eventsProjection.
Finalmente, instanciamos um CursorLoader com essas informações e chamamos o método do carregador LoadInBackground para retornar um Cursor com os dados do evento.
Para exibir os dados do evento na interface do usuário, podemos usar marcação e código como fizemos antes para exibir a lista de calendários. Novamente, usamos SimpleCursorAdapter para vincular os dados a um ListView conforme mostrado no código a seguir:
string[] sourceColumns = {
CalendarContract.Events.InterfaceConsts.Title,
CalendarContract.Events.InterfaceConsts.Dtstart };
int[] targetResources = {
Resource.Id.eventTitle,
Resource.Id.eventStartDate };
var adapter = new SimpleCursorAdapter (this, Resource.Layout.EventListItem,
cursor, sourceColumns, targetResources);
adapter.ViewBinder = new ViewBinder ();
ListAdapter = adapter;
A principal diferença entre esse código e o código que usamos anteriormente para mostrar a lista de calendário é o uso de um ViewBinder, que é definido na linha:
adapter.ViewBinder = new ViewBinder ();
A ViewBinder classe nos permite controlar ainda mais como vinculamos valores a modos de exibição. Nesse caso, nós o usamos para converter a hora de início do evento de milissegundos em uma cadeia de caracteres de data, conforme mostrado na implementação a seguir:
class ViewBinder : Java.Lang.Object, SimpleCursorAdapter.IViewBinder
{
public bool SetViewValue (View view, Android.Database.ICursor cursor,
int columnIndex)
{
if (columnIndex == 2) {
long ms = cursor.GetLong (columnIndex);
DateTime date = new DateTime (1970, 1, 1, 0, 0, 0,
DateTimeKind.Utc).AddMilliseconds (ms).ToLocalTime ();
TextView textView = (TextView)view;
textView.Text = date.ToLongDateString ();
return true;
}
return false;
}
}
Isso exibe uma lista de eventos, conforme mostrado abaixo:
Adicionando um evento do calendário
Vimos como ler dados de calendário. Agora vamos ver como adicionar um evento a um calendário. Para que isso funcione, certifique-se de incluir a android.permission.WRITE_CALENDAR permissão que mencionamos anteriormente. Para adicionar um evento a um calendário, iremos:
- Crie uma instância de
ContentValues. - Use chaves da
CalendarContract.Events.InterfaceConstsclasse para preencher aContentValuesinstância. - Defina os fusos horários para as horas de início e término do evento.
- Use um
ContentResolverpara inserir os dados do evento no calendário.
O código abaixo ilustra essas etapas:
ContentValues eventValues = new ContentValues ();
eventValues.Put (CalendarContract.Events.InterfaceConsts.CalendarId,
_calId);
eventValues.Put (CalendarContract.Events.InterfaceConsts.Title,
"Test Event from M4A");
eventValues.Put (CalendarContract.Events.InterfaceConsts.Description,
"This is an event created from Xamarin.Android");
eventValues.Put (CalendarContract.Events.InterfaceConsts.Dtstart,
GetDateTimeMS (2011, 12, 15, 10, 0));
eventValues.Put (CalendarContract.Events.InterfaceConsts.Dtend,
GetDateTimeMS (2011, 12, 15, 11, 0));
eventValues.Put(CalendarContract.Events.InterfaceConsts.EventTimezone,
"UTC");
eventValues.Put(CalendarContract.Events.InterfaceConsts.EventEndTimezone,
"UTC");
var uri = ContentResolver.Insert (CalendarContract.Events.ContentUri,
eventValues);
Observe que, se não definirmos o fuso horário, uma exceção do tipo Java.Lang.IllegalArgumentException será lançada. Como os valores de tempo de evento devem ser expressos em milissegundos desde a época, criamos um método (em EventListActivity) para converter nossas especificações de GetDateTimeMS data em formato de milissegundos:
long GetDateTimeMS (int yr, int month, int day, int hr, int min)
{
Calendar c = Calendar.GetInstance (Java.Util.TimeZone.Default);
c.Set (Java.Util.CalendarField.DayOfMonth, 15);
c.Set (Java.Util.CalendarField.HourOfDay, hr);
c.Set (Java.Util.CalendarField.Minute, min);
c.Set (Java.Util.CalendarField.Month, Calendar.December);
c.Set (Java.Util.CalendarField.Year, 2011);
return c.TimeInMillis;
}
Se adicionarmos um botão à interface do usuário da lista de eventos e executarmos o código acima no manipulador de eventos click do botão, o evento será adicionado ao calendário e atualizado em nossa lista conforme mostrado abaixo:
Se abrirmos o aplicativo de calendário, veremos que o evento está escrito lá também:
Como você pode ver, o Android permite acesso poderoso e fácil para recuperar e persistir dados de calendário, permitindo que os aplicativos integrem perfeitamente os recursos de calendário.



