Android targetSdkVersion 從22提到25 你需要知道的一切

本篇文章已授權(quán)微信公眾號(hào) guolin_blog (郭霖)獨(dú)家發(fā)布

Android 6.0

  • 運(yùn)行時(shí)權(quán)限

相機(jī)缘回,圖庫(kù)剂公,下載颜武,語(yǔ)音,定位....
此版本引入了一種新的權(quán)限模式香璃,如今同云,用戶(hù)可直接在運(yùn)行時(shí)管理應(yīng)用權(quán)限禁偎。這種模式讓用戶(hù)能夠更好地了解和控制權(quán)限,同時(shí)為應(yīng)用開(kāi)發(fā)者精簡(jiǎn)了安裝和自動(dòng)更新過(guò)程。用戶(hù)可為所安裝的各個(gè)應(yīng)用分別授予或撤銷(xiāo)權(quán)限痪伦。
對(duì)于以 Android 6.0(API 級(jí)別 23)或更高版本為目標(biāo)平臺(tái)的應(yīng)用涣达,請(qǐng)務(wù)必在運(yùn)行時(shí)檢查和請(qǐng)求權(quán)限寇窑。要確定您的應(yīng)用是否已被授予權(quán)限,請(qǐng)調(diào)用新增的 checkSelfPermission()方法无午。要請(qǐng)求權(quán)限梦皮,請(qǐng)調(diào)用新增的requestPermissions() 方法牡借。即使您的應(yīng)用并不以 Android 6.0(API 級(jí)別 23)為目標(biāo)平臺(tái)沈矿,您也應(yīng)該在新權(quán)限模式下測(cè)試您的應(yīng)用醒颖。如需了解有關(guān)在您的應(yīng)用中支持新權(quán)限模式的詳情榛丢,請(qǐng)參閱使用系統(tǒng)權(quán)限。如需了解有關(guān)如何評(píng)估新模式對(duì)應(yīng)用的影響的提示挺庞,請(qǐng)參閱權(quán)限最佳做法晰赞。
權(quán)限管理工具類(lèi)

package cn.loveshow.live.util;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;

import java.util.ArrayList;
import java.util.Arrays;


/**
 * Created by Fungo_Xiaoke on 2017/5/4 14:18.
 * eamil:luoxiaoke@yuntutv.net
 * 權(quán)限工具類(lèi)
 */
public class PermissionUtils {


/**
 * @param context     上下文
 * @param activity    activity
 * @param permissions 權(quán)限數(shù)組
 * @param requestCode 申請(qǐng)碼
 * @return true 有權(quán)限  false 無(wú)權(quán)限
 */
public static boolean checkAndApplyfPermissionActivity(Activity activity, String[] permissions, int requestCode) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        permissions = checkPermissions(activity, permissions);
        if (permissions != null && permissions.length > 0) {
            ActivityCompat.requestPermissions(activity, permissions, requestCode);
            return false;
        } else {
            return true;
        }
    } else {
        return true;
    }
}

/**
 * @param context     上下文
 * @param mFragment   fragment
 * @param permissions 權(quán)限數(shù)組
 * @param requestCode 申請(qǐng)碼
 * @return true 有權(quán)限  false 無(wú)權(quán)限
 */
public static boolean checkAndApplyfPermissionFragment( Fragment mFragment, String[] permissions, int requestCode) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        permissions = checkPermissions(mFragment.getActivity(), permissions);
        if (permissions != null && permissions.length > 0) {
            if (mFragment.getActivity() != null) {
                mFragment.requestPermissions(permissions, requestCode);
            }
            return false;
        } else {
            return true;
        }
    } else {
        return true;
    }
}

/**
 * @param context     上下文
 * @param permissions 權(quán)限數(shù)組
 * @return 還需要申請(qǐng)的權(quán)限
 */
private static String[] checkPermissions(Context context, String[] permissions) {
    if (permissions == null || permissions.length == 0) {
        return new String[0];
    }
    ArrayList<String> permissionLists = new ArrayList<>();
    permissionLists.addAll(Arrays.asList(permissions));
    for (int i = permissionLists.size() - 1; i >= 0; i--) {
        if (ContextCompat.checkSelfPermission(context, permissionLists.get(i)) == PackageManager.PERMISSION_GRANTED) {
            permissionLists.remove(i);
        }
    }

    String[] temps = new String[permissionLists.size()];
    for (int i = 0; i < permissionLists.size(); i++) {
        temps[i] = permissionLists.get(i);
    }
    return temps;
    }


    /**
     * 檢查申請(qǐng)的權(quán)限是否全部允許
     */
    public static boolean checkPermission(int[] grantResults) {
        if (grantResults == null || grantResults.length == 0) {
            return true;
        } else {
            int temp = 0;
            for (int i : grantResults) {
                if (i == PackageManager.PERMISSION_GRANTED) {
                    temp++;
                }
            }
            return temp == grantResults.length;
        }
    }

/**
 * 沒(méi)有獲取到權(quán)限的提示
 *
 * @param permissions 權(quán)限名字?jǐn)?shù)組
 */
public static void showPermissionsToast(Activity activity, @NonNull String[] permissions) {
    if (permissions.length > 0) {
        for (String permission : permissions) {
            showPermissionToast(activity, permission);
        }
     }
   }

/**
 * 沒(méi)有獲取到權(quán)限的提示
 *
 * @param permission 權(quán)限名字
 */
private static void showPermissionToast(Activity activity, @NonNull String permission) {
    if (!ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)) {
        //用戶(hù)勾選了不再詢(xún)問(wèn),提示用戶(hù)手動(dòng)打開(kāi)權(quán)限
        switch (permission) {
            case Manifest.permission.CAMERA:
                ToastUtils.showShort("相機(jī)權(quán)限已被禁止,請(qǐng)?jiān)趹?yīng)用管理中打開(kāi)權(quán)限");
                break;
            case Manifest.permission.WRITE_EXTERNAL_STORAGE:
                ToastUtils.showShort("文件權(quán)限已被禁止挠阁,請(qǐng)?jiān)趹?yīng)用管理中打開(kāi)權(quán)限");
                break;
            case Manifest.permission.RECORD_AUDIO:
                ToastUtils.showShort("錄制音頻權(quán)限已被禁止宾肺,請(qǐng)?jiān)趹?yīng)用管理中打開(kāi)權(quán)限");
                break;
            case Manifest.permission.ACCESS_FINE_LOCATION:
                ToastUtils.showShort("位置權(quán)限已被禁止,請(qǐng)?jiān)趹?yīng)用管理中打開(kāi)權(quán)限");
                break;
        }
    } else {
        //用戶(hù)沒(méi)有勾選了不再詢(xún)問(wèn),拒絕了權(quán)限申請(qǐng)
        switch (permission) {
            case Manifest.permission.CAMERA:
                ToastUtils.showShort("沒(méi)有相機(jī)權(quán)限");
                break;
            case Manifest.permission.WRITE_EXTERNAL_STORAGE:
                ToastUtils.showShort("沒(méi)有文件讀取權(quán)限");
                break;
            case Manifest.permission.RECORD_AUDIO:
                ToastUtils.showShort("沒(méi)有錄制音頻權(quán)限");
                break;
            case Manifest.permission.ACCESS_FINE_LOCATION:
                ToastUtils.showShort("沒(méi)有位置權(quán)限");
                break;
          }
     }
  }
}

用法

   if (PermissionUtils.checkAndApplyfPermissionActivity(this,
        new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 
        REQUESRCARMEA)) {
       //獲取到權(quán)限的操作  沒(méi)有權(quán)限會(huì)申請(qǐng)權(quán)限  然后在onRequestPermissionsResult處理申請(qǐng)的結(jié)果
   }

   @Override
   public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
       super.onRequestPermissionsResult(requestCode, permissions, grantResults);
       if (PermissionUtils.checkPermission(grantResults)) {
           //申請(qǐng)權(quán)限成功
            switch (requestCode) {
                 case 0x001:
                     //dosomething
                     break;
                 case 0x002:
                    //dosomething
                     break;
                 ...
            }
       } else {
           //提示沒(méi)有什么權(quán)限
           PermissionUtils.showPermissionsToast(activity, permissions);
            //or 去權(quán)限管理界面
            //gotoPermissionManager(mContext);
       }
   }

沒(méi)有權(quán)限去權(quán)限管理界面

/**
 * 去應(yīng)用權(quán)限管理界面
 */
public static void gotoPermissionManager(Context context) {
    Intent intent;
    ComponentName comp;
    //防止刷機(jī)出現(xiàn)的問(wèn)題
    try {
        switch (Build.MANUFACTURER) {
            case "Huawei":
                intent = new Intent();
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.putExtra("packageName", BuildConfig.APPLICATION_ID);
                comp = new ComponentName("com.huawei.systemmanager", "com.huawei.permissionmanager.ui.MainActivity");
                intent.setComponent(comp);
                context.startActivity(intent);
                break;
            case "Meizu":
                intent = new Intent("com.meizu.safe.security.SHOW_APPSEC");
                intent.addCategory(Intent.CATEGORY_DEFAULT);
                intent.putExtra("packageName", BuildConfig.APPLICATION_ID);
                context.startActivity(intent);
                break;
            case "Xiaomi":
                String rom = getSystemProperty("ro.miui.ui.version.name");
                if ("v5".equals(rom)) {
                    Uri packageURI = Uri.parse("package:" + context.getApplicationInfo().packageName);
                    intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
                } else {//if ("v6".equals(rom) || "v7".equals(rom)) {
                    intent = new Intent("miui.intent.action.APP_PERM_EDITOR");
                    intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
                    intent.putExtra("extra_pkgname", context.getPackageName());
                }
                context.startActivity(intent);
                break;
            case "Sony":
                intent = new Intent();
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.putExtra("packageName", BuildConfig.APPLICATION_ID);
                comp = new ComponentName("com.sonymobile.cta", "com.sonymobile.cta.SomcCTAMainActivity");
                intent.setComponent(comp);
                context.startActivity(intent);
                break;
            case "OPPO":
                intent = new Intent();
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.putExtra("packageName", BuildConfig.APPLICATION_ID);
                comp = new ComponentName("com.color.safecenter", "com.color.safecenter.permission.PermissionManagerActivity");
                intent.setComponent(comp);
                context.startActivity(intent);
                break;
            case "LG":
                intent = new Intent("android.intent.action.MAIN");
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.putExtra("packageName", BuildConfig.APPLICATION_ID);
                comp = new ComponentName("com.android.settings", "com.android.settings.Settings$AccessLockSummaryActivity");
                intent.setComponent(comp);
                context.startActivity(intent);
                break;
            case "Letv":
                intent = new Intent();
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.putExtra("packageName", BuildConfig.APPLICATION_ID);
                comp = new ComponentName("com.letv.android.letvsafe", "com.letv.android.letvsafe.PermissionAndApps");
                intent.setComponent(comp);
                context.startActivity(intent);
                break;
            default:
                getAppDetailSettingIntent(context);
                break;
        }
    } catch (Exception e) {
        getAppDetailSettingIntent(context);
    }
}

/**
 * 獲取系統(tǒng)屬性值
 */
public static String getSystemProperty(String propName) {
    String line;
    BufferedReader input = null;
    try {
        Process p = Runtime.getRuntime().exec("getprop " + propName);
        input = new BufferedReader(new InputStreamReader(p.getInputStream()), 1024);
        line = input.readLine();
        input.close();
    } catch (IOException ex) {
        Log.e(TAG, "Unable to read sysprop " + propName, ex);
        return null;
    } finally {
        if (input != null) {
            try {
                input.close();
            } catch (IOException e) {
                Log.e(TAG, "Exception while closing InputStream", e);
            }
        }
    }
    return line;
}

  //以下代碼可以跳轉(zhuǎn)到應(yīng)用詳情侵俗,可以通過(guò)應(yīng)用詳情跳轉(zhuǎn)到權(quán)限界面(6.0系統(tǒng)測(cè)試可用)
 public static void getAppDetailSettingIntent(Context context) {
    Intent localIntent = new Intent();
    localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    if (Build.VERSION.SDK_INT >= 9) {
        localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
        localIntent.setData(Uri.fromParts("package", context.getPackageName(), null));
    } else if (Build.VERSION.SDK_INT <= 8) {
        localIntent.setAction(Intent.ACTION_VIEW);
        localIntent.setClassName("com.android.settings", "com.android.settings.InstalledAppDetails");
        localIntent.putExtra("com.android.settings.ApplicationPkgName", context.getPackageName());
    }
    launchApp(context, localIntent);
}

  /**
 * 安全的啟動(dòng)APP
 */
public static boolean launchApp(Context ctx, Intent intent) {
    if (ctx == null)
        throw new NullPointerException("ctx is null");
    try {
        ctx.startActivity(intent);
        return true;
    } catch (ActivityNotFoundException e) {
        Logger.e(e);
        return false;
    }
}
  • 取消支持 Apache HTTP 客戶(hù)端

Android 6.0 版移除了對(duì) Apache HTTP 客戶(hù)端的支持锨用。如果您的應(yīng)用使用該客戶(hù)端,并以 Android 2.3(API 級(jí)別 9)或更高版本為目標(biāo)平臺(tái)隘谣,請(qǐng)改用HttpURLConnection 類(lèi)增拥。此 API 效率更高啄巧,因?yàn)樗梢酝ㄟ^(guò)透明壓縮和響應(yīng)緩存減少網(wǎng)絡(luò)使用,并可最大限度降低耗電量掌栅。要繼續(xù)使用 Apache HTTP API秩仆,您必須先在 build.gradle 文件中聲明以下編譯時(shí)依賴(lài)項(xiàng):

  android {
      useLibrary 'org.apache.http.legacy'
  }
  • BoringSSL

Android 正在從使用 OpenSSL 庫(kù)轉(zhuǎn)向使用 BoringSSL 庫(kù)。如果您要在應(yīng)用中使用 Android NDK猾封,請(qǐng)勿鏈接到并非 NDK API 組成部分的加密庫(kù)澄耍,如libcrypto.so和 libssl.so。這些庫(kù)并非公共 API晌缘,可能會(huì)在不同版本和設(shè)備上毫無(wú)征兆地發(fā)生變化或出現(xiàn)故障齐莲。此外,您還可能讓自己暴露在安全漏洞的風(fēng)險(xiǎn)之下磷箕。請(qǐng)改為修改原生代碼选酗,以通過(guò) JNI 調(diào)用 Java 加密 API,或靜態(tài)鏈接到您選擇的加密庫(kù)岳枷。

bugly錯(cuò)誤
bugly錯(cuò)誤
  • 通知

此版本移除了 Notification.setLatestEventInfo()方法芒填。請(qǐng)改用 Notification.Builder 類(lèi)來(lái)構(gòu)建通知。要重復(fù)更新通知空繁,請(qǐng)重復(fù)使用Notification.Builder 實(shí)例殿衰。調(diào)用 build() 方法可獲取更新后的 Notification 實(shí)例。
adb shell dumpsys notification 命令不再打印輸出您的通知文本家厌。請(qǐng)改用 adb shell dumpsys notification --noredact 命令打印輸出 notification 對(duì)象中的文本播玖。build()方法在4.1以上(16+)的系統(tǒng)才能用。

notification
例子
gif
  • 音頻管理器變更

不再支持通過(guò) AudioManager 類(lèi)直接設(shè)置音量或?qū)⑻囟ㄒ纛l流 靜音饭于。[setStreamSolo()](https://developer.android.google.cn/reference/android/media/AudioManager.html#setStreamSolo(int, boolean)) 方法已棄用蜀踏,您應(yīng)該改為調(diào)用 [requestAudioFocus()](https://developer.android.google.cn/reference/android/media/AudioManager.html#requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int)) 方法。類(lèi)似地掰吕,[setStreamMute()](https://developer.android.google.cn/reference/android/media/AudioManager.html#setStreamMute(int, boolean)) 方法也已棄用果覆,請(qǐng)改為調(diào)用 [adjustStreamVolume()](https://developer.android.google.cn/reference/android/media/AudioManager.html#adjustStreamVolume(int, int, int)) 方法并傳入方向值 ADJUST_MUTEADJUST_UNMUTE

  • Android 密鑰庫(kù)變更

從此版本開(kāi)始殖熟,Android 密鑰庫(kù)提供程序不再支持 DSA局待。但仍支持 ECDSA。
停用或重置安全鎖定屏幕時(shí)(例如菱属,由用戶(hù)或設(shè)備管理員執(zhí)行此類(lèi)操作時(shí))钳榨,系統(tǒng)將不再刪除需要閑時(shí)加密的密鑰,但在上述事件期間會(huì)刪除需要閑時(shí)加密的密鑰纽门。

  • APK 驗(yàn)證

該平臺(tái)現(xiàn)在執(zhí)行的 APK 驗(yàn)證更為嚴(yán)格薛耻。如果在清單中聲明的文件在 APK 中并不存在,該 APK 將被視為已損壞赏陵。移除任何內(nèi)容后必須重新簽署 APK饼齿。

http://www.reibang.com/p/95790125b7f4
http://blog.csdn.net/lxk_1993/article/details/73784883

Android7.0

  • 系統(tǒng)權(quán)限更改

為了提高私有文件的安全性饲漾,面向 Android 7.0 或更高版本的應(yīng)用私有目錄被限制訪問(wèn) (0700)。此設(shè)置可防止私有文件的元數(shù)據(jù)泄漏缕溉,如它們的大小或存在性考传。此權(quán)限更改有多重副作用:

  • 在應(yīng)用間共享文件

對(duì)于面向 Android 7.0 的應(yīng)用,Android 框架執(zhí)行的 StrictModeAPI 政策禁止在您的應(yīng)用外部公開(kāi) file://URI夕膀。如果一項(xiàng)包含文件 URI 的 intent 離開(kāi)您的應(yīng)用虚倒,則應(yīng)用出現(xiàn)故障,并現(xiàn) FileUriExposedException产舞。異常魂奥。要在應(yīng)用間共享文件,您應(yīng)發(fā)送一項(xiàng) content://URI易猫,并授予 URI 臨時(shí)訪問(wèn)權(quán)限耻煤。進(jìn)行此授權(quán)的最簡(jiǎn)單方式是使用FileProvider類(lèi)。如需了解有關(guān)權(quán)限和共享文件的詳細(xì)信息准颓,請(qǐng)參閱共享文件哈蝇。

  • FileProvider用法

AndroidManiFest.xml添加

  <application>
  ...
    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.fileProvider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>
  ...
  </application>
配置applicationId

res目錄下新建xml文件夾,創(chuàng)建provider_paths.xml文件

  <?xml version="1.0" encoding="utf-8"?>
  <resources>
    <paths>
    <!--  前面兩個(gè)是bugly的 -->
    <!-- /storage/emulated/0/Download/${applicationId}/.beta/apk-->
    <external-path
        name="beta_external_path"
        path="Download/" />
    <!--/storage/emulated/0/Android/data/${applicationId}/files/apk/-->
    <external-path
        name="beta_external_files_path"
        path="Android/data/" />

    <external-path
        name="sdcard_files"
        path="" />
    <!--相機(jī)相冊(cè)裁剪-->
    <external-files-path
        name="camera_has_sdcard"
        path="" />
    <files-path
        name="camera_no_sdcard"
        path="" />
    </paths>
    <!--<paths>-->
    <!-- xml文件是唯一設(shè)置分享的目錄 攘已,不能用代碼設(shè)置-->
     <!--1.<files-path>        getFilesDir()  /data/data//files目錄-->
     <!--2.<cache-path>        getCacheDir()  /data/data//cache目錄-->
     <!--3.<external-path>       Environment.getExternalStorageDirectory()  -->
     <!--4.<external-files-path>    
       Context.getExternalFilesDir(String)  Context.getExternalFilesDir(null)  
       == SDCard/Android/data/你的應(yīng)用的包名/files/ 目錄-->
     <!--5.<external-cache-path>      Context.getExternalCacheDir().-->

     <!--  path :代表設(shè)置的目錄下一級(jí)目錄 eg:<external-path path="images/"-->
     <!--整個(gè)目錄為Environment.getExternalStorageDirectory()+"/images/"-->
     <!--name: 代表定義在Content中的字段 eg:name = "myimages" 炮赦,并且請(qǐng)求的內(nèi)容的文件名為default_image.jpg-->
     <!--則 返回一個(gè)URI   content://com.example.myapp.fileprovider/myimages/default_image.jpg-->

   <!--</paths>-->
  </resources>

確認(rèn)下路徑名

路徑

路徑

FileProvider 頭部設(shè)置的對(duì)應(yīng)標(biāo)簽

FileProvider

FileProvider 獲取對(duì)應(yīng)路徑邏輯 解析xml文件 對(duì)比對(duì)應(yīng)的標(biāo)簽 獲取對(duì)應(yīng)的路徑

FileProvider

**修改所有用到Uri的地方 圖中的 BuildConfig.APPLICATION_ID 最好還是改成 context.getPackageName() **


Uri修改

官方鏈接:FileProvider

  • APK Signature Scheme v2

Android 7.0引入了全新的 APK Signature Scheme v2。這是加強(qiáng)對(duì)包的校驗(yàn)贯被,啟動(dòng)了新的簽名后眼五,像美團(tuán)的多渠道打包方案在7.0機(jī)器上就會(huì)報(bào)錯(cuò)了妆艘。
解決的辦法也很簡(jiǎn)單,官方提供了關(guān)閉v2簽名的方法看幼,只需要在gradle上配置一下即可:
signingConfigs {
release {
.......
v2SigningEnabled false
}
}
參考:Android7.0適配
鏈接: APK Signature Scheme v2詳細(xì)介紹

其他

Android6.0

  • USB 連接

默認(rèn)情況下批旺,現(xiàn)在通過(guò) USB 端口進(jìn)行的設(shè)備連接設(shè)置為僅充電模式。要通過(guò) USB 連接訪問(wèn)設(shè)備及其內(nèi)容诵姜,用戶(hù)必須明確地為此類(lèi)交互授予權(quán)限汽煮。如果您的應(yīng)用支持用戶(hù)通過(guò) USB 端口與設(shè)備進(jìn)行交互,請(qǐng)將必須顯式啟用交互考慮在內(nèi)棚唆。

  • 瀏覽器書(shū)簽變更

此版本移除了對(duì)全局書(shū)簽的支持暇赤。android.provider.Browser.getAllBookmarks() 和 android.provider.Browser.saveBookmark() 方法現(xiàn)已移除。同樣宵凌,READ_HISTORY_BOOKMARKS 權(quán)限和 WRITE_HISTORY_BOOKMARKS 權(quán)限也已移除鞋囊。如果您的應(yīng)用以 Android 6.0(API 級(jí)別 23)或更高版本為目標(biāo)平臺(tái),請(qǐng)勿從全局提供程序訪問(wèn)書(shū)簽或使用書(shū)簽權(quán)限瞎惫。您的應(yīng)用應(yīng)改為在內(nèi)部存儲(chǔ)書(shū)簽數(shù)據(jù)溜腐。

  • 硬件標(biāo)識(shí)符訪問(wèn)權(quán)

為給用戶(hù)提供更嚴(yán)格的數(shù)據(jù)保護(hù),從此版本開(kāi)始瓜喇,對(duì)于使用 WLAN API 和 Bluetooth API 的應(yīng)用挺益,Android 移除了對(duì)設(shè)備本地硬件標(biāo)識(shí)符的編程訪問(wèn)權(quán)。WifiInfo.getMacAddress()方法和 BluetoothAdapter.getAddress()方法現(xiàn)在會(huì)返回常量值 02:00:00:00:00:00乘寒。
現(xiàn)在望众,要通過(guò)藍(lán)牙和 WLAN 掃描訪問(wèn)附近外部設(shè)備的硬件標(biāo)識(shí)符,您的應(yīng)用必須擁有 ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION 權(quán)限伞辛。

:當(dāng)運(yùn)行 Android 6.0(API 級(jí)別 23)的設(shè)備發(fā)起后臺(tái) WLAN 或藍(lán)牙掃描時(shí)烂翰,在外部設(shè)備看來(lái),該操作的發(fā)起來(lái)源是一個(gè)隨機(jī)化 MAC 地址始锚。

  • WLAN 和網(wǎng)絡(luò)連接變更

此版本對(duì) WLAN API 和 Networking API 引入了以下行為變更刽酱。

  • 現(xiàn)在,您的應(yīng)用只能更改由您創(chuàng)建的 WifiConfiguration 對(duì)象的狀態(tài)瞧捌。系統(tǒng)不允許您修改或刪除由用戶(hù)或其他應(yīng)用創(chuàng)建的 WifiConfiguration 對(duì)象棵里。

  • 在之前的版本中,如果應(yīng)用利用帶有 disableAllOthers=true
    設(shè)置的 [enableNetwork()](https://developer.android.google.cn/reference/android/net/wifi/WifiManager.html#enableNetwork(int, boolean)) 強(qiáng)制設(shè)備連接特定 WLAN 網(wǎng)絡(luò)姐呐,設(shè)備將會(huì)斷開(kāi)與移動(dòng)數(shù)據(jù)網(wǎng)絡(luò)等其他網(wǎng)絡(luò)的連接殿怜。在此版本中,設(shè)備不再斷開(kāi)與上述其他網(wǎng)絡(luò)的連接曙砂。如果您的應(yīng)用的 targetSdkVersion
    為 “20” 或更低头谜,則會(huì)固定連接所選 WLAN 網(wǎng)絡(luò)。如果您的應(yīng)用的 targetSdkVersion 為 “21”
    或更高鸠澈,請(qǐng)使用多網(wǎng)絡(luò) API(如 openConnection()柱告、bindSocket() 和新增的bindProcessToNetwork()
    方法)來(lái)確保通過(guò)所選網(wǎng)絡(luò)傳送網(wǎng)絡(luò)流量截驮。

  • 相機(jī)服務(wù)變更

在此版本中,相機(jī)服務(wù)中共享資源的訪問(wèn)模式已從之前的“先到先得”訪問(wèn)模式更改為高優(yōu)先級(jí)進(jìn)程優(yōu)先的訪問(wèn)模式际度。對(duì)服務(wù)行為的變更包括:

  • 根據(jù)客戶(hù)端應(yīng)用進(jìn)程的“優(yōu)先級(jí)”授予對(duì)相機(jī)子系統(tǒng)資源的訪問(wèn)權(quán)葵袭,包括打開(kāi)和配置相機(jī)設(shè)備。帶有對(duì)用戶(hù)可見(jiàn) Activity 或前臺(tái) Activity 的應(yīng)用進(jìn)程一般會(huì)被授予較高的優(yōu)先級(jí)乖菱,從而使相機(jī)資源的獲取和使用更加可靠坡锡;

  • 當(dāng)高優(yōu)先級(jí)的應(yīng)用嘗試使用相機(jī)時(shí),系統(tǒng)可能會(huì)“驅(qū)逐”正在使用相機(jī)客戶(hù)端的低優(yōu)先級(jí)應(yīng)用窒所。在已棄用的 Camera API 中鹉勒,這會(huì)導(dǎo)致系統(tǒng)為被驅(qū)逐的客戶(hù)端調(diào)用 [onError()](https://developer.android.google.cn/reference/android/hardware/Camera.ErrorCallback.html#onError(int, android.hardware.Camera))。在 Camera2 API 中吵取,這會(huì)導(dǎo)致系統(tǒng)為被驅(qū)逐的客戶(hù)端調(diào)用 onDisconnected()禽额;

  • 在配備相應(yīng)相機(jī)硬件的設(shè)備上,不同的應(yīng)用進(jìn)程可同時(shí)獨(dú)立打開(kāi)和使用不同的相機(jī)設(shè)備皮官。但現(xiàn)在绵疲,如果在多進(jìn)程用例中同時(shí)訪問(wèn)相機(jī)會(huì)造成任何打開(kāi)的相機(jī)設(shè)備的性能或能力嚴(yán)重下降,相機(jī)服務(wù)會(huì)檢測(cè)到這種情況并禁止同時(shí)訪問(wèn)臣疑。即使并沒(méi)有其他應(yīng)用直接嘗試訪問(wèn)同一相機(jī)設(shè)備,此變更也可能導(dǎo)致低優(yōu)先級(jí)客戶(hù)端被“驅(qū)逐”徙菠。

  • 更改當(dāng)前用戶(hù)會(huì)導(dǎo)致之前用戶(hù)帳戶(hù)擁有的應(yīng)用內(nèi)活動(dòng)相機(jī)客戶(hù)端被驅(qū)逐讯沈。對(duì)相機(jī)的訪問(wèn)僅限于訪問(wèn)當(dāng)前設(shè)備用戶(hù)擁有的用戶(hù)個(gè)人資料。舉例來(lái)說(shuō)婿奔,這意味著缺狠,當(dāng)用戶(hù)切換到其他帳戶(hù)后,“來(lái)賓”帳戶(hù)實(shí)際上無(wú)法讓使用相機(jī)子系統(tǒng)的進(jìn)程保持運(yùn)行狀態(tài)萍摊。

  • 運(yùn)行時(shí)

ART 運(yùn)行時(shí)環(huán)境現(xiàn)在可正確實(shí)現(xiàn) newInstance() 方法的訪問(wèn)規(guī)則挤茄。此變更修正了之前版本中 Dalvik 無(wú)法正確檢查訪問(wèn)規(guī)則的問(wèn)題。如果您的應(yīng)用使用newInstance() 方法冰木,并且您想重寫(xiě)訪問(wèn)檢查穷劈,請(qǐng)調(diào)用 setAccessible() 方法(將輸入?yún)?shù)設(shè)置為 true)。如果您的應(yīng)用使用 v7 appcompat 庫(kù)v7 recyclerview 庫(kù)踊沸,則您必須更新應(yīng)用以使用這些庫(kù)的最新版本歇终。否則,請(qǐng)務(wù)必更新從 XML 引用的任何自定義類(lèi)逼龟,以便能夠訪問(wèn)它們的類(lèi)構(gòu)造函數(shù)评凝。此版本更新了動(dòng)態(tài)鏈接程序的行為。動(dòng)態(tài)鏈接程序現(xiàn)在可以識(shí)別庫(kù)的 soname 與其路徑之間的差異(公開(kāi)錯(cuò)誤 6670)腺律,并且現(xiàn)在已實(shí)現(xiàn)了按 soname 搜索奕短。之前包含錯(cuò)誤的 DT_NEEDED 條目(通常是開(kāi)發(fā)計(jì)算機(jī)文件系統(tǒng)上的絕對(duì)路徑)卻仍工作正常的應(yīng)用宜肉,如今可能會(huì)出現(xiàn)加載失敗。現(xiàn)已正確實(shí)現(xiàn) dlopen(3) RTLD_LOCAL 標(biāo)記翎碑。請(qǐng)注意谬返,RTLD_LOCAL 是默認(rèn)值,因此不顯式使用 RTLD_LOCAL 的 dlopen(3) 調(diào)用將受到影響(除非您的應(yīng)用顯式使用 RTLD_GLOBAL)杈女。使用 RTLD_LOCAL 時(shí)朱浴,在隨后通過(guò)調(diào)用 dlopen(3) 加載的庫(kù)中并不能使用這些符號(hào)(這與由 DT_NEEDED 條目引用的情況截然不同)。

在之前版本的 Android 上达椰,如果您的應(yīng)用請(qǐng)求系統(tǒng)加載包含文本重定位信息的共享庫(kù)翰蠢,系統(tǒng)會(huì)顯示警告,但仍允許加載共享庫(kù)啰劲。從此版本開(kāi)始梁沧,如果您的應(yīng)用的目標(biāo) SDK 版本為 23 或更高,則系統(tǒng)會(huì)拒絕加載該庫(kù)蝇裤。為幫助您檢測(cè)庫(kù)是否加載失敗廷支,您的應(yīng)用應(yīng)該記錄 dlopen(3) 失敗日志,并在日志中加入dlerror(3) 調(diào)用返回的問(wèn)題描述文本栓辜。要詳細(xì)了解如何處理文本重定位恋拍,請(qǐng)參閱此指南

  • 低電耗模式和應(yīng)用待機(jī)模式

此版本引入了針對(duì)空閑設(shè)備和應(yīng)用的最新節(jié)能優(yōu)化技術(shù)藕甩。這些功能會(huì)影響所有應(yīng)用施敢,因此請(qǐng)務(wù)必在這些新模式下測(cè)試您的應(yīng)用。

  • 低電耗模式:如果用戶(hù)拔下設(shè)備的電源插頭狭莱,并在屏幕關(guān)閉后的一段時(shí)間內(nèi)使其保持不活動(dòng)狀態(tài)僵娃,設(shè)備會(huì)進(jìn)入低電耗模式,在該模式下設(shè)備會(huì)嘗試讓系統(tǒng)保持休眠狀態(tài)腋妙。在該模式下默怨,設(shè)備會(huì)定期短時(shí)間恢復(fù)正常工作,以便進(jìn)行應(yīng)用同步骤素,還可讓系統(tǒng)執(zhí)行任何掛起的操作匙睹。
  • 應(yīng)用待機(jī)模式:應(yīng)用待機(jī)模式允許系統(tǒng)判定應(yīng)用在用戶(hù)未主動(dòng)使用它時(shí)處于空閑狀態(tài)。當(dāng)用戶(hù)有一段時(shí)間未觸摸應(yīng)用時(shí)济竹,系統(tǒng)便會(huì)作出此判定垃僚。如果拔下了設(shè)備電源插頭,系統(tǒng)會(huì)為其視為空閑的應(yīng)用停用網(wǎng)絡(luò)訪問(wèn)以及暫停同步和作業(yè)规辱。

要詳細(xì)了解這些節(jié)能變更谆棺,請(qǐng)參閱對(duì)低電耗模式和應(yīng)用待機(jī)模式進(jìn)行針對(duì)性?xún)?yōu)化

  • 文本選擇

現(xiàn)在,當(dāng)用戶(hù)在您的應(yīng)用中選擇文本時(shí)改淑,您可以在一個(gè)浮動(dòng)工具欄中顯示“剪切”碍岔、“復(fù)制”“粘貼”等文本選擇操作。其在用戶(hù)交互實(shí)現(xiàn)上與為單個(gè)視圖啟用上下文操作模式中所述的上下文操作欄類(lèi)似朵夏。
要實(shí)現(xiàn)可用于文本選擇的浮動(dòng)工具欄忘分,請(qǐng)?jiān)谀默F(xiàn)有應(yīng)用中做出以下更改:

請(qǐng)注意辩棒,如果您使用 Android 支持庫(kù) 22.2 修訂版,浮動(dòng)工具欄不向后兼容膨疏,默認(rèn)情況下 appcompat 會(huì)獲得對(duì) ActionMode 對(duì)象的控制權(quán)一睁。這會(huì)禁止顯示浮動(dòng)工具欄。要在ActionMode 中啟用 AppCompatActivity 支持佃却,請(qǐng)調(diào)用 getDelegate()者吁,然后對(duì)返回的setHandleNativeActionModesEnabled() 對(duì)象調(diào)用 AppCompatDelegate,并將輸入?yún)?shù)設(shè)置為 false饲帅。此調(diào)用會(huì)將 ActionMode 對(duì)象的控制權(quán)交還給框架砚偶。在運(yùn)行 Android 6.0(API 級(jí)別 23)的設(shè)備上,框架可以支持 ActionBar 模式或浮動(dòng)工具欄模式洒闸;而在運(yùn)行 Android 5.1(API 級(jí)別 22)或之前版本的設(shè)備上,框架僅支持 ActionBar 模式均芽。

  • Android for Work 變更

此版本包含下列針對(duì) Android for Work 的行為變更:

Android7.0

  • 無(wú)障礙改進(jìn)

為提高平臺(tái)對(duì)于視力不佳或視力受損用戶(hù)的易用性啥供,Android 7.0 做出了一些更改。這些更改一般并不要求更改您的應(yīng)用代碼库糠,不過(guò)您應(yīng)仔細(xì)檢查并使用您的應(yīng)用測(cè)試這些功能伙狐,以評(píng)估它們對(duì)用戶(hù)體驗(yàn)的潛在影響。

  • 電池和內(nèi)存

Android 7.0 包括旨在延長(zhǎng)設(shè)備電池壽命和減少 RAM 使用的系統(tǒng)行為變更。這些變更可能會(huì)影響您的應(yīng)用訪問(wèn)系統(tǒng)資源鳞骤,以及您的應(yīng)用通過(guò)特定隱式 intent 與其他應(yīng)用交互的方式窒百。

  • 屏幕縮放

Android 7.0 支持用戶(hù)設(shè)置顯示尺寸,以放大或縮小屏幕上的所有元素豫尽,從而提升設(shè)備對(duì)視力不佳用戶(hù)的可訪問(wèn)性篙梢。用戶(hù)無(wú)法將屏幕縮放至低于最小屏幕寬度 sw320dp,該寬度是 Nexus 4 的寬度美旧,也是常規(guī)中等大小手機(jī)的寬度渤滞。

正常效果

運(yùn)行 Android 7.0 系統(tǒng)映像的設(shè)備增大顯示尺寸后的效果。

當(dāng)設(shè)備密度發(fā)生更改時(shí)榴嗅,系統(tǒng)會(huì)以如下方式通知正在運(yùn)行的應(yīng)用:

  • 如果是面向 API 級(jí)別 23 或更低版本系統(tǒng)的應(yīng)用妄呕,系統(tǒng)會(huì)自動(dòng)終止其所有后臺(tái)進(jìn)程。這意味著如果用戶(hù)切換離開(kāi)此類(lèi)應(yīng)用嗽测,轉(zhuǎn)而打開(kāi) Settings 屏幕并更改 Display size 設(shè)置绪励,則系統(tǒng)會(huì)像處理內(nèi)存不足的情況一樣終止該應(yīng)用。如果應(yīng)用具有任何前臺(tái)進(jìn)程唠粥,則系統(tǒng)會(huì)如處理運(yùn)行時(shí)更改中所述將配置變更通知給這些進(jìn)程疏魏,就像對(duì)待設(shè)備屏幕方向變更一樣。
  • 如果是面向 Android 7.0 的應(yīng)用晤愧,則其所有進(jìn)程(前臺(tái)和后臺(tái))都會(huì)收到有關(guān)配置變更的通知大莫,如處理運(yùn)行時(shí)更改中所述。

大多數(shù)應(yīng)用并不需要進(jìn)行任何更改即可支持此功能官份,不過(guò)前提是這些應(yīng)用遵循 Android 最佳做法只厘。具體要檢查的事項(xiàng):

  • 在屏幕寬度為 sw320dp 的設(shè)備上測(cè)試您的應(yīng)用,并確保其充分運(yùn)行舅巷。
  • 當(dāng)設(shè)備配置發(fā)生變更時(shí)羔味,更新任何與密度相關(guān)的緩存信息,例如緩存位圖或從網(wǎng)絡(luò)加載的資源钠右。當(dāng)應(yīng)用從暫停狀態(tài)恢復(fù)運(yùn)行時(shí)赋元,檢查配置變更。
    注:如果您要緩存與配置相關(guān)的數(shù)據(jù)爬舰,則最好也包括相關(guān)元數(shù)據(jù),例如該數(shù)據(jù)對(duì)應(yīng)的屏幕尺寸或像素密度寒瓦。保存這些元數(shù)據(jù)便于您在配置變更后決定是否需要刷新緩存數(shù)據(jù)情屹。
  • 避免用像素單位指定尺寸,因?yàn)橄袼夭粫?huì)隨屏幕密度縮放杂腰。應(yīng)改為使用與密度無(wú)關(guān)像素 (dp) 單位指定尺寸垃你。
  • NDK 應(yīng)用鏈接至平臺(tái)庫(kù)

從 Android 7.0 開(kāi)始,系統(tǒng)將阻止應(yīng)用動(dòng)態(tài)鏈接非公開(kāi) NDK 庫(kù),這種庫(kù)可能會(huì)導(dǎo)致您的應(yīng)用崩潰惜颇。此行為變更旨在為跨平臺(tái)更新和不同設(shè)備提供統(tǒng)一的應(yīng)用體驗(yàn)皆刺。即使您的代碼可能不會(huì)鏈接私有庫(kù),但您的應(yīng)用中的第三方靜態(tài)庫(kù)可能會(huì)這么做凌摄。因此羡蛾,所有開(kāi)發(fā)者都應(yīng)進(jìn)行相應(yīng)檢查,確保他們的應(yīng)用不會(huì)在運(yùn)行 Android 7.0 的設(shè)備上崩潰锨亏。如果您的應(yīng)用使用原生代碼痴怨,則只能使用公開(kāi) NDK API

  • 低電耗模式

Android 6.0(API 級(jí)別 23)引入了低電耗模式器予,當(dāng)用戶(hù)設(shè)備未插接電源浪藻、處于靜止?fàn)顟B(tài)且屏幕關(guān)閉時(shí),該模式會(huì)推遲 CPU 和網(wǎng)絡(luò)活動(dòng)乾翔,從而延長(zhǎng)電池壽命爱葵。而 Android 7.0 則通過(guò)在設(shè)備未插接電源且屏幕關(guān)閉狀態(tài)下、但不一定要處于靜止?fàn)顟B(tài)(例如用戶(hù)外出時(shí)把手持式設(shè)備裝在口袋里)時(shí)應(yīng)用部分 CPU 和網(wǎng)絡(luò)限制反浓,進(jìn)一步增強(qiáng)了低電耗模式萌丈。

圖 1. 低電耗模式如何應(yīng)用第一級(jí)系統(tǒng)活動(dòng)限制以延長(zhǎng)電池壽命的圖示。

當(dāng)設(shè)備處于充電狀態(tài)且屏幕已關(guān)閉一定時(shí)間后勾习,設(shè)備會(huì)進(jìn)入低電耗模式并應(yīng)用第一部分限制:關(guān)閉應(yīng)用網(wǎng)絡(luò)訪問(wèn)浓瞪、推遲作業(yè)和同步。如果進(jìn)入低電耗模式后設(shè)備處于靜止?fàn)顟B(tài)達(dá)到一定時(shí)間巧婶,系統(tǒng)則會(huì)對(duì)PowerManager.WakeLock
乾颁、AlarmManager 鬧鈴、GPS 和 WLAN 掃描應(yīng)用余下的低電耗模式限制艺栈。無(wú)論是應(yīng)用部分還是全部低電耗模式限制英岭,系統(tǒng)都會(huì)喚醒設(shè)備以提供簡(jiǎn)短的維護(hù)時(shí)間窗口,在此窗口期間湿右,應(yīng)用程序可以訪問(wèn)網(wǎng)絡(luò)并執(zhí)行任何被推遲的作業(yè)/同步诅妹。
圖 2. 低電耗模式如何在設(shè)備處于靜止?fàn)顟B(tài)達(dá)到一定時(shí)間后應(yīng)用第二級(jí)系統(tǒng)活動(dòng)限制的圖示。

請(qǐng)注意毅人,激活屏幕或插接設(shè)備電源時(shí)吭狡,系統(tǒng)將退出低電耗模式并移除這些處理限制。此項(xiàng)新增的行為不會(huì)影響有關(guān)使您的應(yīng)用適應(yīng) Android 6.0(API 級(jí)別 23)中所推出的舊版本低電耗模式的建議和最佳做法丈莺,如對(duì)低電耗模式和應(yīng)用待機(jī)模式進(jìn)行針對(duì)性?xún)?yōu)化中所討論划煮。您仍應(yīng)遵循這些建議(例如使用 Google 云消息傳遞 (GCM) 發(fā)送和接收消息)并開(kāi)始安排更新計(jì)劃以適應(yīng)新增的低電耗模式行為。

  • Project Svelte:后臺(tái)優(yōu)化

Android 7.0 移除了三項(xiàng)隱式廣播缔俄,以幫助優(yōu)化內(nèi)存使用和電量消耗弛秋。此項(xiàng)變更很有必要器躏,因?yàn)殡[式廣播會(huì)在后臺(tái)頻繁啟動(dòng)已注冊(cè)偵聽(tīng)這些廣播的應(yīng)用。刪除這些廣播可以顯著提升設(shè)備性能和用戶(hù)體驗(yàn)蟹略。
移動(dòng)設(shè)備會(huì)經(jīng)歷頻繁的連接變更登失,例如在 WLAN 和移動(dòng)數(shù)據(jù)之間切換時(shí)。目前挖炬,可以通過(guò)在應(yīng)用清單中注冊(cè)一個(gè)接收器來(lái)偵聽(tīng)隱式 CONNECTIVITY_ACTION
廣播揽浙,讓?xiě)?yīng)用能夠監(jiān)控這些變更。由于很多應(yīng)用會(huì)注冊(cè)接收此廣播茅茂,因此單次網(wǎng)絡(luò)切換即會(huì)導(dǎo)致所有應(yīng)用被喚醒并同時(shí)處理此廣播捏萍。
同理,在之前版本的 Android 中空闲,應(yīng)用可以注冊(cè)接收來(lái)自其他應(yīng)用(例如相機(jī))的隱式 ACTION_NEW_PICTUREACTION_NEW_VIDEO 廣播令杈。當(dāng)用戶(hù)使用相機(jī)應(yīng)用拍攝照片時(shí),這些應(yīng)用即會(huì)被喚醒以處理廣播碴倾。

為緩解這些問(wèn)題逗噩,Android 7.0 應(yīng)用了以下優(yōu)化措施:

  • 面向 Android 7.0 開(kāi)發(fā)的應(yīng)用不會(huì)收到 CONNECTIVITY_ACTION 廣播,即使它們已有清單條目來(lái)請(qǐng)求接受這些事件的通知跌榔。在前臺(tái)運(yùn)行的應(yīng)用如果使用 BroadcastReceiver 請(qǐng)求接收通知异雁,則仍可以在主線程中偵聽(tīng)CONNECTIVITY_CHANGE
  • 應(yīng)用無(wú)法發(fā)送或接收 ACTION_NEW_PICTUREACTION_NEW_VIDEO 廣播。此項(xiàng)優(yōu)化會(huì)影響所有應(yīng)用僧须,而不僅僅是面向 Android 7.0 的應(yīng)用纲刀。

如果您的應(yīng)用使用任何 intent,您仍需要盡快移除它們的依賴(lài)關(guān)系担平,以正確適配 Android 7.0 設(shè)備示绊。Android 框架提供多個(gè)解決方案來(lái)緩解對(duì)這些隱式廣播的需求。例如暂论,JobScheduler API 提供了一個(gè)穩(wěn)健可靠的機(jī)制來(lái)安排滿足指定條件(例如連入無(wú)限流量網(wǎng)絡(luò))時(shí)所執(zhí)行的網(wǎng)絡(luò)操作面褐。您甚至可以使用 JobScheduler 來(lái)適應(yīng)內(nèi)容提供程序變化。如需了解有關(guān) Android N 中后臺(tái)優(yōu)化以及如何改寫(xiě)應(yīng)用的詳細(xì)信息取胎,請(qǐng)參閱后臺(tái)優(yōu)化展哭。

更多信息請(qǐng)猛戳下面的官方鏈接

Android 6.0 變更
Android 7.0 變更

轉(zhuǎn)載請(qǐng)以鏈接形式標(biāo)明出處:
http://www.reibang.com/p/95790125b7f4
本文出自:103style
or
csdn
http://blog.csdn.net/lxk_1993/article/details/73784883
本文出自:lxk_1993

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市闻蛀,隨后出現(xiàn)的幾起案子匪傍,更是在濱河造成了極大的恐慌,老刑警劉巖觉痛,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件役衡,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡秧饮,警方通過(guò)查閱死者的電腦和手機(jī)映挂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)盗尸,“玉大人柑船,你說(shuō)我怎么就攤上這事∑酶鳎” “怎么了鞍时?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)扣蜻。 經(jīng)常有香客問(wèn)我逆巍,道長(zhǎng),這世上最難降的妖魔是什么莽使? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任锐极,我火速辦了婚禮,結(jié)果婚禮上芳肌,老公的妹妹穿的比我還像新娘灵再。我一直安慰自己,他們只是感情好亿笤,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布翎迁。 她就那樣靜靜地躺著,像睡著了一般净薛。 火紅的嫁衣襯著肌膚如雪汪榔。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天肃拜,我揣著相機(jī)與錄音痴腌,去河邊找鬼。 笑死爆班,一個(gè)胖子當(dāng)著我的面吹牛衷掷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播柿菩,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼戚嗅,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了枢舶?” 一聲冷哼從身側(cè)響起懦胞,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎凉泄,沒(méi)想到半個(gè)月后躏尉,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡后众,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年胀糜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了颅拦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡教藻,死狀恐怖距帅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情括堤,我是刑警寧澤碌秸,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站悄窃,受9級(jí)特大地震影響讥电,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜轧抗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一恩敌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧横媚,春花似錦潮剪、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至绽乔,卻和暖如春弧蝇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背折砸。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工看疗, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人睦授。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓两芳,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親去枷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子怖辆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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