Android 定位(GPS為主) 筆記

一概覽

0.概念
GPS是英文Global Positioning System(全球定位系統(tǒng))的簡稱。
GNSS全球?qū)Ш叫l(wèi)星系統(tǒng)(Global Navigation Satellite System)邑滨,它是泛指所有的衛(wèi)星導(dǎo)航系統(tǒng)身堡,包括全球的绵脯、區(qū)域的和增強(qiáng)的。

1.定位方式
(1)GPS_PROVIDER:通過 GPS 來獲取地理位置的經(jīng)緯度信息;
優(yōu)點(diǎn):獲取地理位置信息精確度高嫌套;
缺點(diǎn):只能在戶外使用,獲取經(jīng)緯度信息耗時圾旨,耗電踱讨;

(2)NETWORK_PROVIDER:通過移動網(wǎng)絡(luò)的基站或者 Wi-Fi 來獲取地理位置;
優(yōu)點(diǎn):只要有網(wǎng)絡(luò)碳胳,就可以快速定位勇蝙,室內(nèi)室外都可;
缺點(diǎn):精確度不高挨约;

(3)PASSIVE_PROVIDER:被動接收更新地理位置信息味混,而不用自己請求地理位置信息。 PASSIVE_PROVIDER 返回的位置是通過其他 providers 產(chǎn)生的诫惭,可以查詢 getProvider() 方法決定位置更新的由來翁锡,需要 ACCESS_FINE_LOCATION 權(quán)限,但是如果未啟用 GPS夕土,則此 provider 可能只返回粗略位置匹配馆衔;

2.版本差異與權(quán)限
權(quán)限
(1)ACCESS_FINE_LOCATION是精確位置瘟判,如果使用GPS_PROVIDER或者同時使用GPS_PROVIDER和NETWORK_PROVIDER,需聲明該權(quán)限角溃,它對于這兩個provider都是有效的拷获;
(2)ACCESS_COARSE_LOCATION是粗略位置,該權(quán)限只針對NETWORK_PROVIDER减细。
版本差異
Android 6.0 以上動態(tài)申請權(quán)限
Android 7.0 以上 可以獲取GPS原始數(shù)據(jù)匆瓜。

二、代碼相關(guān)

2.0 權(quán)限檢查

       if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
             Log.i(TAG, "startLocationClient checkSelfPermission return");
            return;
       }

GPS是否開啟

   boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
     if (!gpsEnabled) {
        //檢測gps 開啟狀態(tài)
          Log.i(TAG, "gpsEnabled  " + gpsEnabled);
          Intent settingsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
          settingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
          startActivity(settingsIntent);
     }

2.1 搜星判斷

GPS 首次通信非常耗時未蝌,所以很多時候可能請求不到坐標(biāo)驮吱。可以側(cè)面從有效衛(wèi)星數(shù)量來判斷是室內(nèi)外萧吠。

  LocationManager  locationManager = (LocationManager) getSystemService(Context.
            LOCATION_SERVICE);
  locationManager.addGpsStatusListener(statusListener);


private static int STAR_MAX_SNR = 50;//搜星最大有效snr 上限
private static int STAR_MIN_SNR = 30;//最低有效snr 下限
private static int MIN_STAR_NUM = 4;//最低有效衛(wèi)星數(shù)量
private ArrayList<GpsSatellite> numSatelliteList = new ArrayList();//有效搜星數(shù)量


private final GpsStatus.Listener statusListener = new GpsStatus.Listener() {
    public void onGpsStatusChanged(int event) {// GPS狀態(tài)變化時的回調(diào)左冬,獲取當(dāng)前狀態(tài)

        if (ActivityCompat.checkSelfPermission(LocationServiceGPS.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(LocationServiceGPS.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        if (locationManager != null) {
            GpsStatus status = locationManager.getGpsStatus(null);
            // 獲取衛(wèi)星狀態(tài)相關(guān)數(shù)據(jù)  判斷 室內(nèi)還是室外
            GetGPSStatus(event, status);
        }

    }
};


/**
 * @param event
 * @param status
 */

private void GetGPSStatus(final int event, final GpsStatus status) {

    ThreadPoolProxyFactory.getNormalThreadPoolProxy().execute(new Runnable() {
        @Override
        public void run() {

            if (status == null) {

            } else if (event == GpsStatus.GPS_EVENT_SATELLITE_STATUS) {
                //   獲取最大的衛(wèi)星數(shù)(這個只是一個預(yù)設(shè)值)
                int maxSatellites = status.getMaxSatellites();
                Iterator<GpsSatellite> it = status.getSatellites().iterator();
                numSatelliteList.clear();

                int count = 0;
                while (it.hasNext() && count <= maxSatellites) {
                    GpsSatellite s = it.next();
                    if (s.getSnr() >= STAR_MIN_SNR && s.getSnr() <= STAR_MAX_SNR) {//
                        //只有信躁比不為0的時候才算搜到了星 此處統(tǒng)計SNR在30-50間的衛(wèi)星數(shù), 重要: 需要清除星歷 重測 冷啟動
                        numSatelliteList.add(s);
                        //  SCLog.i(TAG, "s.getSnr()" + " snr--- " + s.getSnr());
                        count++;
                    }

                }
                if (numSatelliteList.size() >= MIN_STAR_NUM) {
                    Log.i(TAG, "updateGpsStatus----numSatelliteList.size() >= 4 numSatelliteList.size()= " + numSatelliteList.size());
                    //todo 此處判斷搜星結(jié)果 為有效信號
           
                }
            } else if (event == GpsStatus.GPS_EVENT_STARTED) {
                Log.i(TAG, "updateGpsStatus----GPS_EVENT_STARTED=");
                //定位啟動
            } else if (event == GpsStatus.GPS_EVENT_STOPPED) {
                //定位結(jié)束
                Log.i(TAG, "updateGpsStatus----GPS_EVENT_STOPPED=");
            }
        }
    });

}

2.2 坐標(biāo)獲取

變量

private LocationManager locationManager;
private String provider = LocationManager.GPS_PROVIDER;//定位提供者
private long minTime = 1000;//最小間隔時間

方法

locationManager.requestLocationUpdates(provider, minTime * 2, 5, locationListener2);

requestLocationUpdates方法四個參數(shù)分別為纸型,位置提供者類型拇砰,最小間隔時間(毫秒),最小間隔距離(米)绊袋,位置變化回調(diào)

 /**
 * 這個 只用來監(jiān)聽狀態(tài) 定位請求交給 主動 realyRequest
 */
private final LocationListener locationListener2 = new LocationListener() {
    public void onLocationChanged(Location location) {
        //當(dāng)坐標(biāo)改變時觸發(fā)此函數(shù)毕匀,如果Provider傳進(jìn)相同的坐標(biāo),它就不會被觸發(fā)
        Log.i(TAG, "LocationListener  onLocationChanged");
        updateToNewLocation(location);
    }

    public void onProviderDisabled(String provider) {
        //Provider被disable時觸發(fā)此函數(shù)癌别,比如GPS被關(guān)閉
        Log.i(TAG, "LocationListener  onProviderDisabled");
    }

    public void onProviderEnabled(String provider) {
         // Provider被enable時觸發(fā)此函數(shù)皂岔,比如GPS被打開
          Log.i(TAG, "LocationListener  onProviderEnabled");
    }

    public void onStatusChanged(String provider, int status, Bundle extras) {
        //  extras   provider的一些設(shè)置參數(shù)(如高精度、低功耗等)
        // Provider的轉(zhuǎn)態(tài)在可用展姐、暫時不可用和無服務(wù)三個狀態(tài)直接切換時觸發(fā)此函數(shù)
        switch (status) {
 //                Provider的轉(zhuǎn)態(tài)
            case LocationProvider.AVAILABLE:
                Log.i(TAG, "LocationListener  onStatusChanged  LocationProvider.AVAILABLE");

                break;
            case LocationProvider.OUT_OF_SERVICE:
                Log.i(TAG, "LocationListener  onStatusChanged   .LocationProvider.OUT_OF_SERVICE");
                Pair state = new Pair(RESULT_STATE_GPS_ERR, "GPS OUT_OF_SERVICE");

                if (gpsCallBack != null) {
                    gpsCallBack.onReceiverStateInfo(state);
                }
                break;
            case LocationProvider.TEMPORARILY_UNAVAILABLE:
                Log.i(TAG, "LocationListener  onStatusChanged   .LocationProvider.TEMPORARILY_UNAVAILABLE");
                Pair state2 = new Pair(RESULT_STATE_GPS_ERR, "GPS 暫不可用");
                if (gpsCallBack != null) {
    //   gpsCallBack 是傳遞狀態(tài)結(jié)果的接口
                    gpsCallBack.onReceiverStateInfo(state2);
                }
                break;
        }
    }
};

至于很多誤導(dǎo)人的操作請求是

 Location newLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

這個是上次獲取的已知坐標(biāo)躁垛,可能是很久之前的其實(shí)沒有意義。

可以從收到的坐標(biāo)中獲取精度最高的圾笨,同時做超時控制判斷每隔一定時間獲取精度最高點(diǎn)上報教馆,最后移除listeners

/**
 * 移除監(jiān)聽
 */
private void removeListeners() {

    if (locationManager != null) {
        Log.i(TAG, "removeListeners----removeListeners");
        // 關(guān)閉程序時將監(jiān)聽器移除
        locationManager.removeUpdates(locationListener2);
        locationManager.removeGpsStatusListener(statusListener);
        locationManager = null;
    }
}

三、一些筆記

1.實(shí)測requestLocationUpdates要配合getLastKnownLocation一起使用擂达,效果會更好土铺。
2.GPS的精度問題

 location.hasAccuracy() 判斷然后location.getAccuracy()獲取。

官方API中提到


image.png

我理解是 以收到坐標(biāo)信息為原點(diǎn)板鬓,以精度值為半徑悲敷,真實(shí)位置在該圓內(nèi)的概率是68%。

四俭令、LocationManager

LocationManager 分析

除了上文的添加GpsStatusListener

    mLocationManager.addGpsStatusListener(statusListener)
    mLocationManager.addNmeaListener(nmeaListener);
    mLocationManager.registerGnssMeasurementsCallback(gnssMeasurementEventListener);
    mLocationManager.registerGnssStatusCallback(gnssStatucallback);
    mLocationManager.registerGnssNavigationMessageCallback(gnssNavigationMessageCallback);

1. addNmeaListener

    mLocationManager.addNmeaListener(nmeaListener);

    private final  GpsStatus.NmeaListener nmeaListener =new GpsStatus.NmeaListener() {
    @Override
    public void onNmeaReceived(long timestamp, String nmea) {

    }
};
  • NMEA 0183是用于與船用電子設(shè)備通信的標(biāo)準(zhǔn),通過此方法獲取GPS引擎接收NMEA數(shù)據(jù)后德。

2.registerGnssStatusCallback

GNSS 狀態(tài)回調(diào)
mLocationManager.registerGnssStatusCallback(gnssStatucallback);

  private GnssStatus.Callback gnssStatucallback =new GnssStatus.Callback() {
    /**
     * Called when GNSS system has started.
     */
    public void onStarted() {}

    /**
     * Called when GNSS system has stopped.
     */
    public void onStopped() {}

    /**
     * Called when the GNSS system has received its first fix since starting.
     * @param ttffMillis the time from start to first fix in milliseconds.
     */
    public void onFirstFix(int ttffMillis) {}

    /**
     * Called periodically to report GNSS satellite status.
     * @param status the current status of all satellites.
     */
    public void onSatelliteStatusChanged(GnssStatus status) {}
};

英語也很簡單,很直白就不翻譯了抄腔。

3.registerGnssNavigationMessageCallback

Used for receiving GNSS satellite Navigation Messages from the GNSS engine.
用于從GNSS引擎接收GNSS衛(wèi)星消息瓢湃。(一般用不到)

  mLocationManager.registerGnssNavigationMessageCallback(gnssNavigationMessageCallback);

     private final GnssNavigationMessage.Callback gnssNavigationMessageCallback=new GnssNavigationMessage.Callback() {
    @Override
    public void onGnssNavigationMessageReceived(GnssNavigationMessage event) {  
   //返回最新收集的GNSS消息理张。
        super.onGnssNavigationMessageReceived(event);
    }

    @Override
    public void onStatusChanged(int status) {
       //返回GNSS導(dǎo)航系統(tǒng)的最新狀態(tài)。
        super.onStatusChanged(status);
    }
};

4.registerGnssMeasurementsCallback

注冊GPS測量回調(diào)绵患。

   mLocationManager.registerGnssMeasurementsCallback(gnssMeasurementEventListener);
    private final GnssMeasurementsEvent.Callback gnssMeasurementEventListener =
        new GnssMeasurementsEvent.Callback() {
            @Override
            public void onGnssMeasurementsReceived(GnssMeasurementsEvent eventArgs) {
                super.onGnssMeasurementsReceived(eventArgs);
                //這里我們獲取到了回調(diào)的測量數(shù)據(jù)容器:GnssMeasurementsEvent eventArgs
                  onGnssMeasurementsReceived(eventArgs);
         
            }

            @Override
            public void onStatusChanged(int status) {
                super.onStatusChanged(status);
            }
        };

五 GNSS

Android 7.0 以后官方推薦使用GNSS 雾叭。

1.GnssMeasurementsEvent

gnss 的測量數(shù)據(jù)mLocationManager.registerGnssMeasurementsCallback(gnssMeasurementEventListener)回調(diào)接受的數(shù)據(jù)
成員變量

private final GnssClock mClock;//時鐘 
private final Collection<GnssMeasurement> mReadOnlyMeasurements;//測量數(shù)據(jù)

參見Android 獲取GNSS原始數(shù)據(jù)

獲取辦法

   private void onGnssMeasurementsReceived(GnssMeasurementsEvent event) {
    StringBuilder builder=new StringBuilder("GNSS測量數(shù)據(jù):\n\n");
    //這里的toStringClock和toStringMeasurement將寫在下一步里
    builder.append(toStringClock(event.getClock()));//寫入gnss時鐘的數(shù)據(jù)
    builder.append("\n");

    for (GnssMeasurement measurement : event.getMeasurements()) {
        builder.append(toStringMeasurement(measurement));//寫入gnss測量數(shù)據(jù)
        builder.append("\n");
    }
    
  }

  private String toStringClock(GnssClock gnssClock){
    //將GPS接收器時鐘的值轉(zhuǎn)換為字符串
    final String format = "   %-4s = %s\n";//定義數(shù)據(jù)顯示格式,“%-4”表示左對齊藏雏、不足四位補(bǔ)足四位
    StringBuilder builder=new StringBuilder("GNSS時鐘:\n");
    DecimalFormat numberFormat = new DecimalFormat("#0.000");//定義格式化數(shù)字


    if (gnssClock.hasLeapSecond()) {
        //如果閏秒存在則顯示閏秒
        builder.append(String.format(format, "閏秒(LeapSecond)", gnssClock.getLeapSecond()));
    }
    builder.append(String.format(format, "硬件時鐘(TimeNanos)", gnssClock.getTimeNanos()));//獲取以毫秒為單位的GNSS接收器內(nèi)部硬件時鐘值
    if (gnssClock.hasTimeUncertaintyNanos()) {
        //獲取硬件時鐘的誤差估計(不確定度)
        builder.append(String.format(format, "時鐘誤差估計(TimeUncertaintyNanos)", gnssClock.getTimeUncertaintyNanos()));
    }

    if (gnssClock.hasFullBiasNanos()) {
        //如果存在接收機(jī)本地時鐘總偏差拷况,則顯示
        builder.append(String.format(format, "總時鐘偏差(FullBiasNanos)", gnssClock.getFullBiasNanos()));
    }
    if (gnssClock.hasBiasNanos()) {
        //亞納秒偏差
        builder.append(String.format(format, "亞偏差(BiasNanos)", gnssClock.getBiasNanos()));
    }
    if (gnssClock.hasBiasUncertaintyNanos()) {
        //FullBiasNanos和BiasNanos的誤差估計
        builder.append(String.format(format, "時鐘偏差估計(BiasUncertaintyNanos)", numberFormat.format(gnssClock.getBiasUncertaintyNanos())));
    }
    /**
     * 注意:以上五個數(shù)據(jù)用于計算GPS時鐘
     * 具體計算方法為:local estimate of GPS time = TimeNanos - (FullBiasNanos + BiasNanos)
     *     世界標(biāo)準(zhǔn)時:UtcTimeNanos = TimeNanos - (FullBiasNanos + BiasNanos) - LeapSecond * 1,000,000,000
     */
    if (gnssClock.hasDriftNanosPerSecond()) {
        //以每秒納秒為單位獲取時鐘的漂移
        builder.append(String.format(format, "時鐘漂移(DriftNanosPerSecond)", numberFormat.format(gnssClock.getDriftNanosPerSecond())));
    }
    if (gnssClock.hasDriftUncertaintyNanosPerSecond()) {
        //時鐘偏差的估計
        builder.append(String.format(format, "時鐘漂移估計(DriftUncertaintyNanosPerSecond)", numberFormat.format(gnssClock.getDriftUncertaintyNanosPerSecond())));
    }
    //獲取硬件時鐘不連續(xù)的計數(shù),即:每當(dāng)gnssclock中斷時,該值+1
    builder.append(String.format(format, "中斷計數(shù)(HardwareClockDiscontinuityCount)", gnssClock.getHardwareClockDiscontinuityCount()));
    return builder.toString();
}


private String toStringMeasurement(GnssMeasurement measurement){
    //將GNSS測量結(jié)果轉(zhuǎn)換為字符串
    //定義顯示格式
    final String format = "   %-4s = %s\n";
    StringBuilder builder = new StringBuilder("GNSS測量結(jié)果:\n");
    DecimalFormat numberFormat = new DecimalFormat("#0.000");
    DecimalFormat numberFormat1 = new DecimalFormat("#0.000E00");

    //獲取衛(wèi)星ID
    /**
     * 取決于衛(wèi)星類型
     * GPS:1-32
     * SBAS:120-151掘殴、183-192
     * GLONASS:OSN或FCN + 100之一
     * 1-24作為軌道槽號(OSN)(首選,如果知道)
     * 93-106作為頻道號(FCN)(-7至+6)加100粟誓。即將-7的FCN編碼為93奏寨,0編碼為100,+ 6編碼為106
     * QZSS:193-200
     * 伽利略:1-36
     * 北斗:1-37
     */
    builder.append(String.format(format, "衛(wèi)星ID", measurement.getSvid()));

    //獲取衛(wèi)星類型
    /**
     *  1:CONSTELLATION_GPS 使用GPS定位
     *  2:CONSTELLATION_SBAS 使用SBAS定位
     *  3:CONSTELLATION_GLONASS 使用格洛納斯定位
     *  4:CONSTELLATION_QZSS 使用QZSS定位
     *  5:CONSTELLATION_BEIDOU 使用北斗定位 (^-^)!
     *  6:CONSTELLATION_GALILEO 使用伽利略定位
     *  7:CONSTELLATION_IRNSS 使用印度區(qū)域衛(wèi)星定位
     */
    builder.append(String.format(format, "衛(wèi)星類型", measurement.getConstellationType()));

    //獲取進(jìn)行測量的時間偏移量(以納秒為單位)
    builder.append(String.format(format, "測量時間偏移量", measurement.getTimeOffsetNanos()));

    //獲取每個衛(wèi)星的同步狀態(tài)
    //具體數(shù)值含義請查表
    builder.append(String.format(format, "同步狀態(tài)", measurement.getState()));

    //獲取時間戳的偽距速率鹰服,以m/s為單位
    builder.append(String.format(format, "偽距速率", numberFormat.format(measurement.getPseudorangeRateMetersPerSecond())));
    //獲取偽距的速率不確定性(1-Sigma)病瞳,以m/s為單位
    builder.append(String.format(format, "偽距速率不確定度", numberFormat.format(measurement.getPseudorangeRateUncertaintyMetersPerSecond())));
    //
    if (measurement.getAccumulatedDeltaRangeState() != 0) {
        // 獲取“累積增量范圍”狀態(tài)
        // 返回:MULTIPATH_INDICATOR_UNKNOWN(指示器不可用)=0
        // notice 即:指示器可用時,收集數(shù)據(jù)
        builder.append(
                String.format(format, "累積增量范圍狀態(tài)", measurement.getAccumulatedDeltaRangeState()));

        //獲取自上次重置通道以來的累積增量范圍悲酷,以米為單位.
        //該值僅在上面的state值為“可用”時有效
        //notice 累積增量范圍= -k * 載波相位(其中k為常數(shù))
        builder.append(String.format(format, "累積增量范圍", numberFormat.format(measurement.getAccumulatedDeltaRangeMeters())));

        //獲取以米為單位的累積增量范圍的不確定性(1-Sigma)
        builder.append(String.format(format, "累積增量范圍不確定度", numberFormat1.format(measurement.getAccumulatedDeltaRangeUncertaintyMeters())));
    }

    if (measurement.hasCarrierFrequencyHz()) {
        //獲取被跟蹤信號的載波頻率
        builder.append(String.format(format, "信號載波頻率", measurement.getCarrierFrequencyHz()));
    }

    if (measurement.hasCarrierCycles()) {
        //衛(wèi)星和接收器之間的完整載波周期數(shù)
        builder.append(String.format(format, "載波周期數(shù)", measurement.getCarrierCycles()));
    }

    if (measurement.hasCarrierPhase()) {
        //獲取接收器檢測到的RF相位
        builder.append(String.format(format, "RF相位", measurement.getCarrierPhase()));
    }

    if (measurement.hasCarrierPhaseUncertainty()) {
        //誤差估計
        builder.append(String.format(format, "RF相位不確定度", measurement.getCarrierPhaseUncertainty()));
    }

    //獲取一個值套菜,該值指示事件的“多路徑”狀態(tài),返回0或1或2
    //MULTIPATH_INDICATOR_DETECTED = 1 測量顯示有“多路徑效應(yīng)”跡象
    // MULTIPATH_INDICATOR_NOT_DETECTED = 2 測量結(jié)果顯示沒有“多路徑效應(yīng)”跡象
    builder.append(String.format(format, "多路經(jīng)效應(yīng)指示器", measurement.getMultipathIndicator()));

    //
    if (measurement.hasSnrInDb()) {
        //獲取信噪比(SNR),以dB為單位
        builder.append(String.format(format, "信噪比", measurement.getSnrInDb()));
    }

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        if (measurement.hasAutomaticGainControlLevelDb()) {
            //獲取以dB為單位的自動增益控制級別
            builder.append(String.format(format, "自動增益控制級別", measurement.getAutomaticGainControlLevelDb()));
        }
        if (measurement.hasCarrierFrequencyHz()) {
            builder.append(String.format(format, "載波頻率", measurement.getCarrierFrequencyHz()));
        }
    }
    return builder.toString();

}

2.GnssNavigationMessage

GNSS satellite Navigation Message.GNSS衛(wèi)星導(dǎo)航消息设易。
其中event.getData()二進(jìn)制數(shù)據(jù)可以按照ICD協(xié)議文件(GPS接口控制文件)逐子幀解碼出衛(wèi)星運(yùn)行軌道參數(shù)逗柴、衛(wèi)星 鐘改正參數(shù)、電離層延遲改正參數(shù)等數(shù)據(jù)用于導(dǎo)航與定位顿肺。
絕大多數(shù)應(yīng)用層開發(fā)無實(shí)際意義戏溺。

3.GnssStatus

mLocationManager.registerGnssStatusCallback(gnssStatucallback)回調(diào)中接收到的數(shù)據(jù)。
status.getSatelliteCount()來獲取衛(wèi)星數(shù)屠尊。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末旷祸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子讼昆,更是在濱河造成了極大的恐慌托享,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,599評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浸赫,死亡現(xiàn)場離奇詭異闰围,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)掺炭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評論 3 385
  • 文/潘曉璐 我一進(jìn)店門辫诅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人涧狮,你說我怎么就攤上這事炕矮∶捶颍” “怎么了?”我有些...
    開封第一講書人閱讀 158,084評論 0 348
  • 文/不壞的土叔 我叫張陵肤视,是天一觀的道長档痪。 經(jīng)常有香客問我,道長邢滑,這世上最難降的妖魔是什么腐螟? 我笑而不...
    開封第一講書人閱讀 56,708評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮困后,結(jié)果婚禮上乐纸,老公的妹妹穿的比我還像新娘。我一直安慰自己摇予,他們只是感情好汽绢,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,813評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著侧戴,像睡著了一般宁昭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上酗宋,一...
    開封第一講書人閱讀 50,021評論 1 291
  • 那天积仗,我揣著相機(jī)與錄音,去河邊找鬼蜕猫。 笑死寂曹,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的丹锹。 我是一名探鬼主播稀颁,決...
    沈念sama閱讀 39,120評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼楣黍!你這毒婦竟也來了布蔗?” 一聲冷哼從身側(cè)響起轨香,我...
    開封第一講書人閱讀 37,866評論 0 268
  • 序言:老撾萬榮一對情侶失蹤占遥,失蹤者是張志新(化名)和其女友劉穎喊儡,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體哩治,經(jīng)...
    沈念sama閱讀 44,308評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡秃踩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,633評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了业筏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片憔杨。...
    茶點(diǎn)故事閱讀 38,768評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蒜胖,靈堂內(nèi)的尸體忽然破棺而出消别,到底是詐尸還是另有隱情抛蚤,我是刑警寧澤,帶...
    沈念sama閱讀 34,461評論 4 333
  • 正文 年R本政府宣布寻狂,位于F島的核電站岁经,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蛇券。R本人自食惡果不足惜缀壤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,094評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望纠亚。 院中可真熱鬧塘慕,春花似錦、人聲如沸蒂胞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽啤誊。三九已至,卻和暖如春拥娄,著一層夾襖步出監(jiān)牢的瞬間蚊锹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評論 1 267
  • 我被黑心中介騙來泰國打工稚瘾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留牡昆,地道東北人。 一個月前我還...
    沈念sama閱讀 46,571評論 2 362
  • 正文 我出身青樓摊欠,卻偏偏與公主長得像丢烘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子些椒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,666評論 2 350