zhongyuanceshi
zhongyuanceshi
采纳率100%
2012-12-02 13:28 阅读 10.1k

如何在Android4.0.4锁屏界面的电话图标右上角显示未接电话个数?

目前,未接电话个数也要获取到。存在的问题就是如何在电话图标右上角显示未接电话个数?
电话图标是控件MultiWaveView上的图标,该类是系统已经定义好的。我想通过直接集成View来自定义自己的View,然后在OnDraw函数通过Canvas和paint,指定坐标来画。但始终是没有显示出来。自定义view的OnDraw函数也有跑到。请指教要实现这效果,该怎样是画未接个数呢?效果图:enter image description here
我是在自定义的handler中调用构造函数。每10s就会handler处理。

private final Handler mUpdateMissCallNum = new Handler() {
@Override
public void handleMessage(Message msg) {
Log.i(TAG, "mUpdateMissCallNum");
switch (msg.what) {
case UPDATESTART:

Log.i(TAG, "UPDATESTART");
sNewMissedCallCount = getMissedCallCount(mContext);
if (sNewMissedCallCount != sTempMissedCallCount)
{

Log.i(TAG, "sNewMissedCallCount != sTempMissedCallCount");
new Thread(new Runnable()
{
public void run()
{

Log.i(TAG, "sNewMissedCallCount is:"+sNewMissedCallCount);

Log.i(TAG, "sTempMissedCallCount is:"+sTempMissedCallCount);
sTempMissedCallCount = sNewMissedCallCount;
mMissedCallView=new MissedCallView(mContext,sTempMissedCallCount);
Log.i(TAG, "sTempMissedCallCount is:"+sTempMissedCallCount);
        }
        }
    ).start();
    }
    break;
    default:
    break;
    }
}
}

mMissedCallView=new MissedCallView(mContext,sTempMissedCallCount);这就是我调用自定义view的地方。通过直接用坐标和canvas,paint画,不要再在xml文件里去写吧。
锁屏用到的xml文件:Keyguardscreentabunlock.xml (framework\base\core\res\res\layout)该文件中用系统自定义的波纹锁屏

<com.android.internal.widget.multiwaveview.MultiWaveView
android:id="@+id/unlockwidget"
android:orientation="horizontal"
android:layoutwidth="matchparent"
android:layoutheight="matchparent"
android:layout_alignParentBottom="true"
        android:targetDrawables="@array/lockscreen_targets_with_camera"
        android:targetDescriptions="@array/lockscreen_target_descriptions_with_camera"
        android:directionDescriptions="@array/lockscreen_direction_descriptions"
        android:handleDrawable="@drawable/ic_lockscreen_handle"
        android:waveDrawable="@drawable/ic_lockscreen_outerring"
        android:outerRadius="@dimen/multiwaveview_target_placement_radius"
        android:snapMargin="@dimen/multiwaveview_snap_margin"
        android:hitRadius="@dimen/multiwaveview_hit_radius"
        android:rightChevronDrawable="@drawable/ic_lockscreen_chevron_right"
        android:horizontalOffset="0dip"
        android:verticalOffset="60dip"
        android:feedbackCount="3"
        android:vibrationDuration="20"
        />

效果图:enter image description here
我们只是把相机改成了拨号,就是在这拨号图标上打算画上未接电话数。请指教,谢谢!
这个类存放位置:framework\base\core\java\com\android\internal\widget\multiwaveview\MissedCallView.java

public class MissedCallView extends View {

private static final String TAG = "MissedCallViews";

public static final int UPDATESTART = 10;

private static final int DELAYTIME = 10000;

private int sTempMissedCallCount=-1;

Context mContext;

Canvas mCanvas;

public MissedCallView(Context context) 
{

super(context);

Log.i(TAG, "MissedCallView1");

mCanvas=new Canvas();

}

public MissedCallView(Context context, AttributeSet attrs)
{ 
super(context, attrs);

Log.i(TAG, "MissedCallView2");

mCanvas=new Canvas();

}

public MissedCallView(Context context,int missedCallNum) {

super(context);

sTempMissedCallCount=missedCallNum;

Log.i(TAG, "MissedCallView3");

mCanvas=new Canvas();

}

@Override 
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

if(sTempMissedCallCount>0)

{

Paint paint=new Paint(Paint.ANTIALIASFLAG); 
paint.setColor(Color.RED); Log.i(TAG,"Integer.toString(sTempMissedCallCount)is:"+Integer.toString(sTempMissedCallCount)); canvas.drawText(Integer.toString(sTempMissedCallCount),40,310,paint);//50 invalidate();

Log.i(TAG, "invalidate");

}

}

} 

这是自定义view。只跑了 这个构造函数MissedCallView(Context context,int missedCallNum)。是在我定义的public class MissCallObserver extends ContentObserver监听未接电话个数类中调用的。为什么没有跑onDraw函数?请指教。未接电话个数获取是正确的。关键是显示了。

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

8条回答 默认 最新

  • 已采纳
    u010616022 u010616022 2013-05-08 06:54

    布局使用FrameLayout,将电话图标控件放下面,默认显示,未接个数控件放上面,默认隐藏;
    逻辑采用ContentObserver监听电话数据库的变化,数据变化时查询数据库,得到未接电话个数

    点赞 4 评论 复制链接分享
  • ce_la_vie ce_la_vie 2012-12-03 03:35

    可以用标记flagFLAG_SHOW_WHEN_LOCKED实现

    public static final int FLAG_SHOW_WHEN_LOCKED
    

    添加到API 5中

    flag: 当屏幕被锁时显示指定标记,这会让应用窗口优先于其他窗口,可以用`FLAG_KEEP_SCREEN_ON`打开屏幕,在keyguard之前直接显示窗口,用`FLAG_DISMISS_KEYGUARD`自动解除keyguard。
    

    在图片中显示2这个数量:

    在系统设置中设置alarm字符串

    String message = "2";
    Settings.System.putString(context.getContentResolver(),
            Settings.System.NEXT_ALARM_FORMATTED, message);
    

    补充:

    需要查询未接电话的个数,然后在Cursor获取查询到的总数:

    String[] projection = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
           String where = CallLog.Calls.TYPE+"="+CallLog.Calls.MISSED_TYPE;          
           Cursor c = this.getContentResolver().query(CallLog.Calls.CONTENT_URI, selection,where, null, null);
           c.moveToFirst();    
           Log.d("CALL", ""+c.getCount()); //其他操作
            if(c.getCount() == SOME_VALUE_TO_START_APP_ONE)
    

    在where语句中,设置选择数据的条件,根据你的需求,应该是CallLog.Calls.MISSED_TYPE

    还可以选择来电的名字,号码,家庭工作什么的。

    表达式和SQL查询语句是等价的,比如:

    SELECT CACHED_NAME, CACHED_NUMBER_LABEL, TYPE FROM CONTENT_URI WHERE TYPE=MISSED_TYPE
    

    android锁屏的说明:http://code.google.com/p/mylockforandroid/wiki/LockActivity

    点赞 评论 复制链接分享
  • franzhong franzhong 2012-12-03 10:08

    如果我理解不错的话,你是想自绘View
    你把问题理清楚,就两点关健地方,
    1:取得未接电话条数
    2:将这个int型变量显示
    问题(1)可参考下面代码:

    private void findNewCallCount(){     
            Cursor  csr = null;     
            int missedCallCount = 0;   
            try {     
                csr = getContentResolver().query(Calls.CONTENT_URI, new String[]{Calls.NUMBER,Calls.TYPE,Calls.NEW},   
                        null,null,Calls.DEFAULT_SORT_ORDER);     
                if(null != csr){   
                    while(csr.moveToNext()){   
                        int type = csr.getInt(csr.getColumnIndex(Calls.TYPE));   
                        switch (type){   
                            case Calls.MISSED_TYPE:   
                                if(csr.getInt(csr.getColumnIndex(Calls.NEW)) == ){   
                                    missedCallCount++;   
                                }   
                                break;   
                            case Calls.INCOMING_TYPE:   
                                break;   
                            case Calls.OUTGOING_TYPE:   
                                break;   
                        }   
                    }   
                }   
            } catch (Exception e) {     
                e.printStackTrace();     
            } finally {     
                csr.close();     
            }     
            newCallCount = missedCallCount;//未读电话数目     
        }
    

    问题(2)关于canvas显示问题
    这样就可以把字写上去了
    //canvas.drawText("123条记录", x, y, mPaint);//xy坐标
    你的view是怎么写的,可以log调试分析呀。
    你想立既显示,却未公布你相关代码,我猜肯定是未刷新造成的
    当有新的未接电话,立马刷新canvas,刷新方式多样
    invalidate或者postinvalindate()都能调用onDraw函数还有矩形区域设置等地方需
    注意,你可以搜"android canvas refresh"
    你需要一个单独线程跟踪或是启动个service监听。

    点赞 评论 复制链接分享
  • cytown Billy_崔海斌 2012-12-06 03:56

    MultiWaveView 接受的是Drawable, 所以最简单的方法是更改为新的BitmapDrawable,里面包含电话的icon和未接电话数,然后MultiWaveView.postInvalidate即可。

    点赞 评论 复制链接分享
  • u013417251 菲雪zzz 2014-01-08 06:13

    先注释后改为Paint mPaint = new Paint(); franzhong

    点赞 评论 复制链接分享
  • u012889565 格瑞特喏 2014-03-12 03:50

    private void findNewCallCount(){

    Cursor csr = null;

    int missedCallCount = 0;

    try {

    csr = getContentResolver().query(Calls.CONTENT_URI, new String[]{Calls.NUMBER,Calls.TYPE,Calls.NEW},

    null,null,Calls.DEFAULT_SORT_ORDER);

    if(null != csr){

    while(csr.moveToNext()){

    int type = csr.getInt(csr.getColumnIndex(Calls.TYPE));

    switch (type){

    case Calls.MISSED_TYPE:

    if(csr.getInt(csr.getColumnIndex(Calls.NEW)) == ){

    missedCallCount++;

    }
    break;

    case Calls.INCOMING_TYPE:

    break;

    case Calls.OUTGOING_TYPE:

    break;

    }

    }

    }

    } catch (Exception e) {

    e.printStackTrace();

    } finally {

    csr.close();

    }

    newCallCount = missedCallCount;//未读电话数目

    }

    点赞 评论 复制链接分享
  • crazy1235 月盡天明 2014-12-09 03:10

    使用github上的开源库BadgeView可以实现你的效果,你的功能就靠你自己来写了!

    点赞 评论 复制链接分享
  • longyc2010 智者向内寻求力量 2014-12-13 13:56

    这个效果一般都是使用相对布局来实现的,在MMS中有实现,可以参考一下。
    原理是,在电话图标所在的位置(坐标),计算数字显示的坐标,然后设置一个TextView到相应的位置,用以现实数字。
    应该是不需要自定义View来实现。每隔一定时间更新一下TextView显示的数字就可以了。
    这里需要注意的是,TextView中显示的数字的位置需要根据数字的宽度调整,否则数字显示的不美观。同时字体的大小也需要有调整。也就是数字位数越多,字体也就相应的小一点,否则是显示不开的,同时也美观。

    点赞 评论 复制链接分享

相关推荐