友录项目总结笔记

来源:互联网 发布:mac 六维空间 编辑:程序博客网 时间:2024/06/06 11:36
分析项目布局结构:
-建立BaseFragment父类,封装Actionbar初始化方法
-建立MyBaseAdapter抽象父类,将共性的方法初始化,个性的方法抽象化


1.联系人模块:
  -封装联系人实体类Contact
  -建立联系人数据的业务处理类ContactManager
  -在业务处理类ContactManager中建立方法从系统数据库获取联系人的信息
    a)通过ContentResolver从ContactsContract.Contacts表中获取联系人账户id
      Uri uri = ContactsContract.Contacts.CONTENT_URI;   
    b) 根据获得的联系人账户id通过ContentResolver从ContactsContract.Data表中获取具体的联系人数据
      Uri dataUri = ContactsContract.Data.CONTENT_URI;
    c)将获取的联系人信息放入缓存数组和联系人集合List<Contact>
  -创建联系人adapter,在adapter中初始化列表,并对在列表第一项加入“新建联系人”项
    a)通过自定义view实现图片圆形处理工具
  -对adapter设置事件监听
   创建对话框管理类DialogManager,所有对话框的操作业务封装在此类
     单击新建联系人项: 通过弹出对话框实现新建联系人,实际通过intent意图来调用系统的新建联系人功能来实现
     Intent intent=new Intent(ContactsContract.Intents.SHOW_OR_CREATE_CONTACT);
 //必须以电话号码为意图的索引
Uri uri=Uri.parse("tel:"+phone);
intent.setData(uri);
 //设置联系人的姓名
intent.putExtra(ContactsContract.Intents.Insert.NAME, name);
          //设置联系人的公司
intent.putExtra(ContactsContract.Intents.Insert.COMPANY, company);
//设置联系人的邮箱
intent.putExtra(Insert.EMAIL, email);
//设置联系人的地址
intent.putExtra(Insert.POSTAL, address);
//激活联人添加的组件
context.startActivity(intent);
  单击其余项: 通过对话编辑更新联系人信息:
   //清空联系人在缓存中的数据
ContactManager.clearCache(contact);
//调用系统的联系人编辑的组件实现联系人的编辑处理
Intent intent=new Intent(Intent.ACTION_EDIT);
   Uri uri=Uri.parse("content://contacts/people/"+contact.getId());
ntent.setData(uri);
 //编辑完成后直接退系统的activity
intent.putExtra("finishActivityOnSaveCompleted", true);
context.startActivity(intent);
   双击新建联系人以外的项:通过对话框来确认删除联系人数据,
             
             删除ContactsContract.RawContacts表中数据:        
     ContentResolver resolver=context.getContentResolver();
     resolver.delete(ContactsContract.RawContacts.CONTENT_URI,
RawContacts.CONTACT_ID+"=?",
new String[]{String.valueOf(contact.getId())});

删除ContactsContract.data表中数据:
Uri uri=Data.CONTENT_URI;
String where=Data.CONTACT_ID+"=?";
String[] args=new String[]{String.valueOf(contact.getId())};
resolver.delete(uri, where, args);
 
  删除联系人集合和缓存数组中的数据
 
 
2.通话记录模块:
-构建通话记录实体类Calllog封装所需的属性
-通过ContentResolver查询CallLog.Calls获得所有通话记录
           所需uri: Uri uri=CallLog.Calls.CONTENT_URI;
  创建格式化日期的方法,将获得的long型日期转化为所需的String型日期
 
        public static String formatDate(long stam){
int daydiff=dayDiff(stam);
String strDate="";
if(daydiff==0){SimpleDateFormat dateFormat=new SimpleDateFormat("HH:mm");
strDate=dateFormat.format(new Date(stam));
}else if(daydiff==1){
strDate="昨天";
}else if(daydiff<=7){
Calendar calendar=Calendar.getInstance();
calendar.setTimeInMillis(stam);
int week=calendar.get(Calendar.DAY_OF_WEEK);
switch (week) {
case Calendar.MONDAY: strDate="星期一";break;
case Calendar.TUESDAY:strDate="星期二";break;
case Calendar.WEDNESDAY:strDate="星期三";break;
case Calendar.THURSDAY: strDate="星期四"; break;
case Calendar.FRIDAY: strDate="星期五"; break;
case Calendar.SATURDAY:strDate="星期六"; break;
case Calendar.SUNDAY:strDate="星期天"; break;
default: break;}
}else{
SimpleDateFormat format=
new SimpleDateFormat("yyyy-MM-dd");
strDate=format.format(new Date(stam));
}
return strDate;
}
  - 构建通话记录adapter,初始化listview列表
  - 设置listview长按监听,弹出对话框,确认删除通话记录:
-根据双击item的Calllog对象的Id来删除CallLog.Calls数据表中的数据
-移除通话记录集合中的此Calllog对象的数据List<Calllog>
 
 
3.拨打电话: 
  -应用通话记录的实体集合及adapter初始化该模块的通话记录数据列表
  -动态添加拨号键盘布局并添加监听:
  public static String keys[]={"1","2","3","4","5","6","7","8","9","0","*","#"};
//动态初始化拨号键盘
public void initialDailPad(){
//设置拨号键的宽和高
DisplayMetrics metrics=new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
//按键的宽度
int width=metrics.widthPixels/3;
int height=(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 55, getActivity().getResources().getDisplayMetrics());

for(int i=0;i<keys.length;i++){
TextView key=new TextView(getActivity());
key.setId((i+1));
key.setText(keys[i]);
key.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 30);
key.setGravity(Gravity.CENTER);

LayoutParams params=new LayoutParams(width, height);
//如果当前控件的循环变量不能被3整除要设置右对齐
if(i%3!=0){
params.addRule(RelativeLayout.RIGHT_OF, i);
}
if(i>=3){
params.addRule(RelativeLayout.BELOW,(i-2));
}
layout_dailpad.addView(key,params);
//为每个按钮添加监听
key.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(isAnim){
return;
}
MediaManager.playTone(getActivity(), R.raw.b);
String k=((TextView)v).getText().toString();
String title=textview_title.getText().toString();
if(title.equals("拨打电话")){
textview_title.setText(k);
}else if(title.length()==3||title.length()==8){
textview_title.append("-");
textview_title.append(k);
}else{
textview_title.append(k);
}
}
});
}
-创建媒体管理类MediaManager通过SoundPool类为按键添加音效:
 
public class MediaManager {
public static SoundPool soundPool=null;
public static void playTone(Context context,int resId){
if(soundPool==null){
soundPool=new SoundPool(4, AudioManager.STREAM_MUSIC, 0);
}
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
soundPool.play(sampleId, 1.0f, 1.0f, 1, 0, 1.0f);}
});
soundPool.load(context, resId, 1);
}
public static void release(){
if(soundPool!=null){
soundPool.release();
soundPool=null;
}
}
}
 
  -调用系统拨号功能来拨打电话:
               Intent intent=new Intent(Intent.ACTION_CALL);
String phone=textview_title.getText().toString();
Uri uri=Uri.parse("tel:"+phone);
intent.setData(uri);
startActivity(intent);
 
 4.短信息模块:
  -构建会话实体类Conversation封装所需的属性
  -创建短信息管理类SMSManager
  -通过ContentResolver以及第三方的Uri来查询所有会话数据:(一个会话可能包含多个短信息)
  Uri CONVERSATION_URI = Uri.parse("content://mms-sms/conversations");
  -所获数据放入会话集合 List<Conversation>
  -创建ConversationAdapter初始化会话列表项
  -为会话列表添加事件监听:
  双击:弹出对话框,确认删除,删除数据库中相应会话Id的数据
  public static void deleteConversation(
Context context,
Conversation conversation){
ContentResolver resolver=context.getContentResolver();
String where="thread_id=?";
String args[]=new String[]{String.valueOf(conversation.getThread_id())};
resolver.delete(CONVERSATION_URI, where, args);
}
单击:跳转到发送短信息的ChatActivity,跳转时需通过intent将所需数据传入ChatActivity
    public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
Conversation conversation=adapter.getItem(position);
SMSManager.updateConversation(getActivity(), conversation);
//实现一个窗口的跳转
//将当前选中的会话信息传到
//下一个窗口
Intent intent=new Intent(getActivity(),ChatActivity.class);
intent.putExtra("thread_id", conversation.getThread_id());
intent.putExtra("name", conversation.getName());
intent.putExtra("address", conversation.getAddress());

startActivity(intent);
}
   - ChatActivity启动时,获取intent传入的数据:
      private void initialData() {
Intent intent=getIntent();
thread_id=intent.getIntExtra("thread_id", 0);
name=intent.getStringExtra("name");
address=intent.getStringExtra("address");
 }
   - ChatActivity中新建BroadcastReceiver内部类,注册为广播接收者,添加事件过滤:
      
      private void registMyReceiver() {
myReceiver=new MyReceiver();
IntentFilter filter=new IntentFilter();
//订阅收到短信时的系统广播
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
filter.addAction("com.tarena.karen.SEND_SMS");
//将过滤器的优先级足够高,使当前应用优先接收到广播 
filter.setPriority(1000);
registerReceiver(myReceiver, filter);
}
   - 有新短息到来时,截取短信,将短信保存到收件箱并忽略收到短信有序广播,不再向系统的短信收发应用传递:
     public void onReceive(Context context, 
Intent intent) {
String action=intent.getAction();
if("android.provider.Telephony.SMS_RECEIVED".equals(action)){
//有短信发来了
//将短信数据提取出来
Bundle bundle=intent.getExtras();
SMS sms=SMSManager.onRecieveMessage(context, bundle);
Log.i("TAG:sms", sms.toString());
//判断一下是不是发给当前会话的短信
//如果是的话将短信保存到收件箱并忽略收到短信的
//有序广播 ,不再向系统的短信收发应用传递
if(address.equals(sms.getAddress())){
//将短信保存在收件箱中
SMSManager.saveReciveMessage(context, sms, thread_id);
//忽略当前的有序广播
//使系统的短信应用不再接收该短信
abortBroadcast();
refreshSMS();
}
}else if("com.tarena.karen.SEND_SMS".equals(action)){
//有短信发出去了。
//把发出的短信的内容存到发件箱中
String body=intent.getStringExtra("body");
String address=intent.getStringExtra("address");
//把短信存到发件箱
SMSManager.saveSendSMS(context, body, address);
//刷新界面
refreshSMS();
}
}

public static SMS onRecieveMessage(Context context,Bundle bundle){
//对bundle中封装的短信内容进行拆解
Object[] pdus =(Object[])bundle.get("pdus");
SmsMessage[] messages=new SmsMessage[pdus.length];
for(int i=0;i<pdus.length;i++){
messages[i]=SmsMessage.createFromPdu((byte[])pdus[i]);
}

StringBuilder builder=new StringBuilder();
String address="";
long date=0;
for(int i=0;i<messages.length;i++){
if(i==0){
address=messages[i].getOriginatingAddress();
date=messages[i].getTimestampMillis();
}
builder.append(messages[i].getMessageBody());
}
SMS sms=new SMS();
sms.setAddress(address);
sms.setDate(date);
sms.setBody(builder.toString());
sms.setType(1);
return sms;
}

             保存收到的短信通过将数据插入到系统的收件箱中实现:
    public static void saveReciveMessage(Context context,SMS sms,int thread_id){
ContentResolver resolver=context.getContentResolver();
ContentValues values=new ContentValues();

values.put("thread_id", thread_id);
values.put("body", sms.getBody());
values.put("address", sms.getAddress());
values.put("date", sms.getDate());
values.put("read", 1);
values.put("type", sms.getType());
 //Uri SMS_INBOX_URI = Uri.parse("content://sms/inbox")
resolver.insert(SMS_INBOX_URI, values);

}
             保存发出的短信通过将数据插入到系统的发件箱中实现:
   
   
   public static void saveSendSMS(Context context,String body,String address){
ContentResolver resolver=context.getContentResolver();
ContentValues values=new ContentValues();

values.put("address", address);
values.put("body", body);
values.put("date", System.currentTimeMillis());
values.put("type", 2);
values.put("read", 1);
 //Uri SMS_SEND_URI = Uri SMS_SEND_URI = Uri.parse("content://sms/sent")
resolver.insert(SMS_SEND_URI, values);
}
   
    发送短信息通过SmsManager以发送广播的方式来进行:
   
   
   public static  void sendSMS(Context context,String content,String address){
SmsManager manager=SmsManager.getDefault();
List<String> smses=manager.divideMessage(content);

for(int i=0;i<smses.size();i++){

Intent intent =new Intent();
String action="com.tarena.karen.SEND_SMS";
intent.setAction(action);
intent.putExtra("body", smses.get(i));
intent.putExtra("address", address);
PendingIntent pendingIntent=PendingIntent.getBroadcast(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);

manager.sendTextMessage(address, null, smses.get(i), pendingIntent, null);
}
}
   
   
   
  说明:对系统的数据库操作以及调用系统相关功能时,需要在清单配置文件中声明权限 
0 0