android开发笔记之锁屏界面未读短信未接来电提醒(android 4.4)
2016-10-19 10:34
489 查看
客户需求
最近在做一个项目,android 4.4系统,客户要求在锁屏界面有未读短信未接来电的提醒功能。而平台没有此功能,要自己实现。并且时间非常紧,………。(其实软件工程师基本上都是这样,坑,坑,坑)效果图
读取数据
(1)读取未接来电的数量主是是判断db数据库中的type和new二个字段是否同时是Calls.MISSED_TYPE 和1(type == Calls.MISSED_TYPE,new == 1).
通话记录的db数据库在:
/data/data/com.android.providers.contacts/databases/contacts2.db
calls表中
public int getUnreadCallNum(){ Log.d(TAG, "TinnoUnreadCallContentObserver---getUnreadCallNum" ); Cursor cursor = context.getContentResolver().query( CallLog.Calls.CONTENT_URI, new String[] {Calls.TYPE}, " type=? and new=?", new String[] {Calls.MISSED_TYPE + "", "1"}, "date desc"); Log.d(TAG, "TinnoUnreadCallContentObserver---getUnreadCallNum--cursor:"+cursor); int count = 0; if (cursor != null) { try { count = cursor.getCount(); Log.d(TAG, "TinnoUnreadCallContentObserver---getUnreadCallNum--count:"+count); } finally { cursor.close(); } } Log.d(TAG, "getUnreadCallNum count=" + count); return count; }
(2)读取未读短信数量:
这主要是未读短信和未读彩信的和:
public int getNewSmsCount() { int result = 0; Cursor csr = context.getContentResolver().query( Uri.parse("content://sms"), null, "type = 1 and read = 0", null, null); if (csr != null) { result = csr.getCount(); csr.close(); } return result; } public int getNewMmsCount() { int result = 0; Cursor csr = context.getContentResolver().query( Uri.parse("content://mms/inbox"), null, "read = 0", null, null); if (csr != null) { result = csr.getCount(); csr.close(); } return result; }
读取上面的数据,是要在AndroidManifest.xml文件中定义一下权限:
<uses-permission android:name="android.permission.READ_CALL_LOG" /> <uses-permission android:name="android.permission.WRITE_CALL_LOG" /> <uses-permission android:name="android.permission.READ_SMS" /> <uses-permission android:name="android.permission.WRITE_SMS"/>
界面显示
好了,要显示的数据得来了,下面就把这些数据在锁屏界面来显示吧。是不是觉得下面非常简单了,事实上,界面显示才是这个功能的真正的难点所在,我花费了大量的时间在这个界面显示上。那么,坑人的地方,是在那里呢?
因为我本身有MTK的实现了此能的代码,我一开始想直接移植此功能,非常可惜,由于平台差异太大,导致我移植后,一开机systemui就直接报错,根本就没有办法调试和分析,而导致systemui报错的地方,就是界面的布局文件是显示。
最好,我还是老老实实的一步一步的添加控件,一步一步的调试,才把这个界面显示添加上去。有时候,最笨的方法才是最可靠的方法。
我们先在keyguard_selector_view.xml文件中,添加显示未读短信和未接来电和图标和数量:
<com.android.keyguard.KeyguardSelectorView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard" android:id="@+id/keyguard_selector_view" android:layout_width="match_parent" android:layout_height="match_parent" androidprv:layout_maxWidth="420dp" androidprv:layout_maxHeight="@dimen/keyguard_security_height" android:clipChildren="false" android:clipToPadding="false" android:orientation="vertical" android:contentDescription="@string/keyguard_accessibility_slide_unlock"> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:clipChildren="false" android:clipToPadding="false" android:gravity="center"> <include layout="@layout/keyguard_message_area" android:layout_width="match_parent" android:layout_height="wrap_content" /> <View android:id="@+id/keyguard_selector_view_frame" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" android:background="@drawable/kg_bouncer_bg_white"/> <!-- add hexiaoming for lockscreen unread event start--> <FrameLayout android:id="@+id/flUnreadIncall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="40dp" android:layout_marginLeft="40dp"> <ImageView android:id="@+id/unreadIncall" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginTop="10dp" android:background="@drawable/mtk_ic_newevent_phone" android:visibility="invisible"/> <TextView android:id="@+id/unreadIncallNum" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="30dp" android:gravity="center" android:background="@drawable/mtk_ic_newevents_numberindication" android:visibility="invisible"/> </FrameLayout> <FrameLayout android:id="@+id/flUnreadIncall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="40dp" android:layout_marginLeft="220dp"> <ImageView android:id="@+id/unreadMms" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginTop="10dp" android:background="@drawable/mtk_ic_newevent_smsmms" android:visibility="invisible"/> <TextView android:id="@+id/unreadMmsNum" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="30dp" android:gravity="center" android:background="@drawable/mtk_ic_newevents_numberindication" android:visibility="invisible"/> </FrameLayout> <!-- add hexiaoming for lockscreen unread event end--> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="20dp" android:id="@+id/keyguard_unlock_panel"> <include layout="@layout/keyguard_glow_pad_container" /> </FrameLayout> <include layout="@layout/keyguard_eca" android:id="@+id/keyguard_selector_fade_container" android:layout_width="match_parent" android:layout_height="48dp" android:layout_gravity="bottom|center_horizontal" /> </FrameLayout> </com.android.keyguard.KeyguardSelectorView>
然后在KeyguardSelectorView.java文件中,添加对显示ui的实现逻辑,而这主要是依靠对call log和短信,彩信三个db数据库的监听来实现的。
先定义:
private SecurityMessageDisplay mSecurityMessageDisplay; private Drawable mBouncerFrame; //add hexiaoming for lockscreen unread event start private boolean isSupportUnreadEventLockscreen = true; private TextView unreadIncallNum = null; private ImageView unreadIncall = null; private Handler handler; private TextView unreadMmsNum = null; private ImageView unreadMms = null; private TinnoUnreadCallContentObserver tinnoUnreadCallContentObserver = null; private TinnoUnreadMmsContentObserver tinnoUnreadMmsContentObserver = null; //add hexiaoming for lockscreen unread event end
再初始化和注册监听:
@Override protected void onFinishInflate() { super.onFinishInflate(); mGlowPadView = (GlowPadView) findViewById(R.id.glow_pad_view); mGlowPadView.setOnTriggerListener(mOnTriggerListener); if (SystemProperties.getBoolean("ro.board.has.3in1speaker", false)) { mGlowPadView.setVibrateEnabled(false); // Do not vibrate when unlocking phone. } updateTargets(); mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this); View bouncerFrameView = findViewById(R.id.keyguard_selector_view_frame); mBouncerFrame = bouncerFrameView.getBackground(); //add hexiaoming for lockscreen unread event start if(isSupportUnreadEventLockscreen){ unreadIncallNum = (TextView)findViewById(R.id.unreadIncallNum); unreadIncall = (ImageView)findViewById(R.id.unreadIncall); handler = new Handler(); tinnoUnreadCallContentObserver = new TinnoUnreadCallContentObserver( handler, getContext(), unreadIncallNum, unreadIncall); getContext().getContentResolver().registerContentObserver( TinnoUnreadCallContentObserver.MISS_CALL_URI, true, tinnoUnreadCallContentObserver); unreadMmsNum = (TextView)findViewById(R.id.unreadMmsNum); unreadMms = (ImageView)findViewById(R.id.unreadMms); tinnoUnreadMmsContentObserver = new TinnoUnreadMmsContentObserver( handler, getContext(), unreadMmsNum, unreadMms); getContext().getContentResolver().registerContentObserver( Uri.parse("content://sms"), true, tinnoUnreadMmsContentObserver); getContext().getContentResolver().registerContentObserver( TinnoUnreadMmsContentObserver.UNREAD_MMSSMS_URI, true, tinnoUnreadMmsContentObserver); } //add hexiaoming for lockscreen unread event end }
至此,逻辑部分已经实现,您还需要在Android.mk文件中添加下面的定义,才可以编译:
#add hexiaoming for lockscreen unread event start LOCAL_JAVA_LIBRARIES += telephony-common mms-common #add hexiaoming for lockscreen unread event end
bug的解决
你以为就ok了,当然,如果从我们开发者来说,是的,功能是可以了。但是,对于使用者来说,不是这样的。测试提出来,说有一个bug:当我们有一个未接来电时,我们点击拨号应用,按道理来说,这个未接来电是要不再显示的,但是我们还是会显示未接来电。
我看了一下操作,思考了一下,其实原理非常简单,因为在点击拨号进入应用时,我们没有把未接来电改为已读来电,当然是还显示未接来电了。
那修改就简单了,我直接在拨号应用的主界面,当进来时,直接把未接来电改为已读来电就可以了。
实现逻辑:
Dialer\src\com\android\dialer\DialtactsActivity.java
@Override protected void onResume() { super.onResume(); ............ ............ //add hexiaoming for lockscreen new event start removeMissedCall(); //add hexiaoming for lockscreen new event end } //add hexiaoming for lockscreen new event start private void removeMissedCall() { // TODO Auto-generated method stub new AsyncTask<Void, Void, Void>() { @Override public Void doInBackground(Void... params) { // Cursor cursor = context.getContentResolver().query( // CallLog.Calls.CONTENT_URI, // new String[] {Calls.TYPE}, // " type=? and new=?", // new String[] {Calls.MISSED_TYPE + "", "1"}, // "date desc"); ContentValues values = new ContentValues(); values.put(Calls.TYPE, Calls.MISSED_TYPE); values.put("new", 0); String where = "type=? and new=?"; String[] selectValue = {Calls.MISSED_TYPE + "", "1"}; Log.d("debug_hxm","removeMissedCall--update"); getContentResolver().update( CallLog.Calls.CONTENT_URI, values, where, selectValue); return null; } }.execute(null, null, null); } //add hexiaoming for lockscreen new event end
源码下载地址:
http://download.csdn.net/detail/hfreeman2008/9657800相关文章推荐
- Android(java)学习笔记221:开发一个多界面的应用程序之不同界面间互相传递数据(短信助手案例)
- Android 在锁屏界面添加未读短信和电话提醒
- Android开发笔记之Intent跳转到系统应用中的拨号界面、联系人界面、短信界面
- Android(java)学习笔记222:开发一个多界面的应用程序之不同界面间互相传递数据(短信助手案例的优化:请求码和结果码)
- Android开发学习笔记(七)Android应用界面编程 Radio/Check/DataPicker学习
- Android应用开发笔记(1):调用打电话和发短信、收短信接口、发Email (Call, Dial, SMSManager, Broadcast, Email)
- Android开发之Intent跳转到系统应用中的拨号界面、联系人界面、短信界面 .相机.录影机....
- Android开发笔记--制作启动界面splash
- Android开发之Intent跳转到系统应用中的拨号界面、联系人界面、短信界面
- Android开发学习笔记(九)Android应用界面编程 AutoCompleteTextView学习
- Android开发之Intent跳转到系统应用中的拨号界面、联系人界面、短信界面 .相机.录影机...
- android ->在界面上使用URI编程 ----开发笔记1
- android ->在界面上使用URI编程 ----开发笔记1
- [置顶] android开发之来电自动拒接并自动回复短信_上课模式app
- Android开发之Intent跳转到系统应用中的拨号界面、联系人界面、短信界面
- android开发笔记 软键盘弹出,界面上移问题
- Android 开发学习笔记(五)—— 最简单的注册界面
- Android应用开发笔记(1):调用打电话和发短信、收短信接口、发Email (Call, Dial, SMSManager, Broadcast, Email)
- Android开发之Intent跳转到系统应用中的拨号界面、联系人界面、短信界面
- Android应用开发笔记(1):调用打电话和发短信、收短信接口、发Email