android notification应用之自定义来电通知


1.为了实现老板的各种要求 本人矜矜业业完成任务 随着这个软电话软件的日益完善 本来来电的时候是创建一条通知点亮屏幕 用户可以解锁屏幕后接起电话 但老板又觉得体验不好 想直接在锁屏状态下直接接起电话 我就寻思着 自带的notification通知栏样式肯定是不能实现这个接电话挂电话的功能的 那就相方设法自己写一个通知栏样式呗 我本来以为自定义通知栏不好实现 加上还有按钮的相关接电话和挂电话的功能 (ps:这个时候我请教了我的老师 其实非常感谢他的帮助 让我在四五个月内 学了不少android的开发技能 问他问题他会给我讲解大致思路 然后让我自己按照这个思路去完成要求 实在不会了 他也会给我提供具体的方法 总之就是很感谢那个大哥哥了)
2. 自定义通知的实现主要是用到了RemoteViews来对通知栏样式进行更改 ,本来通知栏的创建使用了 Notification.Builder(this, CHANNEL_ONE_ID) 自定义通知栏时使用了NotificationCompat.Builder(this) 下面来贴一下代码

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void showNotification(String phoneNum) {
        if (phoneNums.size()>0) {
            notificationId = phoneNums.indexOf(phoneNum);
        } else{
            notificationId = 100;
        }
        manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
        String CHANNEL_ONE_ID = getPackageName();
        String CHANNEL_ONE_NAME = "Channel One";
        NotificationChannel notificationChannel = null;
        manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            notificationChannel = new NotificationChannel(CHANNEL_ONE_ID, CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_HIGH);
            notificationChannel.enableLights(true);
            notificationChannel.setLightColor(Color.RED);
            notificationChannel.setShowBadge(true);
            notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
            manager.createNotificationChannel(notificationChannel);
        }

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);

        builder.setSmallIcon(R.mipmap.ic_launcher);//使用RemoteViews时,设置的是状态栏中的小图标,必须要设置
        builder.setAutoCancel(true);//设置是否点击通知后会自动消失
        Notification notification = builder.build();
        //通过xml创建RemoteViews,并且动态改变布局中的内容
        RemoteViews views = new RemoteViews(getPackageName(), R.layout.layout_notification);
        views.setTextViewText(R.id.notification_title, "WES");
        views.setTextViewText(R.id.notification_content, Sys.details);
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        //按钮点击事件:

		//接通电话的相关操作
        PendingIntent acceptIntent = PendingIntent.getBroadcast(this,notificationId ,new Intent("action.accept"),PendingIntent.FLAG_UPDATE_CURRENT);
        views.setOnClickPendingIntent(R.id.accept_icon,acceptIntent);//点击的id,点击事件
		/挂断电话的相关操作(点击挂断电话的按钮会发送一个action为action.decline的广播,然后广接收者受到广播对广播进行处理 )
        PendingIntent declineIntent = PendingIntent.getBroadcast(this,notificationId ,new Intent("action.decline"),PendingIntent.FLAG_UPDATE_CURRENT);
        views.setOnClickPendingIntent(R.id.decline_icon,declineIntent);//点击的id,点击事件


        String time = sdf.format(date);
        views.setTextViewText(R.id.notification_time, time);
        //这里需要注意,如果不设置 notification.bigContentView ,则由于通知的高度是固定的,如果remoteview的布局超过了其通知的高度,
        //就会有一部分显示不出来了
        notification.bigContentView = views;
        notification.contentView = views;
        notification.visibility = Notification.VISIBILITY_PUBLIC;
        //给整个通知设置一个拉起来电页面的PendingIntent
        Intent intentNotification = new Intent(SiphoneService.this, CallIncomingActivity.class);
        intentNotification.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intentNotification.setPackage("com.sux.sip");
        PendingIntent pi = PendingIntent.getActivity(this, notificationId, intentNotification, PendingIntent.FLAG_CANCEL_CURRENT);
        notification.contentIntent = pi;

        //单独给RemoteView中的控件设置PengdingIntent
//                Intent intentNotification2 = new Intent();
//                intentNotification2.setComponent(new ComponentName("com.netease.newsreader.activity","com.netease.nr.biz.ad.AdActivity"));
//                intentNotification.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//                PendingIntent pi2 = PendingIntent.getActivity(context, 123, intentNotification2, PendingIntent.FLAG_CANCEL_CURRENT);
//                views.setOnClickPendingIntent(R.id.iv_banner,pi2);

        manager.notify(notificationId, notification);
    }

这里我给相同的电话号码设置了相同的notificationId,这样通知的时候就只会出现一条通知 还有一点没完善 应该要填上来电几条的 嗯 以后再加上吧
3.下面来实现广播接受者

public class NotificationBroadcast extends BroadcastReceiver {
    private final static String TAG = "NotificationBroadcast";
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();//动作

        Log.e(TAG, "广播 Action = " + action);
        if (action.equals("action.accept")) {
            Log.e(TAG, "接通电话");
            Call call = SiphoneService.getCore().getCurrentCall();
            if(call != null){
                Call.State state = call.getState();
                if(state.equals(Call.State.IncomingEarlyMedia) ||state.equals(Call.State.IncomingReceived)){
                    if(SiphoneService.manager!=null){
                        System.out.println("call notificationId1:"+SiphoneService.notificationId);
                        SiphoneService.manager.cancel(SiphoneService.notificationId);
                    }
                    CallParams params = SiphoneService.getCore().createCallParams(call);
                    call.acceptWithParams( params );
                }
            }

        }else if (action.equals("action.decline")) {
            Log.e(TAG, "挂断电话");
            Call call = SiphoneService.getCore().getCurrentCall();
            if(call != null){
                Call.State state = call.getState();
                if(state.equals(Call.State.IncomingEarlyMedia) ||state.equals(Call.State.IncomingReceived)){
                //这里的manager是前面代码中的关于notification的manager  挂断电话既是对这条通知的处理 接通电话同理  就直接取消掉前面的通知
                    if(SiphoneService.manager!=null){
                        System.out.println("call notificationId1:"+SiphoneService.notificationId);
                        SiphoneService.manager.cancel(SiphoneService.notificationId);
                    }
                    call.terminate();
                }
            }

        }
    }
//这里我没用这个方法对通知栏进行伸缩  因为当我选择挂断电话还是接听电话  都对这个消息进行了处理  直接使用了上面的取消通知的功能
//    public void collapseStatusBar(Context context) {
//        try {
//            Object statusBarManager = context.getSystemService("statusbar");
//            Method collapse;
//            if (Build.VERSION.SDK_INT <= 16) {
//                collapse = statusBarManager.getClass().getMethod("collapse");
//            } else {
//                collapse = statusBarManager.getClass().getMethod("collapsePanels");
//            }
//            collapse.invoke(statusBarManager);
//        } catch (Exception localException) {
//            localException.printStackTrace();
//        }

}

广播是我们自己定义的action 所以在AndroidManifest.xml中需要拦截一下广播的action

 <receiver
            android:name=".receviers.NotificationBroadcast"
            android:enabled="true">
            <intent-filter>
                <action android:name="action.accept"/>
                <action android:name="action.decline"/>
            </intent-filter>
        </receiver>

4.贴一下我自定义的notification布局 layout_notification.xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp">
        <TextView
            android:id="@+id/notification_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="WES"/>
        <TextView
            android:id="@+id/notification_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:text="23:34"/>

    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp">
        <TextView
            android:id="@+id/notification_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="111111111111111"/>
    </LinearLayout>
    <LinearLayout
        android:id="@+id/acceptUnlock"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/accept_icon"
            android:src="@drawable/call_start"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="3dp"
            android:layout_weight="1"/>
        <ImageView
            android:id="@+id/decline_icon"
            android:src="@drawable/hangup"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"/>
    </LinearLayout>
</LinearLayout>

5.总结一下 贴代码真的很爽 写起文字来真的很烦
最后实现的结果就是在锁屏下会有一条通知点亮屏幕 通知的内容是来电的相关信息 可以选择接电话和挂断电话 接电话后居然可以跨过锁屏来到通话界面 点击缩放可以使通话界面悬浮 再次进到通话界面需要解锁 解锁后也有悬浮窗也可以回到通话界面
在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐