精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

HarmonyOS NEXT體驗官#實戰鴻蒙,實現一款權限請求框架

系統 OpenHarmony
桃夭是鴻蒙系統上的一款權限請求框架,封裝了權限請求邏輯,采用鏈式調用的方式請求權限,極大的簡化了權限請求的代碼,同時支持在UI、UIAbility、UIExtensionAbility?里面申請權限。

想了解更多關于開源的內容,請訪問:

51CTO 鴻蒙開發者社區

https://ost.51cto.com

一、申請權限的一般步驟

  • 判斷是否有權限,如果有權限,直接進行下一步。
  • 如果沒有權限,則開始申請權限。
  • 如果用戶授權,進行下一步。
  • 如果用戶拒絕授權,后面再次申請權限,系統為了不打擾用戶,將不會出現系統的權限彈窗。在用戶拒絕授權后,需要彈窗提示用戶必須授權才能訪問當前功能,并引導用戶到系統設置中打開相應的權限。

每次申請權限的時候,都需要經過以上幾個步驟,當申請的權限越來越多,大量的重復代碼就出現了。為了減少重復代碼,我封裝了一個權限請求框架。

二、權限請求框架

桃夭是鴻蒙系統上的一款權限請求框架,封裝了權限請求邏輯,采用鏈式調用的方式請求權限,極大的簡化了權限請求的代碼,同時支持在UI、UIAbility、UIExtensionAbility里面申請權限。需要注意的是,應用在UIExtensionAbility申請授權時,需要在onWindowStageCreate函數執行結束后或在onWindowStageCreate函數回調中申請權限。

本項目基于開源鴻蒙4.1開發,最低兼容到API 11,請將DevEco Studio升級到最新版,DevEco Studio版本低于5.0.3.403可能無法編譯。

三、桃夭名稱來源

桃夭一詞出自古代第一部詩歌總集《詩經》中《詩經·桃夭》,“桃之夭夭,灼灼其華。”桃花怒放千萬朵,色彩鮮艷紅似火。

四、桃夭的使用方式

下載

ohpm install @shijing/taoyao

申請權限

TaoYao.with(this)
      .runtime()
      // 要申請的權限
      .permission(permissions)
      .onGranted(() => {
        // 權限申請成功
      })
      .onDenied(() => {
        // 權限申請失敗
      })
      .request()

申請權限變得如此之簡單。

五、實現原理

1.如何支持在UI、UIAbility、UIExtensionAbility里面申請權限。

可以使用聯合類型,也可以使用重載。這里通過重載的方式來實現在UI、UIAbility、UIExtensionAbility里面申請權限。

/**
   * 直接在UIExtensionAbility中申請權限
   *
   * @param uiAbility
   * @returns
   */
  static with(extensionAbility: UIExtensionAbility): IAccessControl;
  /**
   * 在UI中向用戶申請授權
   *
   * @param context
   * @returns
   */
  static with(context: common.UIAbilityContext): IAccessControl;

  /**
   * 直接在UIAbility中申請權限
   *
   * @param uiAbility
   * @returns
   */
  static with(uiAbility: UIAbility): IAccessControl;

  static with(context: common.UIAbilityContext | UIAbility | UIExtensionAbility): IAccessControl {
    if (context instanceof UIAbility) {
      return new AccessControl(new UIAbilityOrigin(context))
    } else if (context instanceof UIExtensionAbility) {
      return new AccessControl(new UIExtensionAbilityOrigin(context))
    } else {
      return new AccessControl(new ContextOrigin(context))
    }
  }

UI、UIAbility、UIExtensionAbility里面最重要就是Context對象,申請權限的時候需要傳入Context對象,我們需要從UI、UIAbility、UIExtensionAbility里面獲取Context對象。這里采用策略模式。創建接口Origin,Origin代表從哪申請權限,定義getContext方法,由子類實現該方法。

/**
 * 需要UI、UIAbility、UIExtensionAbility申請權限,同時獲取Context對象。
 */
export interface Origin {

  /**
   * 獲取context對象
   *
   * @returns
   */
  getContext(): Context

}

ContextOrigin代表在在UI中申請權限,實現Origin接口,重寫getContext方法。

/**
 * 在UI中申請權限
 */
export class ContextOrigin implements Origin {

  private context: common.UIAbilityContext

  constructor(context: common.UIAbilityContext) {
    this.context = context
  }

  getContext(): Context {
    return this.context
  }
}

UIAbilityOrigin代表在在UIAbility中申請權限,同樣實現Origin接口,重寫getContext方法。

/**
 * 在UIAbility中申請權限
 */
export class UIAbilityOrigin implements Origin {

  private uiAbility: UIAbility

  constructor(uiAbility: UIAbility) {
    this.uiAbility = uiAbility
  }

  getContext(): Context {
    return this.uiAbility.context
  }
}

UIExtensionAbilityOrigin代表在在UIExtensionAbility中申請權限,同樣實現Origin接口,重寫getContext方法。

/**
 * 在UIExtensionAbility中申請權限
 */
export class UIExtensionAbilityOrigin implements Origin {

  private uiExtensionAbility: UIExtensionAbility

  constructor(uiExtensionAbility: UIExtensionAbility) {
    this.uiExtensionAbility = uiExtensionAbility
  }

  getContext(): Context {
    return this.uiExtensionAbility.context
  }

}

2.檢測申請的權限是否在module.json5文件中聲明

申請的權限必須在module.json5文件中聲明,否則桃夭會直接拋異常。如何檢測申請的權限是否在配置文件中聲明?如下代碼,通過bundleManager對象獲取應用信息,之后就可以獲取應用在配置文件中聲明的權限了。如果要申請的權限沒有module.json5文件中聲明,那就會拋異常。

/**
   * 檢查要申請的權限是否在module.json5文件中聲明
   *
   * @param permissions 要申請的權限
   */
  private checkCommonConfig(permissions: Array<Permissions>) {
    const bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION;
    // 同步獲取在module.json5文件中聲明的所有權限
    const bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleFlags)
    const reqPermissionDetails = bundleInfo.reqPermissionDetails
    if (ArrayUtils.isEmpty(reqPermissionDetails)) {
      throw new Error('請在module.json5文件中聲明權限')
    }
    const reqPermissions = new ArrayList<string>()
    reqPermissionDetails.forEach(reqPermissionDetail => {
      reqPermissions.add(reqPermissionDetail.name)
    })
    permissions.forEach((permission) => {
      if (!reqPermissions.has(permission)) {
        // 要申請的權限沒有module.json5文件中聲明
        throw new Error(`請在module.json5文件中聲明${permission}權限`)
      }
    })
  }

3.檢測其它配置

對于位置權限,有三種情況:

第一:申請模糊位置權限,大部分情況下,不會申請模糊位置權限,更多的是第二種情況。

第二:申請精確位置權限。

第三:申請后臺位置權限。
針對位置權限,我們需要額外的配置下。

如果用戶申請精確位置權限,那就要先申請粗略位置權限。

如果用戶申請后臺位置權限,那就先申請模糊位置權限和精確位置權限。當同意這兩個權限后,彈窗提示用戶到系統設置中打開相應的權限,用戶在設置界面中的選擇“始終允許”應用訪問位置信息權限,應用就獲取了后臺位置權限。

/**
   * 檢查權限的其它配置
   *
   * @param permissions
   */
  checkOtherConfig(permissions: Array<Permissions>) {
    const locationPermissionIndex = permissions.indexOf(this.LOCATION_PERMISSION)
    const locationBackgroundIndex = permissions.indexOf(this.LOCATION_IN_BACKGROUND)
    if (locationPermissionIndex >= 0 && locationBackgroundIndex < 0) {
      /*
       * 對于位置權限,有兩種情況
       * 第一:申請模糊位置權限,大部分情況下,不會申請模糊位置權限,更多的是第二種情況。
       * 第二:申請精確位置權限,需要先申請模糊位置權限。
       */
      permissions = []
      permissions.push(this.APPROXIMATELY_LOCATION)
      permissions.push(this.LOCATION_PERMISSION)
    }
    if (locationBackgroundIndex >= 0) {
      // 申請后臺位置權限,需要先申請模糊位置權限和精確位置權限。當用戶點擊彈窗授予前臺位置權限后,應用通過彈窗、提示窗等形式告知用戶前往設置界面授予后臺位置權限。
      permissions = []
      permissions.push(this.APPROXIMATELY_LOCATION)
      permissions.push(this.LOCATION_PERMISSION)
      permissions.push(this.LOCATION_IN_BACKGROUND)
    }
    this.setNewPermission(permissions)
  }

4.判斷是否有權限

當所有的檢測都通過后,就可以判斷是否有權限了。調用checkAccessToken()方法來校驗當前是否已經授權。如果已經授權,則回調告知調用者已經有權限,否則需要進行下一步操作,即向用戶申請授權。

hasPermission(permissions: Array<Permissions>): boolean {
    for (let i = 0; i < permissions.length; i++) {
      const permission = permissions[i]
      let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
      let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;
      // 獲取應用程序的accessTokenID
      let tokenId: number = 0;
      try {
        let bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
        let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
        tokenId = appInfo.accessTokenId;
      } catch (error) {
        const err: BusinessError = error as BusinessError;
        console.error(`Failed to get bundle info for self. Code is ${err.code}, message is ${err.message}`);
      }
      // 校驗應用是否被授予權限
      grantStatus = atManager.checkAccessTokenSync(tokenId, permission);
      if (grantStatus !== abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
        return false
      }
    }
    return true
  }

5.申請權限

調用requestPermissionsFromUser(),如果用戶授權,則調用mOnGranted。如果用戶拒絕授權,提示用戶必須授權才能訪問當前頁面的功能,并引導用戶到系統設置中打開相應的權限。

/**
   * 申請權限
   *
   * @param permissions
   */
  requestPermission(permissions: Permissions[]) {
    let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
    // requestPermissionsFromUser會判斷權限的授權狀態來決定是否喚起彈窗
    atManager.requestPermissionsFromUser(this.origin.getContext(), permissions).then((data) => {
      let grantStatus: Array<number> = data.authResults;
      let length: number = grantStatus.length;
      for (let i = 0; i < length; i++) {
        if (grantStatus[i] === 0) {
          // 用戶授權,可以繼續訪問目標操作
          this.mOnGranted?.(this.originPermissions)
        } else {
          // 用戶拒絕授權,提示用戶必須授權才能訪問當前頁面的功能,并引導用戶到系統設置中打開相應的權限
          this.mOnDenied?.(this.originPermissions)
          return;
        }
      }
      // 授權成功
    }).catch((err: BusinessError) => {
      console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
    })
  }

6.系統設置彈窗

用戶拒絕授權,提示用戶必須授權才能訪問當前頁面的功能,并引導用戶到系統設置中打開相應的權限。但在跳轉系統設置之前,需要彈窗提示用戶,這里提供一個默認的彈窗。如果這個彈窗不滿足你的要求,你可以改掉。當用戶在彈窗里面點擊取消,則隱藏彈窗。當用戶在彈窗里面點擊去設置,則跳轉到系統設置頁面。

import { TaoYao } from '@shijing/taoyao/Index'
import { common, Permissions } from '@kit.AbilityKit'
import { hilog } from '@kit.PerformanceAnalysisKit'

/**
 * 跳轉系統設置之前,需要先彈窗
 */
@CustomDialog
export struct PermissionDialog {

  private title: string = '權限設置'
  private subtitle?: Resource
  private left: string = '取消'
  private right: string = '去設置'
  private permissions = new Array<Permissions>()
  private context = getContext(this) as common.UIAbilityContext
  controller: CustomDialogController

  aboutToAppear(): void {
    if (this.permissions.indexOf(('ohos.permission.ACCESS_BLUETOOTH' as Permissions)) >= 0) {
      this.subtitle = $r('app.string.access_bluetooth')
    } else if (this.permissions.indexOf(('ohos.permission.MEDIA_LOCATION' as Permissions)) >= 0) {
      this.subtitle = $r('app.string.media_location')
    } else if (this.permissions.indexOf(('ohos.permission.APP_TRACKING_CONSENT' as Permissions)) >= 0) {
      this.subtitle = $r('app.string.app_tracking_consent')
    } else if (this.permissions.indexOf(('ohos.permission.ACTIVITY_MOTION' as Permissions)) >= 0) {
      this.subtitle = $r('app.string.activity_motion')
    } else if (this.permissions.indexOf(('ohos.permission.CAMERA' as Permissions)) >= 0) {
      this.subtitle = $r('app.string.camera')
    } else if (this.permissions.indexOf(('ohos.permission.DISTRIBUTED_DATASYNC' as Permissions)) >= 0) {
      this.subtitle = $r('app.string.distributed_datasync')
    } else if (this.permissions.indexOf(('ohos.permission.LOCATION_IN_BACKGROUND' as Permissions)) >= 0) {
      this.subtitle = $r('app.string.location_in_background')
    } else if (this.permissions.indexOf(('ohos.permission.LOCATION' as Permissions)) >= 0) {
      this.subtitle = $r('app.string.location')
    } else if (this.permissions.indexOf(('ohos.permission.APPROXIMATELY_LOCATION' as Permissions)) >= 0) {
      this.subtitle = $r('app.string.approximately_location')
    } else if (this.permissions.indexOf(('ohos.permission.MICROPHONE' as Permissions)) >= 0) {
      this.subtitle = $r('app.string.microphone')
    } else if (this.permissions.indexOf(('ohos.permission.READ_CALENDAR' as Permissions)) >= 0) {
      this.subtitle = $r('app.string.read_calendar')
    } else if (this.permissions.indexOf(('ohos.permission.WRITE_CALENDAR' as Permissions)) >= 0) {
      this.subtitle = $r('app.string.write_calendar')
    } else if (this.permissions.indexOf(('ohos.permission.READ_HEALTH_DATA' as Permissions)) >= 0) {
      this.subtitle = $r('app.string.read_health_data')
    } else if (this.permissions.indexOf(('ohos.permission.READ_MEDIA' as Permissions)) >= 0) {
      this.subtitle = $r('app.string.read_media')
    } else if (this.permissions.indexOf(('ohos.permission.WRITE_MEDIA' as Permissions)) >= 0) {
      this.subtitle = $r('app.string.write_media')
    }
  }

  build() {
    Column() {
      Text(this.title)
        .fontSize(20)
        .fontColor('#151724')
      Text(this.subtitle)
        .fontColor('#151724')
        .fontSize(15)
        .margin({top: 30})
      Row() {
        Button(this.left)
          .fontColor('#585a5c')
          .borderRadius(24)
          .backgroundColor('#eeeeee')
          .width('40%')
          .height(48)
          .margin({right: 20})
          .onClick(() => {
            this.controller.close()
          })
        Button(this.right)
          .fontColor('#ffffff')
          .borderRadius(24)
          .backgroundColor('#4b54fa')
          .width('40%')
          .height(48)
          .onClick(() => {
            this.controller.close()
            TaoYao.goToSettingPage(this.context)
          })
      }
      .margin({top: 30})
      .justifyContent(FlexAlign.SpaceBetween)
    }
    .width('100%')
    .borderRadius(20)
    .backgroundColor('#ffffff')
    .padding({left: 24, right: 24, top: 30, bottom: 28})
  }
}

7.跳轉到設置頁面

使用下面的代碼即可跳轉到系統設置頁面。構建一個want對象,指定bundleName 、abilityName 、uri 、parameters 等參數,調用startAbility 。

function openPermissionsInSystemSettings(context: common.UIAbilityContext): void {
  let wantInfo: Want = {
    bundleName: 'com.huawei.hmos.settings', // 系統設置的包名
    abilityName: 'com.huawei.hmos.settings.MainAbility', // 系統設置權限頁面的類名
    uri: 'application_info_entry',
    parameters: {
      pushParams: 'com.example.myapplication' // 應用的包名,也就是打開指定應用的詳情頁面
    }
  }
  context.startAbility(wantInfo).then(() => {
    // ...
  }).catch((err: BusinessError) => {
    // ...
  })

目前只有華為手機使用了開源鴻蒙系統,不排除后續會有其它的廠商使用開源鴻蒙系統,到時want對象的bundleName、abilityName、uri可能會不一樣。在這種情況下,上面的代碼就會有兼容性問題。這就需要針對不同的品牌,創建不同的want對象。這里采用策略模式。如下代碼,創建SettingWant接口,定義getWant方法,由子類實現該方法,也就是由子類來創建want對象。

export interface SettingWant {

  /**
   * 獲取want對象
   *
   * @param bundleName
   * @returns
   */
  getWant(bundleName: string): Want
}

新建DefaultSettingWant類,DefaultSettingWant是一個默認創建Want對象的子類。

/**
 * 默認獲取的want參數
 */
export class DefaultSettingWant implements SettingWant {

  getWant(bundleName: string): Want {
    let wantInfo: Want = {
      bundleName: 'com.huawei.hmos.settings',
      abilityName: 'com.huawei.hmos.settings.MainAbility',
      uri: 'application_info_entry',
      parameters: {
        pushParams: bundleName // 打開指定應用的詳情頁面
      }
    }
    return wantInfo
  }

}

對于華為手機,我們就繼承DefaultSettingWant,直接使用默認創建的Want對象。

/**
 * 獲取華為手機上的want參數
 */
export class HuaWeiSettingWant extends DefaultSettingWant {
}

如下代碼,先創建SettingWant 對象,通過deviceInfo.brand判斷品牌,如果是華為手機,則創建HuaWeiSettingWant 。調用getWant獲取到Want對象,調用startAbility跳轉到系統設置。

gToSettingPage(): void {
    const bundleName = this.getContext().abilityInfo.bundleName
    let settingWant: SettingWant
    if (deviceInfo.brand === "HUAWEI") {
      settingWant = new HuaWeiSettingWant()
    } else {
      settingWant = new DefaultSettingWant()
    }
    const want = settingWant.getWant(bundleName)
    if (this.origin instanceof UIExtensionAbilityOrigin) {
      // 在UIExtensionAbility中跳轉到系統設置頁面
      this.startAbilityFromUIExtensionAbility(want)
    } else {
      // 在UI或者UIAbility中跳轉到系統設置頁面
      this.startAbilityFromUIAbility(want)
    }
  }

 /**
   * 在UIExtensionAbility中跳轉到系統設置頁面
   *
   * @param want
   */
  private startAbilityFromUIExtensionAbility(want: Want) {
    (this.origin.getContext() as common.UIExtensionContext).startAbility(want).then(() => {
      // 跳轉成功
    }).catch((err: BusinessError) => {
      console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
    })
  }

  /**
   * 在UI或者UIAbility中跳轉到系統設置頁面
   *
   * @param want
   */
  private startAbilityFromUIAbility(want: Want) {
    this.getContext().startAbility(want).then(() => {
      // 跳轉成功
    }).catch((err: BusinessError) => {
      console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
    })
  }

  getContext(): common.UIAbilityContext {
    return (this.origin.getContext()) as common.UIAbilityContext
  }

六、源碼

更多具體的代碼,請下載源碼或者查看OpenHarmony三方庫中心倉

想了解更多關于開源的內容,請訪問:

51CTO 鴻蒙開發者社區

https://ost.51cto.com

責任編輯:jianghua 來源: 51CTO 鴻蒙開發者社區
相關推薦

2021-11-09 09:43:52

鴻蒙HarmonyOS應用

2024-07-31 09:46:13

2021-01-07 11:32:43

鴻蒙HarmonyOS計算器

2018-01-17 15:05:22

框架設計爬蟲Scrapy

2021-07-23 16:50:19

httpJava框架

2020-01-13 15:24:22

框架SparkHadoop

2022-02-25 14:57:33

harmonyOSjava心形動畫

2021-11-17 15:36:04

鴻蒙HarmonyOS應用

2024-07-31 09:55:19

2023-04-20 08:00:40

2017-06-30 16:24:40

大數據神經網絡NNabla

2021-05-18 13:25:28

feapder爬蟲Python

2023-03-08 07:45:50

可視化編程工具SpringBoot

2021-08-06 09:50:13

SpringBoot框架Java

2021-06-10 09:00:32

Java項目實戰Java編程

2021-09-14 15:01:31

Pstf安全工具指紋框架

2024-12-20 10:53:11

2024-03-14 08:32:37

HTMLWeb 框架PPT

2021-10-24 08:15:44

Web身份認證測試框架

2024-12-25 13:27:16

點贊
收藏

51CTO技術棧公眾號

久久综合亚洲色hezyo国产| 国内av一区二区| 狠狠v欧美ⅴ日韩v亚洲v大胸 | 懂色av一区二区| 欧美视频13p| 亚洲欧美日韩在线综合| 亚洲欧美激情在线观看| 日本不卡一二三区黄网| 欧美国产视频一区二区| 毛片aaaaaa| 鲁大师精品99久久久| 欧美精品色一区二区三区| 免费国产a级片| 成人video亚洲精品| 久久久久久免费| 国产精品久久久对白| 中文字幕男人天堂| 夜夜嗨av一区二区三区网站四季av| 最近2019中文免费高清视频观看www99 | 成人激情校园春色| 91精品免费看| 免费无码国产精品| 亚洲每日在线| 美女精品视频一区| 蜜桃av免费观看| 色老板在线视频一区二区| 日韩一卡二卡三卡| 欧美性受xxxxxx黑人xyx性爽| 成人国产二区| 亚洲.国产.中文慕字在线| 国产一二三四区在线观看| av一本在线| 久久久久久久久97黄色工厂| 国产日韩一区欧美| 国产av无码专区亚洲a∨毛片| 日本sm残虐另类| 欧美一级淫片videoshd| 亚洲欧美在线视频免费| 精品白丝av| 欧美精品久久一区二区| 国产人妻精品一区二区三区不卡| 清纯唯美日韩| 色七七影院综合| 人妻少妇精品视频一区二区三区 | 日韩欧美国产麻豆| 欧美一级特黄aaa| 在线观看亚洲精品福利片| 欧美日韩一区二区欧美激情| 免费看污污网站| 香蕉成人影院| 欧美日韩另类一区| 永久免费的av网站| 亚洲国产aⅴ精品一区二区三区| 欧美午夜一区二区三区| 九色porny自拍| 曰本一区二区| 精品日韩一区二区三区| 欧美一级片黄色| 亚洲激情播播| 亚洲无av在线中文字幕| 九九热免费在线| 国产精品久久观看| 欧美成人小视频| 国产一级片久久| 99精品视频网| 国产精品旅馆在线| 国产精品久久久久久久久久久久久久久久久久 | 久久66热这里只有精品| 免费在线性爱视频| 国产精品久久久久久久久免费樱桃| 夜夜爽www精品| 曰本三级在线| 欧美日韩在线观看视频| 国产一级做a爰片久久| 国产精品777777在线播放| 日韩视频在线你懂得| 免费黄色三级网站| 成人精品亚洲| 色中色综合影院手机版在线观看| 粉嫩aⅴ一区二区三区| 久久亚洲美女| 亚洲淫片在线视频| 色猫av在线| 中文字幕中文字幕一区| 欧美在线观看视频免费| 成人欧美一区二区三区的电影| 精品视频1区2区| 69久久精品无码一区二区| 免费观看成人www动漫视频| 亚洲性69xxxbbb| 免费在线观看亚洲| 日韩黄色免费网站| 国产精品免费在线播放| 成人jjav| 亚洲成a人在线观看| 天天爽天天爽夜夜爽| 亚洲伊人影院| 在线看日韩av| 日韩精品视频免费看| 蜜臀99久久精品久久久久久软件| 国产精品国产三级国产专区53| 国产免费a∨片在线观看不卡| 亚洲一区在线观看免费观看电影高清| 日本黄色三级大片| 亚洲免费一区三区| 中文字幕一精品亚洲无线一区| 国产一级一级片| 久久爱另类一区二区小说| 精品视频免费观看| 亚洲妇熟xxxx妇色黄| 欧美日韩亚洲高清一区二区| 日韩av一二区| 欧美精品一卡| 成人精品aaaa网站| 成人在线观看一区| 欧美日韩免费看| av漫画在线观看| 天天做天天爱天天综合网| 国产精品h片在线播放| 狠狠躁夜夜躁av无码中文幕| 亚洲欧美二区三区| 韩国视频一区二区三区| 美女毛片一区二区三区四区最新中文字幕亚洲| 久久久精品在线观看| 在线视频精品免费| 久久久久久久久久看片| 日本在线xxx| 风间由美一区二区av101| www国产亚洲精品久久网站| 日韩国产成人在线| 久久午夜国产精品| 成人免费毛片网| 猫咪成人在线观看| 午夜精品福利在线观看| 丰满少妇一级片| 亚洲一区在线观看免费观看电影高清| 男人午夜视频在线观看| 91精品国产91久久久久久密臀| 国产精品久久在线观看| 国产三级电影在线观看| 色老汉av一区二区三区| 99久久人妻无码精品系列| 免费亚洲一区| 热舞福利精品大尺度视频| 欧美大胆性生话| 一本久久综合亚洲鲁鲁| 一区二区视频网| 国产精品高清亚洲| 日本在线观看视频一区| 在线精品国产| 国产精品18毛片一区二区| 欧美6一10sex性hd| 亚洲国产精久久久久久久| 九热这里只有精品| 99免费精品在线| 久久久久久久久久久免费视频| 免费看av成人| 国产精品视频午夜| 巨大荫蒂视频欧美另类大| 欧美一级高清大全免费观看| 欧美另类视频在线观看| 99视频一区二区| 亚洲无吗一区二区三区| 亚洲成av人片乱码色午夜| 成人区精品一区二区| 日韩激情电影| 中文综合在线观看| 亚洲精品一区二区三区区别| 婷婷开心激情综合| japanese中文字幕| 国产又黄又大久久| 欧美在线一区视频| 国产在线日韩精品| 亚洲综合在线中文字幕| 深夜在线视频| 日韩在线精品视频| 性猛交富婆╳xxx乱大交天津| 偷拍一区二区三区四区| 国产精品无码无卡无需播放器| 国产乱码一区二区三区| 男女高潮又爽又黄又无遮挡| 日韩大片在线播放| 国产另类自拍| 精品久久99| 555www成人网| 福利视频在线| 亚洲美女激情视频| aaa级黄色片| 一本在线高清不卡dvd| 登山的目的在线| 91麻豆swag| 一级网站在线观看| 老**午夜毛片一区二区三区| 日韩成人午夜影院| 精品国产91| 国产精品一区二区av| 成人18视频在线观看| 亚洲**2019国产| 国产在线一区二区视频| 亚洲女人天堂视频| 亚洲精品久久久久久无码色欲四季| 色悠悠亚洲一区二区| 久久黄色小视频| 国产午夜精品在线观看| 美女搡bbb又爽又猛又黄www| 美女视频一区二区| 虎白女粉嫩尤物福利视频| 欧美片第1页综合| 一区二区日本伦理| 亚洲自拍电影| 国产一区二区三区高清视频| 国产色99精品9i| 成人av在线网址| 国产私拍福利精品视频二区| 91av在线看| 成全电影大全在线观看| 久久九九热免费视频| 成人免费在线电影| 亚洲人成啪啪网站| 日韩精品123| 日韩av最新在线观看| 精品女同一区二区三区| 在线不卡中文字幕播放| 久久午夜鲁丝片| 色狠狠综合天天综合综合| 日本一级片免费看| 亚洲成人免费观看| 久久亚洲AV无码| 亚洲精品视频一区二区| 亚洲精品久久久久久国| 国产精品青草久久| 亚洲欧美va天堂人熟伦| 国产午夜精品一区二区| 国产精品无码一区二区三区| 26uuu成人网一区二区三区| 国产肉体xxxx裸体784大胆| 北岛玲一区二区三区四区| 国产国语老龄妇女a片| 国产成人精品亚洲午夜麻豆| 色姑娘综合天天| 久久成人羞羞网站| 亚洲精品乱码久久久久久动漫| 激情综合亚洲精品| 国产5g成人5g天天爽| 国产**成人网毛片九色| 国产伦精品一区二区三区88av| 成人一道本在线| 熟妇人妻久久中文字幕| 久久在线免费观看| 亚洲最大成人综合网| 中文字幕乱码久久午夜不卡| 91麻豆精品久久毛片一级| 国产精品盗摄一区二区三区| 娇小11一12╳yⅹ╳毛片| 最新国产精品久久精品| 免看一级a毛片一片成人不卡| 亚洲影视在线播放| 免费成年人视频在线观看| 久久精品一区二区不卡| 亚洲午夜在线观看| 一区二区免费不卡在线| 日韩专区第三页| 亚洲国产日本| 免费在线激情视频| 日本成人在线不卡视频| 亚洲第一区第二区第三区| 成人综合在线视频| theav精尽人亡av| 中国色在线观看另类| 老熟妻内射精品一区| 亚洲成av人在线观看| 激情五月婷婷网| 3d成人h动漫网站入口| 风流少妇一区二区三区91| 亚洲精品自在久久| 永久免费av在线| 欧美激情在线视频二区| 日本不卡免费高清视频在线| 国产精品成人aaaaa网站| 国产精品日本一区二区不卡视频 | 中文字幕在线不卡一区二区三区| 欧美精品久久久久久久久46p| 亚洲成年人影院| 最近中文字幕免费观看| 精品乱人伦一区二区三区| 国产系列在线观看| 欧美激情久久久久| 日本在线视频一区二区| 丁香五月网久久综合| 久久最新网址| 人人妻人人澡人人爽欧美一区| 久久人人超碰| 丰满少妇一区二区三区专区| 91麻豆国产福利在线观看| 黄色香蕉视频在线观看| 色综合婷婷久久| 亚洲国产精品国自产拍久久| 国产一区二区三区在线免费观看 | 蜜臀视频在线观看| 国产精品久久三| 欧美三日本三级少妇99| 制服丝袜中文字幕亚洲| 免费黄色在线视频网站| 欧美激情在线观看视频| 国产精品18| 亚洲精品自在在线观看| 亚洲永久免费精品| 色婷婷狠狠18禁久久| 中文字幕在线一区二区三区| 欧美特黄aaaaaa| 精品国产1区二区| 影音先锋在线播放| 91精品啪在线观看麻豆免费| 激情综合网站| 成人在线免费观看av| 国产成人在线电影| 日本中文在线视频| 欧美三电影在线| 国产免费视频在线| 欧美在线中文字幕| 欧美三级午夜理伦三级在线观看| 青青草视频国产| 国产一区不卡在线| 国语对白在线播放| 欧美老肥妇做.爰bbww| 国产大学生校花援交在线播放| 日本精品免费一区二区三区| 久久久久影视| 激情五月宗合网| 91在线国产福利| 日韩欧美性视频| 亚洲激情中文字幕| 国产三级电影在线播放| 国产精品日韩一区二区| 亚洲电影在线| 老熟妇精品一区二区三区| 激情亚洲一区二区三区四区| 成人精品在线播放| 欧美精品福利在线| 欧美男男freegayvideosroom| 久在线观看视频| 久久亚洲欧美国产精品乐播| 免费看毛片网站| 一本大道久久加勒比香蕉| 日韩经典一区| 亚洲人成人77777线观看| 蜜臀国产一区二区三区在线播放| 美女100%露胸无遮挡| 7777精品伊人久久久大香线蕉 | 亚洲欧美综合国产精品一区| 日本特黄在线观看| 亚洲国产日韩综合久久精品| 少妇av一区二区| 日韩av色在线| 日韩欧美一区二区三区在线视频| 国产亚洲视频一区| 亚洲免费电影在线| 欧美性猛交 xxxx| 奇米成人av国产一区二区三区| 精品久久国产| 亚洲色图偷拍视频| 亚洲一区精品在线| 五月婷婷六月丁香综合| 国产精品福利在线观看网址| 97久久夜色精品国产| 韩国av中国字幕| 欧美特黄级在线| 免费观看在线午夜影视| 国产精品对白刺激久久久| 国产精品一区亚洲| 免费一级suv好看的国产网站| 日韩三级视频在线看| 成人短视频app| 国产欧美自拍视频| 不卡视频一二三| 日本三级一区二区三区| 欧美成人激情在线| 一本久久青青| 欧美xxxx黑人| 色综合av在线| 久久不射影院| 日韩亚洲视频在线| 国产凹凸在线观看一区二区| 中文字幕黄色片| 欧美猛交免费看| 欧美日韩国产传媒| 毛茸茸free性熟hd| 欧美日韩在线播放三区| 爱草tv视频在线观看992| 亚洲国产日韩欧美| www.日本不卡| 91在线你懂的| 青草成人免费视频| 国产一区日韩欧美| 91狠狠综合久久久久久| 亚洲电影免费观看高清完整版在线观看 | 色一情一区二区三区| 好吊成人免视频| 青草在线视频| 一区二区三区四区欧美|