Android Notification 史上最全面的解析

关于Notification那些事,最近一直在弄这块,抽了点时间总结一下,做了一个Demo,废话不多说,先上图看效果


通知.png

通知2.png

在Android 3.0 (API level 11)之前,使用new Notification()方式创建通知:

String tickerText = "tikcker内容";
String title ="标题";
String content ="内容";

NotificationManager mNotifyMgr = 
      (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, 
new Intent(this, SecondActivity.class), 0);

Notification notification = new Notification(icon, tickerText, when);
notification.setLatestEventInfo(this, title, content, contentIntent);

mNotifyMgr.notify(0, notification);

Android 3.0 以后以及高版本改用Notification.Builder()来创建通知,原来的new Notification() 的方式被启弃用了

NotificationManager mNotifyMgr=(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
PendingIntent contentIntent=PendingIntent.getActivity(
      this, 0, new Intent(this, SecondActivity.class), 0);

Notification notification = new Notification.Builder(this)
            .setSmallIcon(R.drawable.ic_launcher)
            .setContentTitle("标题")
            .setContentText("需要展示的内容")
            .setContentIntent(contentIntent)
            .build();

mNotifyMgr.notify(0, notification);

现在用的是NotificationCompat.Builder方式,它和Notification.Builder()方式没有很大的区别,NotificationCompat.Builder 是v4包中,而Notification是android.app 包中的,使用NotificationCompat.Builder 在兼容方面会更好一点

接下来看下几种通知
1,普通通知 最常见的方式

做了一下简单的封装,写了一个单独的NotificationManager类来管理通知,先来看下第一种方式的代码

 /**
     * 基本展示通知方法
     *
     * @param ctx      上下文
     * @param noticeId 通知id
     * @param title    通知title
     * @param message  通知内容
     * @param intent   PendingIntent
     */
    public static void showNotify(Context ctx, int noticeId, String title, String message, PendingIntent intent) {
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(ctx, null);
        mBuilder.setSmallIcon(R.mipmap.ic_launcher);
        mBuilder.setContentTitle(title);
        mBuilder.setContentText(message);
        mBuilder.setContentIntent(intent);
        mBuilder.setAutoCancel(true);
        mBuilder.setTicker(title);
        mBuilder.setPriority(NotificationManagerCompat.IMPORTANCE_HIGH);
        Notification notification = mBuilder.build();
        notification.flags = Notification.FLAG_AUTO_CANCEL;
        notification.defaults |= Notification.DEFAULT_SOUND;//默认声音
        notification.defaults |= Notification.DEFAULT_LIGHTS;//默认闪烁
        android.app.NotificationManager notificationManager = (android.app.NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
        if (notificationManager != null) {
            notificationManager.notify(noticeId, notification);
        }
    }

再来看下两种不同的调用方式
no.1

  /**
     * 第一种方式,普通通知
     */
    private void showNotification() {
        Intent resultIntent = new Intent(this, SecondActivity.class);
        resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        //(new Random().nextInt(1000) 这个地方这么写的原因,是部分低版本的不能跳转,比如说小米3
        PendingIntent resultPendingIntent = PendingIntent.getActivity(this, (new Random().nextInt(1000)),
                resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        NotificationManager.showNotify(this,0, getString(R.string.app_name),
                "普通通知", resultPendingIntent);
    }

no.2

  /**
     * 第二种方式的普通通知
     */
    private void showNotion() {
        Intent resultIntent = new Intent(this, SecondActivity.class);
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        stackBuilder.addParentStack(SecondActivity.class);
        stackBuilder.addNextIntent(resultIntent);
        PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
        resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);

        NotificationManager.showNotify(this,1, getString(R.string.app_name),
                "第二种方式的普通通知", resultPendingIntent);

    }

使用第二种方式的是时候需要注意,SecondActivity在androidMainfest.xml中需要设置一下,

原因:

默认情况下,从通知启动一个Activity,按返回键会回到主屏幕。但有时候产品经理要求按返回键仍然留在当前应用的需求,这就要用到TaskStackBuilder了

注意:如果Intent 有数据传递的话,需要在onNewIntent()方法中接收Intent传递过来的数据

 <activity
            android:name=".SecondActivity"
            android:excludeFromRecents="true"
            android:launchMode="singleTask"
            android:parentActivityName=".MainActivity"
            android:taskAffinity="">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".MainActivity"/>
        </activity>

为什么要这么设置呢?
因为在用户点击通知,进入到SecondActivity界面后点击返回按钮是就会回到你设置的那个父类界面,如果不设置的话,就会直接退出了

接下来看下自定义通知
注意:自定义普通视图通知高度限制为64dp,大视图通知高度限制为256dp。在使用自定义通知尽量简单,以提高兼容性。
 /**
     * 设置自定义通知 view
     *
     * @param ctx         上下文
     * @param remoteViews 自定义view
     * @param noticeId    通知id
     * @param ticker      ticker
     * @param intent      PendingIntent
     */
    public static void showCustomNotify(Context ctx, RemoteViews remoteViews, int noticeId, String ticker, PendingIntent intent) {
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(ctx, null);
        mBuilder.setSmallIcon(R.mipmap.ic_launcher);
        mBuilder.setContentIntent(intent);
        mBuilder.setAutoCancel(true);
        mBuilder.setContent(remoteViews);
        mBuilder.setTicker(ticker);
        mBuilder.setPriority(NotificationManagerCompat.IMPORTANCE_HIGH);
        Notification notification = mBuilder.build();
        notification.flags = Notification.FLAG_AUTO_CANCEL;
        notification.defaults |= Notification.DEFAULT_SOUND;//默认声音
        notification.defaults |= Notification.DEFAULT_LIGHTS;//默认闪烁
        android.app.NotificationManager notificationManager = (android.app.NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
        if (notificationManager != null) {
            notificationManager.notify(noticeId, notification);
        }
    }

在Mainactivity里面调用

  /**
     * 自定义view 的普通通知
     *
     * @param context
     */
    private static void showCustomNotification(Context context) {
        //自定义显示布局
        RemoteViews contentViews = new RemoteViews(context.getPackageName(), R.layout.custom_notification);
        //通过控件的Id设置属性
        contentViews.setImageViewResource(R.id.ImageView, R.mipmap.ic_launcher);
        contentViews.setTextViewText(R.id.title, "自定义通知标题");
        contentViews.setTextViewText(R.id.content, "自定义通知内容");

        Intent resultIntent = new Intent(context, SecondActivity.class);
        resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        //(new Random().nextInt(1000) 这个地方这么写的原因,是部分低版本的不能跳转,比如说小米3
        PendingIntent resultPendingIntent = PendingIntent.getActivity(context, (new Random().nextInt(1000)),
                resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        NotificationManager.showCustomNotify(context, contentViews,2, "ticker", resultPendingIntent);

    }

custom_notification.xml代码

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:padding="10dp"
    >

    <ImageView
        android:id="@+id/ImageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_marginRight="10dp"/>

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/ImageView"/>

    <TextView
        android:id="@+id/content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/title"
        android:layout_toRightOf="@id/ImageView">
    </TextView>

</RelativeLayout>

从API16开始,通知出现了大视图的样式,在下拉视图时会呈现大视图的效果。大图通知一般分成3种,文字型(BigTextStyle)、图片型(BigPictureStyle)、列表型(InboxStyle)

BigTextStyle 方式的通知
/**
     * 设置 BigTextStyle通知
     *
     * @param ctx         上下文
     * @param noticeId    通知id
     * @param title       标题
     * @param summaryText 摘要
     * @param bigText     内容
     * @param intent      PendingIntent
     */
    public static void showBigTextNotify(Context ctx, int noticeId, String title, String summaryText, String bigText, PendingIntent intent) {
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(ctx, null);
        mBuilder.setSmallIcon(R.mipmap.ic_launcher);
        mBuilder.setContentIntent(intent);
        mBuilder.setAutoCancel(true);
        mBuilder.setTicker(title);
        mBuilder.setPriority(NotificationManagerCompat.IMPORTANCE_HIGH);

        NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle();
        bigTextStyle.setBigContentTitle(title)
                .setSummaryText(summaryText)
                .bigText(bigText);
        mBuilder.setStyle(bigTextStyle);

        Notification notification = mBuilder.build();
        notification.flags = Notification.FLAG_AUTO_CANCEL;
        notification.defaults |= Notification.DEFAULT_SOUND;//默认声音
        notification.defaults |= Notification.DEFAULT_LIGHTS;//默认闪烁
        android.app.NotificationManager notificationManager = (android.app.NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
        if (notificationManager != null) {
            notificationManager.notify(noticeId, notification);
        }
    }

在MainActivity里面调用

 /**
     * 展示bigTextStyle 通知
     */
    private void showBigTextNotification() {
        Intent resultIntent = new Intent(this, SecondActivity.class);
        resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent resultPendingIntent = PendingIntent.getActivity(this, (new Random().nextInt(1000)),
                resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        NotificationManager.showBigTextNotify(this, 4,"标题", "摘要摘要", "bigTextStyle通知", resultPendingIntent);
    }
BigPictureStyle 样式的通知

    /**
     * 设置BigPictureStyle通知
     *
     * @param ctx         上下文
     * @param noticeId    通知id
     * @param title       标题
     * @param summaryText 摘要
     * @param intent      PendingIntent
     */
    public static void showBigPictureNotify(Context ctx, int noticeId, String title, String summaryText, PendingIntent intent) {
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(ctx, null);
        mBuilder.setSmallIcon(R.mipmap.ic_launcher);
        mBuilder.setLargeIcon(BitmapFactory.decodeResource(ctx.getResources(), R.mipmap.icon_picture));
        mBuilder.setContentIntent(intent);
        mBuilder.setAutoCancel(true);
        mBuilder.setTicker(title);
        mBuilder.setPriority(NotificationManagerCompat.IMPORTANCE_HIGH);

        NotificationCompat.BigPictureStyle bigTextStyle = new NotificationCompat.BigPictureStyle();
        bigTextStyle.setBigContentTitle(title)
                .setSummaryText(summaryText)
                .bigLargeIcon(BitmapFactory.decodeResource(ctx.getResources(), R.mipmap.icon_picture))
                .bigPicture(BitmapFactory.decodeResource(ctx.getResources(), R.mipmap.bg_big_picture));
        mBuilder.setStyle(bigTextStyle);

        Notification notification = mBuilder.build();
        notification.flags = Notification.FLAG_AUTO_CANCEL;
        notification.defaults |= Notification.DEFAULT_SOUND;//默认声音
        notification.defaults |= Notification.DEFAULT_LIGHTS;//默认闪烁
        android.app.NotificationManager notificationManager = (android.app.NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
        if (notificationManager != null) {
            notificationManager.notify(noticeId, notification);
        }
    }

在MainActivity 中调用

 /**
     * 展示bigPictureStyle 通知
     */
    private void showBigPictureNotification() {
        Intent resultIntent = new Intent(this, SecondActivity.class);
        resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent resultPendingIntent = PendingIntent.getActivity(this, (new Random().nextInt(1000)),
                resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        NotificationManager.showBigPictureNotification(this, "标题", "bigPictureStyle形式的通知", resultPendingIntent);
    }

InboxStyle 多行通知
  /**
     * 展示多行通知
     *
     * @param ctx         上下文
     * @param noticeId    通知id
     * @param title       标题
     * @param summaryText 摘要
     * @param lineList    需要展示多行数据的集合
     * @param intent      PendingIntent
     */
    public static void showInboxNotify(Context ctx, int noticeId, String title, String summaryText, List<String> lineList, PendingIntent intent) {
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(ctx, null);
        mBuilder.setSmallIcon(R.mipmap.ic_launcher);
        mBuilder.setLargeIcon(BitmapFactory.decodeResource(ctx.getResources(), R.mipmap.icon_picture));
        mBuilder.setContentIntent(intent);
        mBuilder.setAutoCancel(true);
        mBuilder.setTicker(title);
        mBuilder.setPriority(NotificationManagerCompat.IMPORTANCE_HIGH);

        NotificationCompat.InboxStyle bigTextStyle = new NotificationCompat.InboxStyle();
        bigTextStyle.setBigContentTitle(title)
                .setSummaryText(summaryText);
        for (int i = 0; i < lineList.size(); i++) {
            bigTextStyle.addLine(lineList.get(i));
        }
        mBuilder.setStyle(bigTextStyle);

        Notification notification = mBuilder.build();
        notification.flags = Notification.FLAG_AUTO_CANCEL;
        notification.defaults |= Notification.DEFAULT_SOUND;//默认声音
        notification.defaults |= Notification.DEFAULT_LIGHTS;//默认闪烁
        android.app.NotificationManager notificationManager = (android.app.NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
        if (notificationManager != null) {
            notificationManager.notify(noticeId, notification);
        }
    }

在MainActivity中调用

 /**
     * 展示InboxStyle 通知
     */
    private void showInboxNotification() {
        Intent resultIntent = new Intent(this, SecondActivity.class);
        resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent resultPendingIntent = PendingIntent.getActivity(this, (new Random().nextInt(1000)),
                resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        List<String> lineList = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            lineList.add("wwwwwwwwww" + i);
        }
        NotificationManager.showInboxNotify(this,5, "标题标题", "InboxStyle形式的通知", lineList, resultPendingIntent);
    }
进度条通知
进度条通知.png
/**
     * 带有进度条的通知
     *
     * @param ctx     上下文
     * @param title   标题
     * @param message 内容信息
     * @param intent  PendingIntent 这里做了一个下载安装的案例,实际情况如果不需要则可以不加PendingIntent 参数,点击通知就不会有跳转
     * @return NotificationCompat.Builder
     */
    public static NotificationCompat.Builder showProgressNotify(Context ctx, String title, String message, PendingIntent intent) {
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(ctx, null);
        mBuilder.setSmallIcon(R.mipmap.ic_launcher);
        mBuilder.setContentTitle(title);
        mBuilder.setContentText(message);
        mBuilder.setContentIntent(intent);
        mBuilder.setAutoCancel(true);
        mBuilder.setTicker(title);
        mBuilder.setPriority(NotificationManagerCompat.IMPORTANCE_HIGH);//设置通知的优先级
        return mBuilder;
    }

在前面MainActivity里调用

 /**
     * 进度条通知
     */
    private void showProgressNotification() {
        Intent resultIntent = new Intent(this, SecondActivity.class);
        resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent resultPendingIntent = PendingIntent.getActivity(this, (new Random().nextInt(1000)),
                resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        final NotificationCompat.Builder builder = NotificationManager.showProgressNotify(this, "下载", "正在下载", resultPendingIntent);

        Notification notification = builder.build();
        notification.flags = Notification.FLAG_AUTO_CANCEL;//当通知被用户点击之后会自动被清除(cancel)
        final android.app.NotificationManager notificationManager = (android.app.NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        if (notificationManager != null) {
            //这里最好使用固定的id,因为如果通知id不固定的话,每次更新就会弹出多个通知
            notificationManager.notify(PROGRESS_NO_ID, notification);
        }
        builder.setProgress(100, 0, false);
        //下载以及安装线程模拟
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    builder.setProgress(100, i, false);
                    notificationManager.notify(PROGRESS_NO_ID, builder.build());
                    //下载进度提示
                    builder.setContentText("下载" + i + "%");
                    try {
                        Thread.sleep(50);//演示休眠50毫秒
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //下载完成后更改标题以及提示信息
                builder.setContentTitle("开始安装");
                builder.setContentText("安装中...");
                //设置进度为不确定,用于模拟安装
                builder.setProgress(0, 0, true);
                notificationManager.notify(PROGRESS_NO_ID, builder.build());
            }
        }).start();
    }
接下来看下更新通知

更新通知很简单,只需再次发送相同ID(就是上面代码中的通知ID)的通知即可,如果之前的通知依然存在则会更新通知属性,如果之前通知不存在则重新创建。
如果用不同的ID,那么通知就会往上叠加,和IOS一样,
本文最后会Git地址中的代码写了两种方式方法,需要的话可以download下来看下

取消通知
  1. 点击通知栏的清除按钮,会清除所有可清除的通知

  2. 设置了 setAutoCancel() 或 FLAG_AUTO_CANCEL的通知,点击该通知时会清除它

  3. 通过 NotificationManager 调用 cancel() 方法清除指定ID的通知

  4. 通过 NotificationManager 调用 cancelAll() 方法清除所有该应用之前发送的通知

以下是需要注意的地方
通知必须要设置的属性
setSmallIcon() 设置小图标
setContentTitle() 设置通知标题
setContentText()  设置通知内容

注意:

1,如果是自定义通知的话
setSmallIcon() 这个方法一定要有
标题和内容可以放在自定义布局里面

2,文字型(BigTextStyle)、图片型(BigPictureStyle)、列表型(InboxStyle) 也是必须要设置setSmallIcon()
标题和内容可以通过对应的Style 方式设置

浮动通知

图片

设置setFullScreenIntent()

详情可以看我的代码中,这是Android5.0以后才有的。
如果你要用这个方法,最好做下sdk的判断,该方法很坑的

注意上面那个方法的使用,
注意点:
1. 设置改方法后,通知不会自动消失,需要用户手动滑掉,比如左滑就删除了,向上滑才会消失
2. 如果你的通知有跳转界面的话,使用该方法后部分手机会直接跳转,魅族和美图手机就出现了,(已踩坑)
3,在锁屏状态下收到通知时,同样的如果有跳转的话,会直接跳转到你APP 对应的界面,用户体验很不好

这个问题,官网说就是这样的,
暂时没有找到解决方法,如果有人找到的话,记得给俺留言😁

锁屏通知

Android5.0开始,通知可以显示在锁屏上。用户可以通过设置选择是否允许敏感的通知内容显示在安全的锁屏上。
你的应用可以通过setVisibility()控制通知的显示等级:
VISIBILITY_PRIVATE : 显示基本信息,如通知的图标,但隐藏通知的全部内容
VISIBILITY_PUBLIC : 显示通知的全部内容
VISIBILITY_SECRET : 不显示任何内容,包括图标
例如:
mBuilder.setVisibility(NotificationCompat.VISIBILITY_SECRET);//通知的显示等级

常见的Notification的Flag属性使用
Notification.DEFAULT_VIBRATE           //添加默认震动提醒  需要 VIBRATE permission
Notification.DEFAULT_SOUND             //添加默认声音提醒
Notification.DEFAULT_LIGHTS            // 添加默认三色灯提醒
Notification.DEFAULT_ALL               // 添加默认以上3种全部提醒
Notification.FLAG_SHOW_LIGHTS          //三色灯提醒,在使用三色灯提醒时候必须加该标志符
Notification.FLAG_ONGOING_EVENT        //发起正在运行事件(活动中)
Notification.FLAG_INSISTENT            //让声音、振动无限循环,直到用户响应(取消或者打开)
Notification.FLAG_ONLY_ALERT_ONCE      //发起Notification后,铃声和震动均只执行一次
Notification.FLAG_AUTO_CANCEL          //用户单击通知后自动消失
Notification.FLAG_NO_CLEAR             //只有全部清除时,Notification才会清除 ,不清除该通知 
Notification.FLAG_FOREGROUND_SERVICE   //表示正在运行的服务
调用方法
Notification notification = mBuilder.build();
notification.flags = Notification.FLAG_AUTO_CANCEL;////当通知被用户点击之后会自动被清除(cancel)
notification.defaults |= Notification.DEFAULT_SOUND;//默认声音
notification.defaults |= Notification.DEFAULT_LIGHTS;//默认闪烁
PendingIntent 和Intent区别
1, Intent 是及时启动,Intent 随着所在的Activity 消失而消失

2,PendingIntent是即将要发生的事情,在Notification中跳转页面,不是马上跳转,而是你点击通知后再跳转,
可以理解为延迟执行的Intent 

3,PendingIntent可以cancel,Intent 是不可以的另外
Intent在程序结束后即终止,而PendingIntent在程序结束后依然有效

4,Intent一般是用作Activity、Sercvice、BroadcastReceiver之间传递数据,而Pendingintent,一般用在Notification上,PendingIntent是对Intent一个包装。 

5, 如果你在项目中使用到了Intent,最好设置下setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
因为有些Android 4.4 以下的手机,跳转有问题

后续会继续补充更多说明
以上是给出的代码是项目中的一部分,详细的代码在Git 上
地址: https://github.com/shaozucheng/NotificationDemo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容