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

Android M 新運行時權限開發者需要知道的一切

移動開發
android在不斷發展,最近的更新 M 非常不同,一些主要的變化例如運行時權限將有顛覆性影響。驚訝的是android社區鮮有談論這事兒,盡管這事很重要或許在不遠的將來會引發很嚴重的問題。 這是今天我寫這篇博客的原因。這里有一切關于android運行時權限你需要知道的,包括如何在代碼中實現。現在亡羊補牢還不晚。

[[149547]]

android M 的名字官方剛發布不久,最終正式版即將來臨!

android在不斷發展,最近的更新 M 非常不同,一些主要的變化例如運行時權限將有顛覆性影響。驚訝的是android社區鮮有談論這事兒,盡管這事很重要或許在不遠的將來會引發很嚴重的問題。
這是今天我寫這篇博客的原因。這里有一切關于android運行時權限你需要知道的,包括如何在代碼中實現。現在亡羊補牢還不晚。

新運行時權限

android的權限系統一直是首要的安全概念,因為這些權限只在安裝的時候被詢問一次。一旦安裝了,app可以在用戶毫不知曉的情況下訪問權限內的所有東西。

難怪一些壞蛋利用這個缺陷惡意收集用戶數據用來做壞事了!

android小組也知道這事兒。7年了!權限系統終于被重新設計了。在android6.0棉花糖,app將不會在安裝的時候授予權限。取而代之的是,app不得不在運行時一個一個詢問用戶授予權限。

Android M 新的運行時權限開發者需要知道的一切

注意權限詢問對話框不會自己彈出來。開發者不得不自己調用。如果開發者要調用的一些函數需要某權限而用戶又拒絕授權的話,函數將拋出異常直接導致程序崩潰。

Android M 新的運行時權限開發者需要知道的一切

另外,用戶也可以隨時在設置里取消已經授權的權限。

[[149548]]

你或許已經感覺到背后生出一陣寒意。。。如果你是個android開發者,意味著要完全改變你的程序邏輯。你不能像以前那樣直接調用方法了,你不得不為每個需要的地方檢察權限,否則app就崩潰了!

是的。我不能哄你說這是簡單的事兒。盡管這對用戶來說是好事,但是對開發者來說就是噩夢。我們不得不修改編碼不然不論短期還是長遠來看都是潛在的問題。

這個新的運行時權限僅當我們設置targetSdkVersion to 23(這意味著你已經在23上測試通過了)才起作用,當然還要是M系統的手機。app在6.0之前的設備依然使用舊的權限系統。

已經發布了的app會發生什么

新運行時權限可能已經讓你開始恐慌了。“hey,伙計!我三年前發布的app可咋整呢。如果他被裝到android 6.0上,我的app會崩潰嗎?!?”

莫慌張,放輕松。android小隊又不傻,肯定考慮到了這情況。如果app的targetSdkVersion 低于 23,那將被認為app沒有用23新權限測試過,那將被繼續使用舊有規則:用戶在安裝的時候不得不接受所有權限,安裝后app就有了那些權限咯!

[[149549]]

然后app像以前一樣奔跑!注意,此時用戶依然可以取消已經同意的授權!用戶取消授權時,android 6.0系統會警告,但這不妨礙用戶取消授權。

Android M 新的運行時權限開發者需要知道的一切

問題又來了,這時候你的app崩潰嗎?

善意的主把這事也告訴了android小組,當我們在targetSdkVersion 低于23的app調用一個需要權限的函數時,這個權限如果被用戶取消授權了的話,不拋出異常。但是他將啥都不干,結果導致函數返回值是null或者0.

Android M 新的運行時權限開發者需要知道的一切

別高興的太早。盡管app不會調用這個函數時崩潰,返回值null或者0可能接下來依然導致崩潰。

好消息(至少目前看來)是這類取消權限的情況比較少,我相信很少用戶這么搞。如果他們這么辦了,后果自負咯。

但從長遠看來,我相信還是會有大量用戶會關閉一些權限。我們app不能再新設備完美運行這是不可接受的。

怎樣讓他完美運行呢,你最好修改代碼支持最新的權限系統,而且我建議你立刻著手搞起!

代碼沒有成功改為支持最新運行時權限的app,不要設置targetSdkVersion 23 發布,否則你就有麻煩了。只有當你測試過了,再改為targetSdkVersion 23 。

警告:現在你在android studio新建項目,targetSdkVersion 會自動設置為 23。如果你還沒支持新運行時權限,我建議你首先把targetSdkVersion 降級到22

PROTECTION_NORMAL類權限

當用戶安裝或更新應用時,系統將授予應用所請求的屬于 PROTECTION_NORMAL 的所有權限(安裝時授權的一類基本權限)。這類權限包括:


  1. android.permission.ACCESS_LOCATION_EXTRA_COMMANDS 
  2. android.permission.ACCESS_NETWORK_STATE 
  3. android.permission.ACCESS_NOTIFICATION_POLICY 
  4. android.permission.ACCESS_WIFI_STATE 
  5. android.permission.ACCESS_WIMAX_STATE 
  6. android.permission.BLUETOOTH 
  7. android.permission.BLUETOOTH_ADMIN 
  8. android.permission.BROADCAST_STICKY 
  9. android.permission.CHANGE_NETWORK_STATE 
  10. android.permission.CHANGE_WIFI_MULTICAST_STATE 
  11. android.permission.CHANGE_WIFI_STATE 
  12. android.permission.CHANGE_WIMAX_STATE 
  13. android.permission.DISABLE_KEYGUARD 
  14. android.permission.EXPAND_STATUS_BAR 
  15. android.permission.FLASHLIGHT 
  16. android.permission.GET_ACCOUNTS 
  17. android.permission.GET_PACKAGE_SIZE 
  18. android.permission.INTERNET 
  19. android.permission.KILL_BACKGROUND_PROCESSES 
  20. android.permission.MODIFY_AUDIO_SETTINGS 
  21. android.permission.NFC 
  22. android.permission.READ_SYNC_SETTINGS 
  23. android.permission.READ_SYNC_STATS 
  24. android.permission.RECEIVE_BOOT_COMPLETED 
  25. android.permission.REORDER_TASKS 
  26. android.permission.REQUEST_INSTALL_PACKAGES 
  27. android.permission.SET_TIME_ZONE 
  28. android.permission.SET_WALLPAPER 
  29. android.permission.SET_WALLPAPER_HINTS 
  30. android.permission.SUBSCRIBED_FEEDS_READ 
  31. android.permission.TRANSMIT_IR 
  32. android.permission.USE_FINGERPRINT 
  33. android.permission.VIBRATE 
  34. android.permission.WAKE_LOCK 
  35. android.permission.WRITE_SYNC_SETTINGS 
  36. com.android.alarm.permission.SET_ALARM 
  37. com.android.launcher.permission.INSTALL_SHORTCUT 
  38. com.android.launcher.permission.UNINSTALL_SHORTCUT 

只需要在AndroidManifest.xml中簡單聲明這些權限就好,安裝時就授權。不需要每次使用時都檢查權限,而且用戶不能取消以上授權。

#p#

讓你的app支持新運行時權限

是時候讓我們的app支持新權限模型了,從設置compileSdkVersion andtargetSdkVersion 為 23開始吧.


  1. android { 
  2.     compileSdkVersion 23 
  3.     ... 
  4.  
  5.     defaultConfig { 
  6.         ... 
  7.         targetSdkVersion 23 
  8.         ... 
  9.     } 

例子,我想用一下方法添加聯系人。


  1. private static final String TAG = "Contacts"
  2. private void insertDummyContact() { 
  3.     // Two operations are needed to insert a new contact. 
  4.     ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(2); 
  5.  
  6.     // First, set up a new raw contact. 
  7.     ContentProviderOperation.Builder op = 
  8.             ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) 
  9.                     .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null
  10.                     .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null); 
  11.     operations.add(op.build()); 
  12.  
  13.     // Next, set the name for the contact. 
  14.     op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) 
  15.             .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0
  16.             .withValue(ContactsContract.Data.MIMETYPE, 
  17.                     ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) 
  18.             .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, 
  19.                     "__DUMMY CONTACT from runtime permissions sample"); 
  20.     operations.add(op.build()); 
  21.  
  22.     // Apply the operations. 
  23.     ContentResolver resolver = getContentResolver(); 
  24.     try { 
  25.         resolver.applyBatch(ContactsContract.AUTHORITY, operations); 
  26.     } catch (RemoteException e) { 
  27.         Log.d(TAG, "Could not add a new contact: " + e.getMessage()); 
  28.     } catch (OperationApplicationException e) { 
  29.         Log.d(TAG, "Could not add a new contact: " + e.getMessage()); 
  30.     } 

上面代碼需要WRITE_CONTACTS權限。如果不詢問授權,app就崩了。

下一步像以前一樣在AndroidManifest.xml添加聲明權限。


  1. <uses-permission android:name="android.permission.WRITE_CONTACTS"/> 

下一步,不得不再寫個方法檢查有沒有權限。如果沒有彈個對話框詢問用戶授權。然后你才可以下一步創建聯系人。

權限被分組了,如下表:

Android M 新的運行時權限開發者需要知道的一切

同一組的任何一個權限被授權了,其他權限也自動被授權。例如,一旦WRITE_CONTACTS被授權了,app也有READ_CONTACTS和GET_ACCOUNTS了。

源碼中被用來檢查和請求權限的方法分別是Activity的checkSelfPermission和requestPermissions。這些方法api23引入。


  1. final private int REQUEST_CODE_ASK_PERMISSIONS = 123
  2.  
  3. private void insertDummyContactWrapper() { 
  4.     int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_CONTACTS); 
  5.     if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) { 
  6.         requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS}, 
  7.                 REQUEST_CODE_ASK_PERMISSIONS); 
  8.         return
  9.     } 
  10.     insertDummyContact(); 

如果已有權限,insertDummyContact()會執行。否則,requestPermissions被執行來彈出請求授權對話框,如下:

Android M 新的運行時權限開發者需要知道的一切

不論用戶同意還是拒絕,activity的onRequestPermissionsResult會被回調來通知結果(通過第三個參數),grantResults,如下:


  1. @Override 
  2. public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 
  3.     switch (requestCode) { 
  4.         case REQUEST_CODE_ASK_PERMISSIONS: 
  5.             if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
  6.                 // Permission Granted 
  7.                 insertDummyContact(); 
  8.             } else { 
  9.                 // Permission Denied 
  10.                 Toast.makeText(MainActivity.this"WRITE_CONTACTS Denied", Toast.LENGTH_SHORT) 
  11.                         .show(); 
  12.             } 
  13.             break
  14.         default
  15.             super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
  16.     } 

這就是新權限模型工作過程。代碼真復雜但是只能去習慣它。。。為了讓app很好兼容新權限模型,你不得不用以上類似方法處理所有需要的情況。

如果你想捶墻,現在是時候了。。。

處理 “不再提醒”

如果用戶拒絕某授權。下一次彈框,用戶會有一個“不再提醒”的選項的來防止app以后繼續請求授權。

Android M 新的運行時權限開發者需要知道的一切

如果這個選項在拒絕授權前被用戶勾選了。下次為這個權限請求requestPermissions時,對話框就不彈出來了,結果就是,app啥都不干。

這將是很差的用戶體驗,用戶做了操作卻得不到響應。這種情況需要好好處理一下。在請求requestPermissions前,我們需要檢查是否需要展示請求權限的提示通過activity的shouldShowRequestPermissionRationale,代碼如下:


  1. final private int REQUEST_CODE_ASK_PERMISSIONS = 123
  2.  
  3. private void insertDummyContactWrapper() { 
  4.     int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_CONTACTS); 
  5.     if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) { 
  6.             if (!shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CONTACTS)) { 
  7.                 showMessageOKCancel("You need to allow access to Contacts"
  8.                         new DialogInterface.OnClickListener() { 
  9.                             @Override 
  10.                             public void onClick(DialogInterface dialog, int which) { 
  11.                                 requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS}, 
  12.                                         REQUEST_CODE_ASK_PERMISSIONS); 
  13.                             } 
  14.                         }); 
  15.                 return
  16.             } 
  17.         requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS}, 
  18.                 REQUEST_CODE_ASK_PERMISSIONS); 
  19.         return
  20.     } 
  21.     insertDummyContact(); 
  22.  
  23. private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) { 
  24.     new AlertDialog.Builder(MainActivity.this
  25.             .setMessage(message) 
  26.             .setPositiveButton("OK", okListener) 
  27.             .setNegativeButton("Cancel"null
  28.             .create() 
  29.             .show(); 

當一個權限第一次被請求和用戶標記過不再提醒的時候,我們寫的對話框被展示。

后一種情況,onRequestPermissionsResult 會收到PERMISSION_DENIED ,系統詢問對話框不展示。

Android M 新的運行時權限開發者需要知道的一切

搞定!

#p#

一次請求多個權限

當然了有時候需要好多權限,可以用上面方法一次請求多個權限。不要忘了為每個權限檢查“不再提醒”的設置。

修改后的代碼:


  1. final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124
  2.  
  3. private void insertDummyContactWrapper() { 
  4.     List<String> permissionsNeeded = new ArrayList<String>(); 
  5.  
  6.     final List<String> permissionsList = new ArrayList<String>(); 
  7.     if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION)) 
  8.         permissionsNeeded.add("GPS"); 
  9.     if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS)) 
  10.         permissionsNeeded.add("Read Contacts"); 
  11.     if (!addPermission(permissionsList, Manifest.permission.WRITE_CONTACTS)) 
  12.         permissionsNeeded.add("Write Contacts"); 
  13.  
  14.     if (permissionsList.size() > 0) { 
  15.         if (permissionsNeeded.size() > 0) { 
  16.             // Need Rationale 
  17.             String message = "You need to grant access to " + permissionsNeeded.get(0); 
  18.             for (int i = 1; i < permissionsNeeded.size(); i++) 
  19.                 message = message + ", " + permissionsNeeded.get(i); 
  20.             showMessageOKCancel(message, 
  21.                     new DialogInterface.OnClickListener() { 
  22.                         @Override 
  23.                         public void onClick(DialogInterface dialog, int which) { 
  24.                             requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), 
  25.                                     REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); 
  26.                         } 
  27.                     }); 
  28.             return
  29.         } 
  30.         requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), 
  31.                 REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); 
  32.         return
  33.     } 
  34.  
  35.     insertDummyContact(); 
  36.  
  37. private boolean addPermission(List<String> permissionsList, String permission) { 
  38.     if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { 
  39.         permissionsList.add(permission); 
  40.         // Check for Rationale Option 
  41.         if (!shouldShowRequestPermissionRationale(permission)) 
  42.             return false
  43.     } 
  44.     return true

如果所有權限被授權,依然回調onRequestPermissionsResult,我用hashmap讓代碼整潔便于閱讀。


  1. @Override 
  2. public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 
  3.     switch (requestCode) { 
  4.         case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: 
  5.             { 
  6.             Map<String, Integer> perms = new HashMap<String, Integer>(); 
  7.             // Initial 
  8.             perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED); 
  9.             perms.put(Manifest.permission.READ_CONTACTS, PackageManager.PERMISSION_GRANTED); 
  10.             perms.put(Manifest.permission.WRITE_CONTACTS, PackageManager.PERMISSION_GRANTED); 
  11.             // Fill with results 
  12.             for (int i = 0; i < permissions.length; i++) 
  13.                 perms.put(permissions[i], grantResults[i]); 
  14.             // Check for ACCESS_FINE_LOCATION 
  15.             if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED 
  16.                     && perms.get(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED 
  17.                     && perms.get(Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) { 
  18.                 // All Permissions Granted 
  19.                 insertDummyContact(); 
  20.             } else { 
  21.                 // Permission Denied 
  22.                 Toast.makeText(MainActivity.this"Some Permission is Denied", Toast.LENGTH_SHORT) 
  23.                         .show(); 
  24.             } 
  25.             } 
  26.             break
  27.         default
  28.             super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
  29.     } 

條件靈活的,你自己設置。有的情況,一個權限沒有授權,就不可用;但是也有情況,能工作,但是表現的是有所限制的。對于這個我不做評價,你自己設計吧。

用兼容庫使代碼兼容舊版

以上代碼在android 6.0以上運行沒問題,但是23 api之前就不行了,因為沒有那些方法。

粗暴的方法是檢查版本


  1. if (Build.VERSION.SDK_INT >= 23) { 
  2.     // Marshmallow+ 
  3. else { 
  4.     // Pre-Marshmallow 

但是太復雜,我建議用v4兼容庫,已對這個做過兼容,用這個方法代替:

  • ContextCompat.checkSelfPermission()
    被授權函數返回PERMISSION_GRANTED,否則返回PERMISSION_DENIED ,在所有版本都是如此。
  • ActivityCompat.requestPermissions()
    這個方法在M之前版本調用,OnRequestPermissionsResultCallback 直接被調用,帶著正確的 PERMISSION_GRANTED或者 PERMISSION_DENIED 。
  • ActivityCompat.shouldShowRequestPermissionRationale()
    在M之前版本調用,永遠返回false。
    用v4包的這三方法,完美兼容所有版本!這個方法需要額外的參數,Context or Activity。別的就沒啥特別的了。下面是代碼:

  1. private void insertDummyContactWrapper() { 
  2.     int hasWriteContactsPermission = ContextCompat.checkSelfPermission(MainActivity.this
  3.             Manifest.permission.WRITE_CONTACTS); 
  4.     if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) { 
  5.         if (!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this
  6.                 Manifest.permission.WRITE_CONTACTS)) { 
  7.             showMessageOKCancel("You need to allow access to Contacts"
  8.                     new DialogInterface.OnClickListener() { 
  9.                         @Override 
  10.                         public void onClick(DialogInterface dialog, int which) { 
  11.                             ActivityCompat.requestPermissions(MainActivity.this
  12.                                     new String[] {Manifest.permission.WRITE_CONTACTS}, 
  13.                                     REQUEST_CODE_ASK_PERMISSIONS); 
  14.                         } 
  15.                     }); 
  16.             return
  17.         } 
  18.         ActivityCompat.requestPermissions(MainActivity.this
  19.                 new String[] {Manifest.permission.WRITE_CONTACTS}, 
  20.                 REQUEST_CODE_ASK_PERMISSIONS); 
  21.         return
  22.     } 
  23.     insertDummyContact(); 

后兩個方法,我們也可以在Fragment中使用,用v13兼容包:FragmentCompat.requestPermissions() and FragmentCompat.shouldShowRequestPermissionRationale().和activity效果一樣。

第三方庫簡化代碼

以上代碼真尼瑪復雜。為解決這事,有許多第三方庫已經問世了,真屌真有速度。我試了很多最終找到了個滿意的hotchemi’s PermissionsDispatcher

他和我上面做的一樣,只是簡化了代碼。靈活易擴展,試一下吧。如果不滿足你可以找些其他的。

如果我的app還開著呢,權限被撤銷了,會發生生么

權限隨時可以被撤銷。

[[149550]]

當app開著的時候被撤消了會發生什么呢?我試過了發現這時app會突然終止 terminated。app中的一切都被簡單粗暴的停止了,因為terminated!對我來說這可以理解,因為系統如果允許它繼續運行(沒有某權 限),這會召喚弗雷迪到我的噩夢里。或許更糟…

結論建議

我相信你對新權限模型已經有了清晰的認識。我相信你也意識到了問題的嚴峻。
但是你沒得選擇。新運行時權限已經在棉花糖中被使用了。我們沒有退路。我們現在唯一能做的就是保證app適配新權限模型.
欣慰的是只有少數權限需要運行時權限模型。大多數常用的權限,例如,網絡訪問,屬于Normal Permission 在安裝時自動會授權,當然你要聲明,以后無需檢查。因此,只有少部分代碼你需要修改。

兩個建議:

1.嚴肅對待新權限模型
2.如果你代碼沒支持新權限,不要設置targetSdkVersion 23 。尤其是當你在Studio新建工程時,不要忘了修改!

說一下代碼修改。這是大事,如果代碼結構被設計的不夠好,你需要一些很蛋疼的重構。每個app都要被修正。如上所說,我們沒的選擇。。。

列出所有你需要請求的權限所有情形,如果A被授權,B被拒絕,會發生什么。blah,blah。

祝重構順利。把它列為你需要做的大事,從現在就開始著手做,以保證M正式發布的時候沒有問題。

希望本文對你有用,快樂編碼!

責任編輯:倪明 來源: 碼農網
相關推薦

2015-08-31 09:41:38

androidM權限

2023-02-10 08:44:05

KafkaLinkedIn模式

2020-11-17 10:38:40

云計算工具技術

2023-02-27 15:47:31

2022-07-06 10:07:21

物聯網IoT

2023-10-12 07:06:32

2023-10-12 09:42:44

2022-09-01 15:26:45

物聯網人工智能傳感器

2022-04-24 09:00:00

滲透測試安全數字時代

2022-12-30 11:24:21

2018-06-15 23:00:56

2023-09-11 07:36:35

2021-12-29 14:24:12

物聯網IoT5G

2019-05-24 08:54:13

2022-07-15 14:58:26

數據分析人工智能IT

2014-07-17 09:31:50

iOS8SDK

2022-08-27 12:15:51

Linux Mint操作系統

2023-03-23 14:31:35

2017-04-29 09:00:14

Linux程序進程

2019-05-22 15:10:43

點贊
收藏

51CTO技術棧公眾號

青青草精品毛片| 在线电影国产精品| 青青草久久网络| 亚洲av无码乱码国产精品fc2| 欧美色女视频| 欧美高清视频在线高清观看mv色露露十八 | 国产一级免费av| 欧美人妖视频| 在线不卡一区二区| 久青草视频在线播放| 人人九九精品| 美女www一区二区| 欧美老少配视频| 日韩人妻一区二区三区| 福利视频一区| 亚洲二区在线观看| 日产国产精品精品a∨| 国产不卡av在线播放| 香蕉国产精品偷在线观看不卡| 自拍亚洲一区欧美另类| 一区二区在线免费观看视频| 亚洲成人看片| 亚洲国产综合91精品麻豆| 日本一区美女| 欧美在线 | 亚洲| 蜜乳av一区二区三区| 欧美精品激情在线| 国产在线免费看| 秋霞蜜臀av久久电影网免费 | 国产同性人妖ts口直男| 久久国产直播| 欧美激情喷水视频| 蜜桃av.com| 国产一区二区三区四区二区 | 国产精品久久久久久久7电影| 久久久久久久蜜桃| 99久久夜色精品国产亚洲狼| 日韩国产在线播放| 欧美丰满熟妇bbb久久久| 国产成人福利夜色影视| 日韩欧美亚洲成人| 18禁免费观看网站| 免费在线观看av电影| 国产精品乱码妇女bbbb| 日本精品一区| 欧美zzoo| 久久久久国产精品麻豆ai换脸| 国产精品久久久久久久久婷婷| 国产精品乱码久久久| 青青草精品视频| 国产精品大片wwwwww| 日韩 欧美 综合| 亚洲国产综合在线看不卡| 九九精品在线视频| 黄色一级视频免费观看| 婷婷综合久久| 欧美成人剧情片在线观看| 成人18视频免费69| 五月精品视频| 中文字幕视频一区二区在线有码| 国产交换配乱淫视频免费| 欧美大胆视频| 亚洲欧美在线免费| 免费看黄色的视频| 精品一区二区三区中文字幕老牛| 亚洲免费中文字幕| 成熟人妻av无码专区| 不卡日本视频| 精品国产一区二区三区久久狼黑人| jizz18女人高潮| 天天射综合网视频| 美女福利精品视频| 久久精品国产亚洲av麻豆色欲 | 特级西西444www大胆免费看| 日韩不卡免费视频| 91久久精品美女| 亚洲av综合色区无码一区爱av| 丁香六月久久综合狠狠色| 国产精品一区二区三区免费观看| 亚洲 精品 综合 精品 自拍| 久久久五月婷婷| 亚洲欧美成人一区| 成人在线观看亚洲| 亚洲成a人片在线不卡一二三区| 131美女爱做视频| 婷婷综合六月| 3d动漫精品啪啪一区二区竹菊| www.久久久久久久久久久| 中文一区二区三区四区| 亚洲精品视频免费| 三级黄色免费观看| 亚洲激情国产| 国产精品久久久久福利| 国产视频手机在线| 91香蕉视频在线| 一区二区在线高清视频| av在线理伦电影| 欧美午夜电影网| 国产精品99久久久精品无码| 在线日本制服中文欧美| www日韩欧美| 亚洲免费激情视频| 久久国产日韩欧美精品| 国产精品视频在线免费观看 | 久久伊人免费视频| 国产精品视频久久久久久久| 久久国产精品99精品国产| 国产精品10p综合二区| 国产视频网址在线| 亚洲成av人片| 日本国产一级片| 色吊丝一区二区| 久久成人这里只有精品| 午夜精品一区二| 粉嫩av一区二区三区在线播放| 日韩激情视频| hd国产人妖ts另类视频| 7777精品伊人久久久大香线蕉最新版| 噜噜噜在线视频| 亚洲最大av| 国产精品美女999| 五月天婷婷社区| 亚洲精品久久久蜜桃| 搡女人真爽免费午夜网站| 国产精品高潮呻吟久久久久| 日韩在线视频免费观看高清中文 | 欧美亚洲图片小说| 性欧美丰满熟妇xxxx性久久久| 一本一道久久a久久精品蜜桃| 国产成人精品最新| 四虎电影院在线观看| 亚洲一区二区三区视频在线 | 亚洲精品色婷婷福利天堂| 青草草在线视频| 久99久精品视频免费观看| 日本高清一区| 午夜精品久久久久久久久久蜜桃| 亚洲第一精品夜夜躁人人躁 | 日漫免费在线观看网站| 亚洲一区二区欧美激情| 中文字幕第66页| 我不卡影院28| 成人国内精品久久久久一区| 国产粉嫩一区二区三区在线观看| 疯狂欧美牲乱大交777| 少妇精品无码一区二区| 中文字幕一区二区三区久久网站| 国产精品一区电影| av在线播放网站| 欧美影院精品一区| 你懂得视频在线观看| 久久一本综合频道| 欧美亚洲精品日韩| 朝桐光一区二区| 国产亚洲精品久久久久久牛牛| 69视频免费在线观看| 久久综合色鬼综合色| av网站在线观看不卡| 亚洲亚洲免费| 国产精品成人va在线观看| av亚洲在线| 欧美日韩不卡一区| 日韩影院一区二区| 国产盗摄精品一区二区三区在线| 精品免费久久久久久久| 电影一区二区在线观看| 午夜精品久久久久久久男人的天堂 | 亚洲精品麻豆| 久久婷婷人人澡人人喊人人爽| www成人免费观看| 亚洲欧美日本精品| 亚洲av无码乱码国产精品fc2| 国产精品久久久久影院亚瑟| av免费一区二区| 中文字幕一区二区精品区| 国产精品亚洲一区| 在线天堂新版最新版在线8| 亚洲三级av在线| 中文字幕乱码一区二区| 亚洲精品你懂的| 亚洲911精品成人18网站| 在线日韩电影| 日韩精品久久久毛片一区二区| 久久伊人国产| 久久久亚洲国产天美传媒修理工| 亚洲三区在线播放| 欧美日韩久久不卡| 玖玖爱免费视频| 久久精品一二三| 激情久久综合网| 亚洲女优在线| 欧美亚洲视频一区| 日本三级久久| 91在线观看免费网站| 理论不卡电影大全神| 在线播放亚洲激情| 丁香花免费高清完整在线播放 | 超碰在线成人| 国产精品久久久久久久久免费| 在线视频国产区| 亚洲码在线观看| 国产成人a人亚洲精品无码| 欧美视频13p| 亚洲欧美小视频| 久久久久99精品国产片| 国产农村妇女精品久久| 久久国产精品久久w女人spa| 久久久久亚洲av无码专区喷水| 欧美sss在线视频| 51成人做爰www免费看网站| 亚洲精品中文字幕| 久久九九精品99国产精品| 亚洲av成人无码网天堂| 日韩一区二区三| 你懂的国产视频| 欧美国产欧美综合| 无码一区二区精品| 国产精品一区二区黑丝| wwww.国产| 国产欧美日韩一级| 国产激情在线看| 四季av一区二区凹凸精品| 麻豆av一区| 国产欧美三级电影| 1卡2卡3卡精品视频| 精品美女一区| 国产精品xxx视频| 午夜影院在线观看国产主播| 久精品免费视频| 黄色大片在线播放| 色琪琪综合男人的天堂aⅴ视频| 亚洲色偷精品一区二区三区| 日韩免费观看高清完整版 | 青青草国产精品亚洲专区无| 日韩精品视频一区二区在线观看| 欧美视频亚洲视频| 大陆极品少妇内射aaaaaa| 色喇叭免费久久综合| 日本午夜精品一区二区三区| 欧美顶级毛片在线播放| 国产经品一区二区| 精品久久对白| 91嫩草免费看| 97视频一区| 成人精品水蜜桃| 99这里只有精品视频| 成人91视频| 成人av影音| 激情一区二区三区| 美女视频免费精品| 久久综合婷婷综合| 亚洲最好看的视频| 欧美日韩大片一区二区三区 | 日韩精品在线播放| 五月婷婷在线播放| 日韩成人中文字幕| 免费在线毛片| 在线不卡国产精品| 免费黄网站在线| 欧美成人午夜激情在线| 午夜在线激情影院| 韩国美女主播一区| 一二三四视频在线中文| 国产成人精品午夜| 91麻豆精品| 99视频免费观看| 国产精品流白浆在线观看| 精品欧美国产一区二区三区不卡| 日韩大片在线免费观看| 日本一区免费看| 欧美超碰在线| av在线免费观看国产| 99综合精品| 精品日韩久久久| 国产精品小仙女| 免费a在线观看播放| 国产色综合一区| 欧美偷拍第一页| 午夜电影久久久| 亚洲成人av网址| 91精品国产综合久久福利软件| 亚洲黄色小说网| 亚洲乱码国产乱码精品精天堂| 思思99re6国产在线播放| 欧美夫妻性生活xx| 婷婷激情一区| 亚洲综合日韩在线| 中文精品一区二区| 今天免费高清在线观看国语| 亚洲精一区二区三区| 美女一区二区三区视频| 国产精品99久久久久久久女警| 亚洲av无码一区二区三区网址| 欧美国产一区二区在线观看| 婷婷色中文字幕| 91成人网在线| 成人午夜免费在线观看| 中文字幕亚洲一区二区三区| av免费在线视| 国产综合久久久久久| 开心激情综合| 艳母动漫在线免费观看| 亚洲综合三区| 中文字幕在线观看视频www| 国产亚洲欧美日韩在线一区| 日韩女优一区二区| 在线观看国产日韩| 婷婷色在线观看| 久久夜色精品国产欧美乱| 电影久久久久久| 国产精品久久久久久久久久久久冷| 日韩精品影视| 无码aⅴ精品一区二区三区浪潮| 国产在线精品免费| 亚洲av熟女国产一区二区性色| 亚洲第一av色| 99国产精品一区二区三区| 一区二区三区亚洲| 欧美男男激情videos| 成人av播放| 68国产成人综合久久精品| 日本www高清视频| 91一区在线观看| 久久亚洲国产成人精品性色| 欧美日韩成人在线| 中国日本在线视频中文字幕| 人人做人人澡人人爽欧美| 久草精品视频| 91免费黄视频| 国产成人av电影在线观看| 天天操夜夜操av| 欧美日韩国产另类一区| 成人高清免费在线播放| 热门国产精品亚洲第一区在线| 欧美交a欧美精品喷水| av片在线免费| 国产成人精品影院| 深夜福利影院在线观看| 欧美丰满高潮xxxx喷水动漫| 91涩漫在线观看| 国产精品日韩专区| 欧美日韩中字| 欧美第一页浮力影院| 欧美经典三级视频一区二区三区| 天堂中文在线网| 亚洲欧美精品一区| 625成人欧美午夜电影| 久久综合入口| 麻豆9191精品国产| 免费视频91蜜桃| 欧美性受极品xxxx喷水| 国产精品久久久久一区二区国产| 日韩av理论片| 欧美性感美女一区二区| 久久99999| **性色生活片久久毛片| 97超碰人人模人人人爽人人爱| 日日噜噜噜夜夜爽亚洲精品| 欧美一级做a| 伊人网在线免费| 粉嫩嫩av羞羞动漫久久久| 日产精品久久久久| 亚洲欧美制服另类日韩| 日韩av超清在线观看| 一级二级三级欧美| 国产精品99久| 男女啊啊啊视频| 亚洲四色影视在线观看| 91国拍精品国产粉嫩亚洲一区| 一本色道婷婷久久欧美| 国产精品一二三| 国产精品一区二区6| 在线看日韩欧美| 欧美视频三区| 免费毛片网站在线观看| 国产亚洲va综合人人澡精品| 中文字幕人妻互换av久久| 插插插亚洲综合网| 日韩深夜影院| 狠狠操狠狠干视频| 亚洲国产视频网站| 极品美乳网红视频免费在线观看| 国产精品第一页在线| 欧美女激情福利| 少妇精品一区二区三区| 欧美精品亚洲一区二区在线播放| 欧美日韩色网| 日本一区二区三区视频在线观看 | 亚洲精品国产偷自在线观看| 亚洲欧洲国产视频| 欧美在线视频全部完| 91网址在线观看| 欧洲av一区| 成人综合婷婷国产精品久久 | 日韩av不卡一区二区| 日韩一区二区不卡视频| 亚洲精品美女久久久久| 成人国产精品一区二区免费麻豆| 国产一线二线三线女| 国产视频一区二区三区在线观看|