android permission權(quán)限與安全機制解析(下)

<p>  剛建了一個QQ群,感興趣的大家一起多多交流:544645972

  在<a >android permission權(quán)限與安全機制解析(上)</a>篇博客中果漾,我已經(jīng)詳細介紹了android相關(guān)系統(tǒng)permission和自定義permission奏路,以及一些權(quán)限機制和安全機制锣披。這篇博客主要將會介紹到<strong>android 6.0的相關(guān)權(quán)限更改箍邮,原理和相關(guān)的處理方式酿炸,解決方法</strong>等恋博。

  就以我以前的一個<a >仿最新版微信相冊</a>為例子來分析齐佳。</p>

<h1 id="android-60權(quán)限全面詳細分析和解決方案"><strong>android 6.0權(quán)限全面詳細分析和解決方案</strong></h1>

<h2 id="marshmallow版本權(quán)限修改"><strong>Marshmallow版本權(quán)限修改</strong></h2>

<p>  android的權(quán)限系統(tǒng)一直是首要的安全概念,因為這些權(quán)限只在安裝的時候被詢問一次债沮。一旦安裝了炼吴,app可以在用戶毫不知曉的情況下訪問權(quán)限內(nèi)的所有東西,而且一般用戶安裝的時候很少會去仔細看權(quán)限列表疫衩,更不會去深入了解這些權(quán)限可能帶來的相關(guān)危害硅蹦。所以在android 6.0 Marshmallow版本之后,系統(tǒng)不會在軟件安裝的時候就賦予該app所有其申請的權(quán)限闷煤,對于一些危險級別的權(quán)限童芹,app需要在運行時一個一個詢問用戶授予權(quán)限。

  

這里寫圖片描述
</p>

<h2 id="舊版本app兼容問題"><strong>舊版本app兼容問題</strong></h2>

<p>  那么問題來了曹傀,是不是所有以前發(fā)布的app都會出現(xiàn)問題呢辐脖?答案是不會,只有那些targetSdkVersion 設(shè)置為23和23以上的應用才會出現(xiàn)異常皆愉,在使用危險權(quán)限的時候系統(tǒng)必須要獲得用戶的同意才能使用嗜价,要不然應用就會崩潰,出現(xiàn)類似

java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider

的崩潰日志幕庐。所以targetSdkVersion如果沒有設(shè)置為23版本或者以上久锥,系統(tǒng)還是會使用舊規(guī)則:在安裝的時候賦予該app所申請的所有權(quán)限。所以app當然可以和以前一樣正常使用了异剥,但是還有一點需要注意的是6.0的系統(tǒng)里面瑟由,<strong>用戶可以手動將該app的權(quán)限關(guān)閉</strong>,如下圖

  

這里寫圖片描述


  那么問題又來了冤寿,雖然會彈出提示歹苦,但是如果以前的老應用申請的權(quán)限被用戶不管提示強行手動關(guān)閉了怎么辦,應用會崩潰么督怜?我們來試一試

  
這里寫圖片描述


  好吧殴瘦,可以慶幸了一下了,不會拋出異常号杠,不會崩潰蚪腋,只不過調(diào)用那些被用戶禁止權(quán)限的api接口返回值都為null或者0丰歌,所以我們只需要做一下判空操作就可以了,不判空當然還是會崩潰的嘍屉凯。</p>

<h2 id="普通權(quán)限和危險權(quán)限列表"><strong>普通權(quán)限和危險權(quán)限列表</strong></h2>

<p>  現(xiàn)在對于新版本的權(quán)限變更應該有了基本的認識立帖,那么,是不是所有權(quán)限都需要去進行特殊處理呢悠砚?當然不是晓勇,只有那些危險級別的權(quán)限才需要,如列表所示:

  

這里寫圖片描述


  android開發(fā)者官網(wǎng)也有相關(guān)描述:

  <a >http://developer.android.com/training/permissions/requesting.html</a>

  <a >http://developer.android.com/guide/topics/security/permissions.html#normal-dangerous</a>

  所以仔細去看看自己的app哩簿,對照列表宵蕉,如果有需要申請其中的一個權(quán)限酝静,就需要進行特殊操作节榜。還有一個比較人性的地方就是如果同一組的任何一個權(quán)限被授權(quán)了,其他權(quán)限也自動被授權(quán)别智。例如宗苍,一旦WRITE_EXTERNAL_STORAGE被授權(quán)了,app也有READ_EXTERNAL_STORAGE權(quán)限了薄榛。</p>

<h2 id="支持marshmallow新版本權(quán)限機制"><strong>支持Marshmallow新版本權(quán)限機制</strong></h2>

<p>  終于要開始支持android 6.0版本了讳窟,最先一步當然就是修改build.gradle文件中的tragetSdkVersion和compileSdkVersion成23版本,同時使用compile ‘com.android.support:appcompat-v7:23.1.1’最新v7包敞恋。

android { compileSdkVersion 23 ... defaultConfig { ... targetSdkVersion 23 ... }}...dependencies {...compile 'com.android.support:appcompat-v7:23.1.1'...

修改完后丽啡,感興趣的朋友可以直接打包在手機上測試一下,看看是不是會出現(xiàn)類似于上面我說的那些崩潰日志硬猫。

  接著下一步當然就是要修改代碼了补箍,最原始代碼,無任何處理:

private void startGetImageThread(){.... Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; ContentResolver contentResolver = getContentResolver(); //獲取jpeg和png格式的文件啸蜜,并且按照時間進行倒序 Cursor cursor = contentResolver.query(uri, null, MediaStore.Images.Media.MIME_TYPE + "=\"image/jpeg\" or " + MediaStore.Images.Media.MIME_TYPE + "=\"image/png\"", null, MediaStore.Images.Media.DATE_MODIFIED+" desc"); ....}

這段代碼需要訪問外部存儲(相冊圖片)坑雅,屬于危險級別的權(quán)限,直接使用會造成應用崩潰衬横,所以在這段代碼執(zhí)行之前我們需要進行特殊處理:

int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, CODE_FOR_WRITE_PERMISSION); return;}

寫完這段代碼之后裹粤,就會出現(xiàn)如下系統(tǒng)dialog:

  

這里寫圖片描述


  緊接著就需要去處理DENY和ALLOW的回調(diào)了,重寫onRequestPermissionsResult函數(shù):

@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == CODE_FOR_WRITE_PERMISSION){ if (permissions[0].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE) &&grantResults[0] == PackageManager.PERMISSION_GRANTED){ //用戶同意使用write startGetImageThread(); }else{ //用戶不同意蜂林,自行處理即可 finish(); } }}

好了遥诉,這樣就算是簡單初步適配完成了。</p>

<h2 id="特殊權(quán)限"><strong><a ><font color="#4FA1E0">特殊權(quán)限</font></a></strong></h2>

<p>  還有非常重要的兩個特殊權(quán)限也要著重講一下噪叙,這兩個權(quán)限很敏感矮锈,google告訴我們絕大多數(shù)應用不需要申請這兩個權(quán)限,在Android系統(tǒng)中构眯,主要有兩個:</p><ul><li>SYSTEM_ALERT_WINDOW愕难,設(shè)置懸浮窗;</li><li>WRITE_SETTINGS 修改系統(tǒng)設(shè)置</li></ul>  關(guān)于上面兩個特殊權(quán)限的授權(quán),做法是使用 startActivityForResult 啟動授權(quán)界面來完成猫缭。<p></p>

<h3 id="systemalertwindow"><strong><a ><font color="#4FA1E0">SYSTEM_ALERT_WINDOW</font></a></strong></h3>

<p>  想要實現(xiàn)一個懸浮窗葱弟,之前的解決方法很簡單,在 Manifest 文件中添加<code><uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /></code>權(quán)限猜丹,接著設(shè)置 WindowManager.LayoutParams.type 為 WindowManager.LayoutParams.TYPE_SYSTEM_ERROR 就可以了芝加。這種方法在 6.0 之前是可以的,但是在 M 版本之后射窒,會如下的錯誤:

android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@83908c9 -- permission denied for this window type

6.0之后藏杖,google 對權(quán)限的管理更加嚴格了,現(xiàn)在需要彈出懸浮框脉顿,不光要在 Manifest 中靜態(tài)申請蝌麸,而且需要進行如下的動態(tài)申請:

private static final int REQUEST_CODE = 1;private void requestAlertWindowPermission() { Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); intent.setData(Uri.parse("package:" + getPackageName())); startActivityForResult(intent, REQUEST_CODE);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE) { if (Settings.canDrawOverlays(this)) { Log.i(LOGTAG, "onActivityResult granted"); } }}

上述代碼需要注意的是</p><ul><li>使用Action Settings.ACTION_MANAGE_OVERLAY_PERMISSION 啟動隱式Intent</li><li>使用 “package:” + getPackageName() 攜帶App的包名信息</li><li>使用 Settings.canDrawOverlays 方法判斷授權(quán)結(jié)果</li></ul>  在用戶開啟相關(guān)權(quán)限之后才能使用 WindowManager.LayoutParams.TYPE_SYSTEM_ERROR ,要不然是會直接崩潰的哦。<p></p>

<h3 id="writesettings"><strong><a ><font color="#4FA1E0">WRITE_SETTINGS</font></a></strong></h3>

<p>  這個權(quán)限的用法主要是用來讀取和更改系統(tǒng)設(shè)置艾疟,和上一個權(quán)限一樣是需要先在 Manifest 中靜態(tài)注冊完之后再通過下面代碼進行動態(tài)申請:

private static final int REQUEST_CODE_WRITE_SETTINGS = 2;private void requestWriteSettings() { Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse("package:" + getPackageName())); startActivityForResult(intent, REQUEST_CODE_WRITE_SETTINGS);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE_WRITE_SETTINGS) { if (Settings.System.canWrite(this)) { Log.i(LOGTAG, "onActivityResult write settings granted"); } }}

上述代碼需要注意的是</p><ul><li>使用Action Settings.ACTION_MANAGE_WRITE_SETTINGS 啟動隱式Intent</li><li>使用 “package:” + getPackageName() 攜帶App的包名信息</li><li>使用 Settings.System.canWrite 方法檢測授權(quán)結(jié)果</li></ul><p></p>

<h2 id="packageusagestats"><strong><a ><font color="#4FA1E0">PACKAGE_USAGE_STATS</font></a></strong></h2>

<p>  這個權(quán)限需要單獨拿出來說一下来吩,API23版本添加,用來提供給應用手機相關(guān)組件的使用統(tǒng)計蔽莱,該權(quán)限也需要用戶在Setting頁面單獨授權(quán)才可使用弟疆。例如,改權(quán)限可以用來收集最近打開的應用盗冷,具體的可以看看<a ><font color="#4FA1E0">android WindowManager解析與騙取QQ密碼案例分析</font></a>怠苔。具體的使用方法是現(xiàn)在 manifest 中注冊:

<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />

注冊完之后,繼續(xù)在代碼中檢測改權(quán)限是否被允許仪糖,如果沒有柑司,去Setting頁面讓用戶手動開啟:

private boolean checkUsagePermission() { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE); int mode = 0; mode = appOps.checkOpNoThrow("android:get_usage_stats", android.os.Process.myUid(), getPackageName()); boolean granted = mode == AppOpsManager.MODE_ALLOWED; if (!granted) { Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS); startActivityForResult(intent, 1); return false; } } return true;}...@TargetApi(Build.VERSION_CODES.M)@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 1) { AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE); int mode = 0; mode = appOps.checkOpNoThrow("android:get_usage_stats", android.os.Process.myUid(), getPackageName()); boolean granted = mode == AppOpsManager.MODE_ALLOWED; if (!granted) { Toast.makeText(this, "請開啟該權(quán)限", Toast.LENGTH_SHORT).show(); } }}

這樣當改權(quán)限被用戶手動開啟之后就能夠成功使用了。</p>

<h2 id="處理不再提醒"><strong>處理不再提醒</strong></h2>

<p>  如果用戶拒絕某授權(quán)乓诽。下一次彈框帜羊,用戶會有一個“不再提醒”的選項的來防止app以后繼續(xù)請求授權(quán)。

  

這里寫圖片描述


  如果這個選項在拒絕授權(quán)前被用戶勾選了鸠天。下次為這個權(quán)限請求requestPermissions時讼育,對話框就不彈出來了,系統(tǒng)會直接回調(diào)onRequestPermissionsResult函數(shù)稠集,回調(diào)結(jié)果為最后一次用戶的選擇奶段。所以為了應對這種情況,系統(tǒng)提供了一個<a >shouldShowRequestPermissionRationale()</a>函數(shù)剥纷,這個函數(shù)的作用是幫助開發(fā)者找到需要向用戶額外解釋權(quán)限的情況痹籍,這個函數(shù):</p><ol><li>應用安裝后第一次訪問,直接返回false晦鞋;</li><li>第一次請求權(quán)限時蹲缠,用戶拒絕了棺克,下一次shouldShowRequestPermissionRationale()返回 true,這時候可以顯示一些為什么需要這個權(quán)限的說明线定;</li><li>第二次請求權(quán)限時娜谊,用戶拒絕了,并選擇了“不再提醒”的選項時:shouldShowRequestPermissionRationale()返回 false斤讥;</li><li>設(shè)備的系統(tǒng)設(shè)置中禁止當前應用獲取這個權(quán)限的授權(quán)纱皆,shouldShowRequestPermissionRationale()返回false;</li></ol><font color="red">  注意:第二次請求權(quán)限時芭商,才會有“不再提醒”的選項派草,如果用戶一直拒絕,并沒有選擇“不再提醒”的選項铛楣,下次請求權(quán)限時近迁,會繼續(xù)有“不再提醒”的選項,并且shouldShowRequestPermissionRationale()也會一直返回true蛉艾。</font>

  所以利用這個函數(shù)我們可以進行相應的優(yōu)化钳踊,針對shouldShowRequestPermissionRationale函數(shù)返回false的處理有兩種方法:<ul><li>如果應用是第一次請求該權(quán)限,則直接調(diào)用requestPermissions函數(shù)去請求權(quán)限勿侯;如果不是則代表用戶勾選了’不再提醒’,彈出dialog缴罗,告訴用戶為什么你需要該權(quán)限助琐,讓用戶自己手動開啟該權(quán)限。鏈接:<a >http://stackoverflow.com/questions/32347532/android-m-permissions-confused-on-the-usage-of-shouldshowrequestpermissionrati</a></li><li>在onRequestPermissionsResult函數(shù)中進行檢測面氓,如果返回PERMISSION_DENIED兵钮,則去調(diào)用shouldShowRequestPermissionRationale函數(shù),如果返回false代表用戶已經(jīng)禁止該權(quán)限(上面的3和4兩種情況)舌界,彈出dialog告訴用戶你需要該權(quán)限的理由掘譬,讓用戶手動打開。鏈接:<a >http://stackoverflow.com/questions/30719047/android-m-check-runtime-permission-how-to-determine-if-the-user-checked-nev</a></li></ul>  處理方法已經(jīng)有了呻拌,修改一下代碼葱轩,我這里就以第二種方案來處理了:

@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == CODE_FOR_WRITE_PERMISSION){ if (permissions[0].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE) &&grantResults[0] == PackageManager.PERMISSION_GRANTED){ //用戶同意使用write startGetImageThread(); }else{ //用戶不同意,向用戶展示該權(quán)限作用 if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { AlertDialog dialog = new AlertDialog.Builder(this) .setMessage("該相冊需要賦予訪問存儲的權(quán)限藐握,不開啟將無法正常工作靴拱!") .setPositiveButton("確定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish(); } }) .setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish(); } }).create(); dialog.show(); return; } finish(); } }}

當勾選不再提醒,并且拒絕之后猾普,彈出dialog袜炕,提醒用戶該權(quán)限的重要性:

  

這里寫圖片描述


  搞定!3跫摇偎窘!</p>

<h2 id="使用兼容庫"><strong>使用兼容庫</strong></h2>

<p>  以上的代碼在6.0版本上使用沒有問題乌助,但是在之前就有問題了,最簡單粗暴的解決方法可能就是利用Build.VERSION.SDK_INT >= 23這個判斷語句來判斷了陌知,方便的是SDK 23的v4包加入了專門類進行相關(guān)的處理:</p><ul><li>ContextCompat.checkSelfPermission()</li>被授權(quán)函數(shù)返回PERMISSION_GRANTED眷茁,否則返回PERMISSION_DENIED ,在所有版本都是如此纵诞。<li>ActivityCompat.requestPermissions()</li>這個方法在6.0之前版本調(diào)用上祈,OnRequestPermissionsResultCallback 直接被調(diào)用,帶著正確的 PERMISSION_GRANTED或者PERMISSION_DENIED浙芙。<li>ActivityCompat.shouldShowRequestPermissionRationale()</li>在6.0之前版本調(diào)用登刺,永遠返回false。</ul>  用v4包的這三方法嗡呼,完美兼容所有版本纸俭!下面是代碼:

//使用兼容庫就無需判斷系統(tǒng)版本int hasWriteContactsPermission = ContextCompat.checkSelfPermission(getApplication(), Manifest.permission.WRITE_EXTERNAL_STORAGE);if (hasWriteContactsPermission == PackageManager.PERMISSION_GRANTED) { startGetImageThread();}//需要彈出dialog讓用戶手動賦予權(quán)限else{ ActivityCompat.requestPermissions(PickOrTakeImageActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, CODE_FOR_WRITE_PERMISSION);}

onRequestPermissionsResult函數(shù)不變。后兩個方法南窗,我們也可以在Fragment中使用揍很,用v13兼容包:FragmentCompat.requestPermissions() and FragmentCompat.shouldShowRequestPermissionRationale()和activity效果一樣。</p>

<h2 id="一次請求多個權(quán)限"><strong>一次請求多個權(quán)限</strong></h2>

<p>  當然了有時候需要多個權(quán)限万伤,可以用上面方法一次請求多個權(quán)限窒悔。當然最重要的是不要忘了為每個權(quán)限檢查“不再提醒”的設(shè)置。

List<String> permissionsNeeded = new ArrayList<String>();permissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);permissionsNeeded.add(Manifest.permission.READ_CONTACTS);permissionsNeeded.add(Manifest.permission.WRITE_CONTACTS);requestPermissions(permissionsNeeded.toArray(new String[permissionsList.size()]), CODE_FOR_MULTIPLE_PERMISSION);

最后在onRequestPermissionsResult函數(shù)中一個個處理返回結(jié)果即可敌买。</p>

<h2 id="第三方庫簡化代碼"><strong>第三方庫簡化代碼</strong></h2>

<p>  當然早就有第三方庫來幫忙做這些事情了:

  Github上的開源項目 <a >PermissionHelper</a>和<a >hotchemi’s PermissionsDispatcher</a></p>

<h2 id="app處于運行狀態(tài)下被撤銷權(quán)限"><strong>APP處于運行狀態(tài)下简珠,被撤銷權(quán)限</strong></h2>

<p>  如果APP正在運行中,用戶進入設(shè)置-應用程序頁面去手動撤銷該APP權(quán)限虹钮,會出現(xiàn)什么情況呢聋庵?哈哈,系統(tǒng)又會接著彈出權(quán)限請求對話框芙粱,挺好挺好:

  

這里寫圖片描述


  這樣就沒有問題了吧O(∩_∩)O~

  <font color="red">上面的測試環(huán)境為genymotion6.0模擬器祭玉,有朋友跟我反映在6.0nexus 6p真機上會直接退出應用,所以這個應該還和測試環(huán)境有關(guān)春畔。</font></p>

<h2 id="結(jié)論建議"><strong>結(jié)論建議</strong></h2>

<p>  新運行時權(quán)限已經(jīng)在棉花糖中被使用了脱货。我們沒有退路。我們現(xiàn)在唯一能做的就是保證app適配新權(quán)限模型拐迁。欣慰的是只有少數(shù)權(quán)限需要運行時權(quán)限模型蹭劈。大多數(shù)常用的權(quán)限,例如线召,網(wǎng)絡訪問铺韧,屬于Normal Permission 在安裝時自動會授權(quán),當然你要聲明缓淹,以后無需檢查哈打。因此塔逃,只有少部分代碼你需要修改。

兩個建議:

  1.嚴肅對待新權(quán)限模型料仗。

  2.如果你代碼沒支持新權(quán)限湾盗,不要設(shè)置targetSdkVersion 23 。尤其是當你在Studio新建工程時立轧,不要忘了修改格粪!

  說一下代碼修改。這是大事氛改,如果代碼結(jié)構(gòu)被設(shè)計的不夠好帐萎,你需要一些很蛋疼的重構(gòu)。每個app都要被修正胜卤。如上所說疆导,我們沒的選擇。列出所有你需要請求權(quán)限的全部情形葛躏,如果A被授權(quán)澈段,B被拒絕,會發(fā)生什么舰攒,針對每一個情況認真處理败富。</p>

<h2 id="引用文章"><strong>引用文章</strong></h2>

<blockquote>
<p><a href="http://www.reibang.com/p/e1ab1a179fbb">http://www.reibang.com/p/e1ab1a179fbb</a>

<a >http://blog.csdn.net/yangqingqo/article/details/48371123</a>

<a >http://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en</a>

<a >http://developer.android.com/training/permissions/requesting.html</a>

<a >http://developer.android.com/guide/topics/security/permissions.html#normal-dangerous</a>

<a >http://developer.android.com/reference/android/support/v4/app/ActivityCompat.html</a>

<a >http://www.open-open.com/lib/view/open1453044042667.html</a></p>
</blockquote>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市芒率,隨后出現(xiàn)的幾起案子囤耳,更是在濱河造成了極大的恐慌,老刑警劉巖偶芍,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異德玫,居然都是意外死亡匪蟀,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門宰僧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來材彪,“玉大人,你說我怎么就攤上這事琴儿《位” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵造成,是天一觀的道長显熏。 經(jīng)常有香客問我,道長晒屎,這世上最難降的妖魔是什么喘蟆? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任缓升,我火速辦了婚禮,結(jié)果婚禮上蕴轨,老公的妹妹穿的比我還像新娘港谊。我一直安慰自己,他們只是感情好橙弱,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布歧寺。 她就那樣靜靜地躺著,像睡著了一般棘脐。 火紅的嫁衣襯著肌膚如雪斜筐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天荆残,我揣著相機與錄音奴艾,去河邊找鬼。 笑死内斯,一個胖子當著我的面吹牛蕴潦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播俘闯,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼潭苞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了真朗?” 一聲冷哼從身側(cè)響起此疹,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎遮婶,沒想到半個月后蝗碎,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡旗扑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年蹦骑,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片臀防。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡眠菇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出袱衷,到底是詐尸還是另有隱情捎废,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布致燥,位于F島的核電站登疗,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏篡悟。R本人自食惡果不足惜谜叹,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一匾寝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧荷腊,春花似錦艳悔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至疾忍,卻和暖如春乔外,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背一罩。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工杨幼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人聂渊。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓差购,卻偏偏與公主長得像,于是被迫代替她去往敵國和親汉嗽。 傳聞我的和親對象是個殘疾皇子欲逃,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

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