iOS藍(lán)牙開發(fā)

CoreBluetooth詳解

CoreBluetooth框架的核心其實是兩個東西科盛,peripheral和central, 可以理解成外設(shè)和中心绊起。

圖中兩組api分別對應(yīng)不同的業(yè)務(wù)場景写半,左側(cè)叫做中心模式吏恭,就是以你的app作為中心惠豺,連接其他的外設(shè)的場景辽故,而右側(cè)稱為外設(shè)模式徒仓,使用手機作為外設(shè)別其他中心設(shè)備操作的場景

image

關(guān)于藍(lán)牙開發(fā)的一些重要的理論概念:

  1、服務(wù)(services):藍(lán)牙外設(shè)對外廣播的時候一定會有一個服務(wù)誊垢,有些時候也可以是有多個服務(wù)掉弛,服務(wù)下面包含一些特性,服務(wù)可以理解成一個模塊的窗口喂走;
  2殃饿、特征(characteristic):特征存在于服務(wù)下面的,一個服務(wù)下面可以有多個特征芋肠,特征可以理解成具體實現(xiàn)功能的窗口乎芳,一般的特性都會有value,也就是特征值帖池,是特征和外界交互的最小單位奈惑;
  3、UUID:藍(lán)牙上的唯一標(biāo)示符睡汹,為了區(qū)分不同設(shè)備肴甸、服務(wù)及特征,就用UUID來表示囚巴。

CBCentralMannager 中心模式

以手機(app)作為中心原在,連接其他外設(shè)的場景。詳細(xì)流程如下:

步驟1.建立一個Central Manager實例進行藍(lán)牙管理

步驟2.搜索外圍設(shè)備

步驟3.連接外圍設(shè)備

步驟4.獲得外圍設(shè)備的服務(wù)

步驟5.獲得服務(wù)的特征

步奏6.從外圍設(shè)備讀數(shù)據(jù)(直接讀取和訂閱兩種方法)

步驟7.給外圍設(shè)備發(fā)送數(shù)據(jù)

#import "ViewController.h"
#import 
#define kPeripheralName @"Kenshin Cui's Device" //外圍設(shè)備名稱
#define kServiceUUID @"C4FB2349-72FE-4CA2-94D6-1F3CB16331EE" //服務(wù)的UUID
#define kCharacteristicUUID @"6A3E4B28-522D-4B3B-82A9-D5E2004534FC" //特征的UUID

@interface ViewController ()

@property (strong,nonatomic) CBPeripheralManager *peripheralManager;//外圍設(shè)備管理器

@property (strong,nonatomic) NSMutableArray *centralM;//訂閱此外圍設(shè)備特征的中心設(shè)備

@property (strong,nonatomic) CBMutableCharacteristic *characteristicM;//特征
@property (weak, nonatomic) IBOutlet UITextView *log; //日志記錄

@end
@implementation ViewController
#pragma mark - 控制器視圖事件
- (void)viewDidLoad {
    [super viewDidLoad];
}

#pragma mark - UI事件
- (IBAction)startClick:(UIBarButtonItem *)sender {
    //創(chuàng)建中心設(shè)備管理器并設(shè)置當(dāng)前控制器視圖為代理
    _centralManager=[[CBCentralManager alloc]initWithDelegate:self queue:nil];
}

#pragma mark - CBCentralManager代理方法
//中心服務(wù)器狀態(tài)更新后
-(void)centralManagerDidUpdateState:(CBCentralManager *)central{
    switch (central.state) {
        case CBPeripheralManagerStatePoweredOn:
            NSLog(@"BLE已打開.");
            [self writeToLog:@"BLE已打開."];
            //掃描外圍設(shè)備
//            [central scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:kServiceUUID]] options:@{CBCentralManagerScanOptionAllowDuplicatesKey:@YES}];
            [central scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey:@YES}];
            break;

        default:
            NSLog(@"此設(shè)備不支持BLE或未打開藍(lán)牙功能彤叉,無法作為外圍設(shè)備.");
            [self writeToLog:@"此設(shè)備不支持BLE或未打開藍(lán)牙功能晤斩,無法作為外圍設(shè)備."];
            break;
    }
}
/**
 *  發(fā)現(xiàn)外圍設(shè)備
 *
 *  @param central           中心設(shè)備
 *  @param peripheral        外圍設(shè)備
 *  @param advertisementData 特征數(shù)據(jù)
 *  @param RSSI              信號質(zhì)量(信號強度)
 */
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{
    NSLog(@"發(fā)現(xiàn)外圍設(shè)備...");
    [self writeToLog:@"發(fā)現(xiàn)外圍設(shè)備..."];
    //停止掃描
    [self.centralManager stopScan];
    //連接外圍設(shè)備
    if (peripheral) {
        //添加保存外圍設(shè)備,注意如果這里不保存外圍設(shè)備(或者說peripheral沒有一個強引用姆坚,無法到達連接成功(或失敯谋谩)的代理方法,因為在此方法調(diào)用完就會被銷毀
        if(![self.peripherals containsObject:peripheral]){
            [self.peripherals addObject:peripheral];
        }
        NSLog(@"開始連接外圍設(shè)備...");
        [self writeToLog:@"開始連接外圍設(shè)備..."];
        [self.centralManager connectPeripheral:peripheral options:nil];
    }

}
//連接到外圍設(shè)備
-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
    NSLog(@"連接外圍設(shè)備成功!");
    [self writeToLog:@"連接外圍設(shè)備成功!"];
    //設(shè)置外圍設(shè)備的代理為當(dāng)前視圖控制器
    peripheral.delegate=self;
    //外圍設(shè)備開始尋找服務(wù)
    [peripheral discoverServices:@[[CBUUID UUIDWithString:kServiceUUID]]];
}
//連接外圍設(shè)備失敗
-(void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
    NSLog(@"連接外圍設(shè)備失敗!");
    [self writeToLog:@"連接外圍設(shè)備失敗!"];
}

#pragma mark - CBPeripheral 代理方法
//外圍設(shè)備尋找到服務(wù)后
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
    NSLog(@"已發(fā)現(xiàn)可用服務(wù)...");
    [self writeToLog:@"已發(fā)現(xiàn)可用服務(wù)..."];
    if(error){
        NSLog(@"外圍設(shè)備尋找服務(wù)過程中發(fā)生錯誤兼呵,錯誤信息:%@",error.localizedDescription);
        [self writeToLog:[NSString stringWithFormat:@"外圍設(shè)備尋找服務(wù)過程中發(fā)生錯誤兔辅,錯誤信息:%@",error.localizedDescription]];
    }
    //遍歷查找到的服務(wù)
    CBUUID *serviceUUID=[CBUUID UUIDWithString:kServiceUUID];
    CBUUID *characteristicUUID=[CBUUID UUIDWithString:kCharacteristicUUID];
    for (CBService *service in peripheral.services) {
        if([service.UUID isEqual:serviceUUID]){
            //外圍設(shè)備查找指定服務(wù)中的特征
            [peripheral discoverCharacteristics:@[characteristicUUID] forService:service];
        }
    }
}
//外圍設(shè)備尋找到特征后
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
    NSLog(@"已發(fā)現(xiàn)可用特征...");
    [self writeToLog:@"已發(fā)現(xiàn)可用特征..."];
    if (error) {
        NSLog(@"外圍設(shè)備尋找特征過程中發(fā)生錯誤腊敲,錯誤信息:%@",error.localizedDescription);
        [self writeToLog:[NSString stringWithFormat:@"外圍設(shè)備尋找特征過程中發(fā)生錯誤,錯誤信息:%@",error.localizedDescription]];
    }
    //遍歷服務(wù)中的特征
    CBUUID *serviceUUID=[CBUUID UUIDWithString:kServiceUUID];
    CBUUID *characteristicUUID=[CBUUID UUIDWithString:kCharacteristicUUID];
    if ([service.UUID isEqual:serviceUUID]) {
        for (CBCharacteristic *characteristic in service.characteristics) {
            if ([characteristic.UUID isEqual:characteristicUUID]) {
                //情景一:通知
                /*找到特征后設(shè)置外圍設(shè)備為已通知狀態(tài)(訂閱特征):
                 *1.調(diào)用此方法會觸發(fā)代理方法:-(void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
                 *2.調(diào)用此方法會觸發(fā)外圍設(shè)備的訂閱代理方法
                 */
                [peripheral setNotifyValue:YES forCharacteristic:characteristic];
                //情景二:讀取
//                [peripheral readValueForCharacteristic:characteristic];
//                    if(characteristic.value){
//                    NSString *value=[[NSString alloc]initWithData:characteristic.value encoding:NSUTF8StringEncoding];
//                    NSLog(@"讀取到特征值:%@",value);
//                }
            }
        }
    }
}
//特征值被更新后
-(void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    NSLog(@"收到特征更新通知...");
    [self writeToLog:@"收到特征更新通知..."];
    if (error) {
        NSLog(@"更新通知狀態(tài)時發(fā)生錯誤维苔,錯誤信息:%@",error.localizedDescription);
    }
    //給特征值設(shè)置新的值
    CBUUID *characteristicUUID=[CBUUID UUIDWithString:kCharacteristicUUID];
    if ([characteristic.UUID isEqual:characteristicUUID]) {
        if (characteristic.isNotifying) {
            if (characteristic.properties==CBCharacteristicPropertyNotify) {
                NSLog(@"已訂閱特征通知.");
                [self writeToLog:@"已訂閱特征通知."];
                return;
            }else if (characteristic.properties ==CBCharacteristicPropertyRead) {
                //從外圍設(shè)備讀取新值,調(diào)用此方法會觸發(fā)代理方法:-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
                [peripheral readValueForCharacteristic:characteristic];
            }

        }else{
            NSLog(@"停止已停止.");
            [self writeToLog:@"停止已停止."];
            //取消連接
            [self.centralManager cancelPeripheralConnection:peripheral];
        }
    }
}
//更新特征值后(調(diào)用readValueForCharacteristic:方法或者外圍設(shè)備在訂閱后更新特征值都會調(diào)用此代理方法)
-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    if (error) {
        NSLog(@"更新特征值時發(fā)生錯誤碰辅,錯誤信息:%@",error.localizedDescription);
        [self writeToLog:[NSString stringWithFormat:@"更新特征值時發(fā)生錯誤,錯誤信息:%@",error.localizedDescription]];
        return;
    }
    if (characteristic.value) {
        NSString *value=[[NSString alloc]initWithData:characteristic.value encoding:NSUTF8StringEncoding];
        NSLog(@"讀取到特征值:%@",value);
        [self writeToLog:[NSString stringWithFormat:@"讀取到特征值:%@",value]];
    }else{
        NSLog(@"未發(fā)現(xiàn)特征值.");
        [self writeToLog:@"未發(fā)現(xiàn)特征值."];
    }
}

#pragma mark - 屬性
-(NSMutableArray *)peripherals{
   if(!_peripherals){
       _peripherals=[NSMutableArray array];
   }
   return _peripherals;
}

#pragma mark - 私有方法
/**
 *  記錄日志
 *
 *  @param info 日志信息
 */
-(void)writeToLog:(NSString *)info{
    self.log.text=[NSString stringWithFormat:@"%@\r\n%@",self.log.text,info];
}

@end

CBPeripheralManager 外設(shè)模式

使用手機作為外設(shè)連接其他中心設(shè)備操作的場景介时。
PS:因為蘋果設(shè)備的安全性和封閉性,蘋果設(shè)備不能通過與其他設(shè)備藍(lán)牙鏈接進行文件傳輸?shù)裙δ?所以在iOS與藍(lán)牙開發(fā)的編程中是CBCentralMannager 中心模式編程居多.

1 建立外設(shè)角色
2 設(shè)置本地外設(shè)的服務(wù)和特征
3 發(fā)布外設(shè)和特征
4 廣播服務(wù)
5 響應(yīng)中心的讀寫請求
6 發(fā)送更新的特征值没宾,訂閱中心

#import "ViewController.h"
#import 
#define kServiceUUID @"C4FB2349-72FE-4CA2-94D6-1F3CB16331EE" //服務(wù)的UUID
#define kCharacteristicUUID @"6A3E4B28-522D-4B3B-82A9-D5E2004534FC" //特征的UUID

@interface ViewController ()

@property (strong,nonatomic) CBCentralManager *centralManager;//中心設(shè)備管理器
@property (strong,nonatomic) NSMutableArray *peripherals;//連接的外圍設(shè)備
@property (weak, nonatomic) IBOutlet UITextView *log;//日志記錄

@end
@implementation ViewController
#pragma mark - 視圖控制器方法
- (void)viewDidLoad {
    [super viewDidLoad];
}

#pragma mark - UI事件
//創(chuàng)建外圍設(shè)備
- (IBAction)startClick:(UIBarButtonItem *)sender {
    _peripheralManager=[[CBPeripheralManager alloc]initWithDelegate:self queue:nil];
}
//更新數(shù)據(jù)
- (IBAction)transferClick:(UIBarButtonItem *)sender {
    [self updateCharacteristicValue];
}

#pragma mark - CBPeripheralManager代理方法
//外圍設(shè)備狀態(tài)發(fā)生變化后調(diào)用
-(void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral{
    switch (peripheral.state) {
        case CBPeripheralManagerStatePoweredOn:
            NSLog(@"BLE已打開.");
            [self writeToLog:@"BLE已打開."];
            //添加服務(wù)
            [self setupService];
            break;

        default:
            NSLog(@"此設(shè)備不支持BLE或未打開藍(lán)牙功能,無法作為外圍設(shè)備.");
            [self writeToLog:@"此設(shè)備不支持BLE或未打開藍(lán)牙功能沸柔,無法作為外圍設(shè)備."];
            break;
    }
}
//外圍設(shè)備添加服務(wù)后調(diào)用
-(void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error{
    if (error) {
        NSLog(@"向外圍設(shè)備添加服務(wù)失敗循衰,錯誤詳情:%@",error.localizedDescription);
        [self writeToLog:[NSString stringWithFormat:@"向外圍設(shè)備添加服務(wù)失敗,錯誤詳情:%@",error.localizedDescription]];
        return;
    }

    //添加服務(wù)后開始廣播
    NSDictionary *dic=@{CBAdvertisementDataLocalNameKey:kPeripheralName};//廣播設(shè)置
    [self.peripheralManager startAdvertising:dic];//開始廣播
    NSLog(@"向外圍設(shè)備添加了服務(wù)并開始廣播...");
    [self writeToLog:@"向外圍設(shè)備添加了服務(wù)并開始廣播..."];
}
-(void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error{
    if (error) {
        NSLog(@"啟動廣播過程中發(fā)生錯誤褐澎,錯誤信息:%@",error.localizedDescription);
        [self writeToLog:[NSString stringWithFormat:@"啟動廣播過程中發(fā)生錯誤会钝,錯誤信息:%@",error.localizedDescription]];
        return;
    }
    NSLog(@"啟動廣播...");
    [self writeToLog:@"啟動廣播..."];
}
//訂閱特征
-(void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic{
    NSLog(@"中心設(shè)備:%@ 已訂閱特征:%@.",central,characteristic);
    [self writeToLog:[NSString stringWithFormat:@"中心設(shè)備:%@ 已訂閱特征:%@.",central.identifier.UUIDString,characteristic.UUID]];
    //發(fā)現(xiàn)中心設(shè)備并存儲
    if (![self.centralM containsObject:central]) {
        [self.centralM addObject:central];
    }
    /*中心設(shè)備訂閱成功后外圍設(shè)備可以更新特征值發(fā)送到中心設(shè)備,一旦更新特征值將會觸發(fā)中心設(shè)備的代理方法:
     -(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
     */

//    [self updateCharacteristicValue];
}
//取消訂閱特征
-(void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic{
    NSLog(@"didUnsubscribeFromCharacteristic");
}
-(void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(CBATTRequest *)request{
    NSLog(@"didReceiveWriteRequests");
}
-(void)peripheralManager:(CBPeripheralManager *)peripheral willRestoreState:(NSDictionary *)dict{
    NSLog(@"willRestoreState");
}
#pragma mark -屬性
-(NSMutableArray *)centralM{
    if (!_centralM) {
        _centralM=[NSMutableArray array];
    }
    return _centralM;
}

#pragma mark - 私有方法
//創(chuàng)建特征、服務(wù)并添加服務(wù)到外圍設(shè)備
-(void)setupService{
    /*1.創(chuàng)建特征*/
    //創(chuàng)建特征的UUID對象
    CBUUID *characteristicUUID=[CBUUID UUIDWithString:kCharacteristicUUID];
    //特征值
//    NSString *valueStr=kPeripheralName;
//    NSData *value=[valueStr dataUsingEncoding:NSUTF8StringEncoding];
    //創(chuàng)建特征
    /** 參數(shù)
     * uuid:特征標(biāo)識
     * properties:特征的屬性工三,例如:可通知迁酸、可寫、可讀等
     * value:特征值
     * permissions:特征的權(quán)限
     */
    CBMutableCharacteristic *characteristicM=[[CBMutableCharacteristic alloc]initWithType:characteristicUUID properties:CBCharacteristicPropertyNotify value:nil permissions:CBAttributePermissionsReadable];
    self.characteristicM=characteristicM;
//    CBMutableCharacteristic *characteristicM=[[CBMutableCharacteristic alloc]initWithType:characteristicUUID properties:CBCharacteristicPropertyRead value:nil permissions:CBAttributePermissionsReadable];
//    characteristicM.value=value;

    /*創(chuàng)建服務(wù)并且設(shè)置特征*/
    //創(chuàng)建服務(wù)UUID對象
    CBUUID *serviceUUID=[CBUUID UUIDWithString:kServiceUUID];
    //創(chuàng)建服務(wù)
    CBMutableService *serviceM=[[CBMutableService alloc]initWithType:serviceUUID primary:YES];
    //設(shè)置服務(wù)的特征
    [serviceM setCharacteristics:@[characteristicM]];

    /*將服務(wù)添加到外圍設(shè)備*/
    [self.peripheralManager addService:serviceM];
}
//更新特征值
-(void)updateCharacteristicValue{
    //特征值
    NSString *valueStr=[NSString stringWithFormat:@"%@ --%@",kPeripheralName,[NSDate   date]];
    NSData *value=[valueStr dataUsingEncoding:NSUTF8StringEncoding];
    //更新特征值
    [self.peripheralManager updateValue:value forCharacteristic:self.characteristicM onSubscribedCentrals:nil];
    [self writeToLog:[NSString stringWithFormat:@"更新特征值:%@",valueStr]];
}
/**
 *  記錄日志
 *
 *  @param info 日志信息
 */
-(void)writeToLog:(NSString *)info{
    self.log.text=[NSString stringWithFormat:@"%@\r\n%@",self.log.text,info];
}
@end

藍(lán)牙連接發(fā)送數(shù)據(jù)的流程圖

16a2962d7ce67281.png

lightblue怎么用

OTA(空中升級)

將手機作為外圍設(shè)備開發(fā)

iOS淺析藍(lán)牙設(shè)備之服務(wù)器(外圍設(shè)備)

APP被作為外設(shè)

遇到的坑

截屏2019-10-2315.57.54.png

所以得知道 設(shè)備廣播的的UUID
或者用下面代碼搜索藍(lán)牙

 [self.centralManager scanForPeripheralsWithServices:nil options:nil];

一般藍(lán)牙連接失敗我們會實現(xiàn)以下方法

// 連接失敿笳(但不包含超時奸鬓,系統(tǒng)沒有超時處理)
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
    if (error && self.delegate && [self.delegate respondsToSelector:@selector(centralTool:connectFailure:)]) {
        [self.delegate centralTool:self connectFailure:error];
    }
}

- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
    [self autoConnect];
}

但是當(dāng)廣播設(shè)備的藍(lán)牙斷開再想重連的話還要實現(xiàn)下面這個方法

- (void)peripheral:(CBPeripheral *)peripheral didModifyServices:(NSArray<CBService *> *)invalidatedServices{

    [self.centralManager connectPeripheral:peripheral options:nil];
      // 注意保留 Peripheral 的引用
    self.lastConnectedPeripheral = peripheral;
    [self startTimer];
}

只有這樣才能實現(xiàn)斷開藍(lán)牙重開藍(lán)牙秒連

另外,有時候要提高搜索效率的話,可以過濾藍(lán)牙的名字

    NSString *name = peripheral.name;
       if (name.length == 0) {
           return;
       }
       NSLog(@"name ===  %@",name);
       
       NSString *string = [NSString stringWithFormat:@"已發(fā)現(xiàn) peripheral: %@ rssi: %@, UUID: %@ advertisementData: %@ ", peripheral, RSSI, peripheral.identifier, advertisementData];
       NSLog(@"string ==  %@",string);
    


       if ([name rangeOfString:@"Berry"].location == NSNotFound) {
           return;
       }
    
   
//    NSString *kCBAdvDataLocalName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
//    if ([kCBAdvDataLocalName rangeOfString:@"Berry"].location == NSNotFound) {
//             return;
//         }

不過要注意 上文代碼中的name 和 kCBAdvDataLocalName 是不同的
一個是藍(lán)牙設(shè)備的名字, 一個是廣播的名字

//添加服務(wù)后開始廣播
//廣播設(shè)置
    NSDictionary *dic=@{CBAdvertisementDataLocalNameKey:MyDeviceName,CBAdvertisementDataServiceUUIDsKey:@[[CBUUID UUIDWithString:@"FFE0"]]};
//廣播設(shè)置
    [self.peripheralManager startAdvertising:dic];//開始廣播

第一個坑中設(shè)置UUID找不到的問題就是,需要在上述代碼中設(shè)置UUID
網(wǎng)上找的大部分資料都是關(guān)于如何設(shè)置中心設(shè)備的,外設(shè)的比較少,所以這里容易出錯

不過,如果這塊都設(shè)置了,對于快速精準(zhǔn)找到目標(biāo)藍(lán)牙服務(wù)是大有裨益的,也會減少耗電量,提高響應(yīng)速度等等。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末掸读,一起剝皮案震驚了整個濱河市全蝶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌寺枉,老刑警劉巖抑淫,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異姥闪,居然都是意外死亡始苇,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門筐喳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來催式,“玉大人,你說我怎么就攤上這事避归∪僭拢” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵梳毙,是天一觀的道長哺窄。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么萌业? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任坷襟,我火速辦了婚禮,結(jié)果婚禮上生年,老公的妹妹穿的比我還像新娘婴程。我一直安慰自己,他們只是感情好抱婉,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布档叔。 她就那樣靜靜地躺著,像睡著了一般蒸绩。 火紅的嫁衣襯著肌膚如雪衙四。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天侵贵,我揣著相機與錄音届搁,去河邊找鬼缘薛。 笑死窍育,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的宴胧。 我是一名探鬼主播漱抓,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼恕齐!你這毒婦竟也來了乞娄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤显歧,失蹤者是張志新(化名)和其女友劉穎仪或,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體士骤,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡范删,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了拷肌。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片到旦。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖巨缘,靈堂內(nèi)的尸體忽然破棺而出添忘,到底是詐尸還是另有隱情,我是刑警寧澤若锁,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布搁骑,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏靶病。R本人自食惡果不足惜会通,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望娄周。 院中可真熱鬧涕侈,春花似錦、人聲如沸煤辨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽众辨。三九已至端三,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鹃彻,已是汗流浹背郊闯。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蛛株,地道東北人团赁。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像谨履,于是被迫代替她去往敵國和親欢摄。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容