准备写个app,本弱鸡自然是从最简单的功能入手,边学边写,其中一个小功能便是做一个,事件提醒功能,不过听说用系统日历,app被杀依然能执行事件提醒功能,所以便开始了学习
之前已经发过了一个博客,这次就写里面的 坑~~,还有完整的实现代码;
首先是xml的代码,然后是活动Activit里的代码,Log,v()是我用来测试的,请忽略
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="向系统日历中添加事件" />
<Button
android:id="@+id/inputaccount"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="添加账户" />
<Button
android:id="@+id/readUserButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="查看账户" />
<Button
android:id="@+id/readEventButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="查看事件" />
<Button
android:id="@+id/writeEventButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="插入事件" />
<Button
android:id="@+id/delEventButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="删除事件" />
</LinearLayout>
package com.example.shiyan1;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.TimeZone;
import android.Manifest;
import android.app.Activity;
import android.content.ContentValues;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.nfc.Tag;
import android.os.Bundle;
import android.provider.CalendarContract;
import android.provider.CalendarContract.Calendars;
import android.provider.CalendarContract.Events;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.DialogTitle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class Main2Activity extends Activity {
//Android2.2版本以后的URL,之前的就不写了
private static String calanderURL = "content://com.android.calendar/calendars";
private static String calanderEventURL = "content://com.android.calendar/events";
private static String calanderRemiderURL = "content://com.android.calendar/reminders";
private static final String TAG = "MainActivity1";
private static final String TAG1 = "MainActivity2";
private static final String TAG2 = "MainActivity3";
private static final String TAG3= "MainActivity4";
private static final String TAG5 = "MainActivity6";
private static final String TAG6 = "MainActivity7";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
String[] permission1 = new String[]{Manifest.permission.READ_CALENDAR};
String[] permissions2=new String[]{Manifest.permission.WRITE_CALENDAR};
if (ContextCompat.checkSelfPermission(Main2Activity.this, Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(Main2Activity.this, new
String[]{ Manifest.permission.READ_CALENDAR }, 1);
}
if (ContextCompat.checkSelfPermission(Main2Activity.this, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(Main2Activity.this, new
String[]{ Manifest.permission.WRITE_CALENDAR}, 1);
}
}
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
switch (requestCode) {
case 1:
if (grantResults.length > 0 && grantResults[0] == PackageManager.
PERMISSION_GRANTED) {
Toast.makeText(this,"谢谢给予权限",Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "You denied the permission", Toast.LENGTH_SHORT).show();
}
break;
default:
}
}
public void onClick(View v) {
Cursor userCursor=null;
if (v.getId() == R.id.readUserButton) { //读取系统日历账户,如果为0的话先添加
Log.v("Tag6","去吧皮卡丘,哈哈哈哈哈哈哈哈哈哈哈哈嘿嘿");
try {
Uri uri = Uri.parse("content://com.android.calendar/calendars");
userCursor = getContentResolver().query(uri, null, null, null, null);
Log.v("Tag", "去吧皮卡丘,哈哈哈哈哈哈哈哈哈哈哈哈嘿嘿");
Toast.makeText(this, "Count: " + userCursor.getCount(), Toast.LENGTH_LONG).show();
for (userCursor.moveToFirst(); !userCursor.isAfterLast(); userCursor.moveToNext()) {
Log.v("Tag1 ", "我" + userCursor.getString(userCursor.getColumnIndex("ACCOUNT_NAME")));
String userName1 = userCursor.getString(userCursor.getColumnIndex("name"));
String userName0 = userCursor.getString(userCursor.getColumnIndex("ACCOUNT_NAME"));
Toast.makeText(this, "NAME: " + userName1 + " -- ACCOUNT_NAME: " + "我" + userName0, Toast.LENGTH_LONG).show();
}
}catch (Exception e){
e.printStackTrace();
}finally {
if(userCursor !=null){
userCursor.close();
}
}
}
else if (v.getId() == R.id.inputaccount) { //添加日历账户
initCalendars();
}
else if (v.getId() == R.id.delEventButton) { //删除事件
int rownum = getContentResolver().delete(Uri.parse(calanderURL), "_id!=-1", null); //注意:会全部删除所有账户,新添加的账户一般从id=1开始,
//可以令_id=你添加账户的id,以此删除你添加的账户
Toast.makeText(Main2Activity.this, "删除了: " + rownum, Toast.LENGTH_LONG).show();
}
else if (v.getId() == R.id.readEventButton) { //读取事件
try {
Cursor eventCursor = getContentResolver().query(Uri.parse(calanderEventURL), null, null, null, null);
if (eventCursor.getCount() > 0) {
eventCursor.moveToLast(); //注意:这里与添加事件时的账户相对应,都是向最后一个账户添加
String eventTitle = eventCursor.getString(eventCursor.getColumnIndex("title"));
Toast.makeText(Main2Activity.this, eventTitle, Toast.LENGTH_LONG).show();
}
}catch (Exception e){
e.printStackTrace();
}finally {
if(userCursor!=null){
userCursor.close();
}
}
}
else if (v.getId() == R.id.writeEventButton) {
// 获取要出入的gmail账户的id
String calId = "";
Log.v(TAG3,"我崩溃了没 writebutton2zzz2");
try {
userCursor = getContentResolver().query(Uri.parse(calanderURL), null, null, null, null);
Log.v(TAG3, "我崩溃了没 writebutton2多少度222");
if (userCursor.getCount() > 0) {
userCursor.moveToLast(); //注意:是向最后一个账户添加,开发者可以根据需要改变添加事件 的账户
calId = userCursor.getString(userCursor.getColumnIndex("_id"));
} else {
Toast.makeText(this, "没有账户,请先添加账户", Toast.LENGTH_SHORT).show();
return;
}
}catch (Exception e){
e.printStackTrace();
}finally {
if(userCursor!=null){
userCursor.close();
}
}
ContentValues event = new ContentValues();
event.put("title", "插入了个事件l");
event.put("description", "Frankiedfaijdfiohjfionswwrfkjnwlfnmwkerfhk~");
// 插入账户
event.put("calendar_id", calId);
System.out.println("calId: " + calId);
event.put("eventLocation", "地球-华夏");
Calendar mCalendar = Calendar.getInstance();
mCalendar.set(Calendar.HOUR_OF_DAY, 11);
mCalendar.set(Calendar.MINUTE, 45);
long start = mCalendar.getTime().getTime();
mCalendar.set(Calendar.HOUR_OF_DAY, 12);
long end = mCalendar.getTime().getTime();
event.put("dtstart", start);
event.put("dtend", end);
event.put("hasAlarm", 1);
event.put(Events.EVENT_TIMEZONE, "Asia/Shanghai"); //这个是时区,必须有,
//添加事件
Log.v(TAG3,"我崩溃了没 writebutton4444");
Uri newEvent = getContentResolver().insert(Uri.parse(calanderEventURL), event);
Log.v(TAG3,"我崩溃了没 writebutton3333");
//事件提醒的设定
long id = Long.parseLong(newEvent.getLastPathSegment());
ContentValues values = new ContentValues();
values.put("event_id", id);
// 提前10分钟有提醒
values.put("minutes", 10);
Log.v(TAG3,"我崩溃了没 writebutton");
getContentResolver().insert(Uri.parse(calanderRemiderURL), values);
Log.v(TAG3,"我崩溃了没 writebutton2222");
Toast.makeText(Main2Activity.this, "插入事件成功!!!", Toast.LENGTH_LONG).show();
}
}
//添加账户
private void initCalendars() {
TimeZone timeZone = TimeZone.getDefault();
ContentValues value = new ContentValues();
value.put(Calendars.NAME, "yy");
value.put(Calendars.ACCOUNT_NAME, "mygmailaddress@gmail.com");
value.put(Calendars.ACCOUNT_TYPE, "com.android.exchange");
value.put(Calendars.CALENDAR_DISPLAY_NAME, "mytt");
value.put(Calendars.VISIBLE, 1);
value.put(Calendars.CALENDAR_COLOR, -9206951);
value.put(Calendars.CALENDAR_ACCESS_LEVEL, Calendars.CAL_ACCESS_OWNER);
value.put(Calendars.SYNC_EVENTS, 1);
value.put(Calendars.CALENDAR_TIME_ZONE, timeZone.getID());
value.put(Calendars.OWNER_ACCOUNT, "mygmailaddress@gmail.com");
value.put(Calendars.CAN_ORGANIZER_RESPOND, 0);
Uri calendarUri = Calendars.CONTENT_URI;
calendarUri = calendarUri.buildUpon()
.appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
.appendQueryParameter(Calendars.ACCOUNT_NAME, "mygmailaddress@gmail.com")
.appendQueryParameter(Calendars.ACCOUNT_TYPE, "com.android.exchange")
.build();
Log.v(TAG2,"我崩溃了没");
try{getContentResolver().insert(calendarUri, value);}
catch (Exception e){
e.printStackTrace();
}
Log.v(TAG3,"我崩溃了没222");
}
}
遇到的坑就是,button一点击程序就崩溃,报错也是报的不太相关的东西,找了别人的代码才发现了区别
第一个就是抛出异常,别人写了我没写,
第二个Cursor对象,用完别人关闭了,我没关
而且经过测试发现getContentResolver进行查询的时候,程序运行到这里就会崩。所这块地方我全抛出了异常
第三个,就是后来发现calendarRead,calenarWrite 竟然是危险权限,所以只在 AndroidManifest申请权限是不行的,还要在活动里,再申请一遍,让用户同意申请才行。