Android 6.0許可權全面詳細分析和解決方案

来源:http://www.cnblogs.com/l2rf/archive/2016/10/08/5937490.html
-Advertisement-
Play Games

原文: http://www.2cto.com/kf/201512/455888.html http://blog.csdn.net/yangqingqo/article/details/48371123 http://inthecheesefactory.com/blog/things-you-n ...


原文:

http://www.2cto.com/kf/201512/455888.html

http://blog.csdn.net/yangqingqo/article/details/48371123

http://inthecheesefactory.com/blog/things-you-need-to-know-about-Android-m-permission-developer-edition/en

 

一、Marshmallow版本許可權簡介

android的許可權系統一直是首要的安全概念,因為這些許可權只在安裝的時候被詢問一次。一旦安裝了,app可以在用戶毫不知曉的情況下訪問許可權內的所有東西,而且一般用戶安裝的時候很少會去仔細看許可權列表,更不會去深入瞭解這些許可權可能帶來的相關危害。所以在android 6.0 Marshmallow版本之後,系統不會在軟體安裝的時候就賦予該app所有其申請的許可權,對於一些危險級別的許可權,app需要在運行時一個一個詢問用戶授予許可權。



二、舊版本app相容問題

  那麼問題來了,是不是所有以前發佈的app都會出現問題呢?答案是不會,只有那些targetSdkVersion 設置為23和23以上的應用才會出現異常,在使用危險許可權的時候系統必須要獲得用戶的同意才能使用,要不然應用就會崩潰,出現類似
java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider

的崩潰日誌。所以targetSdkVersion如果沒有設置為23版本或者以上,系統還是會使用舊規則:在安裝的時候賦予該app所申請的所有許可權。所以app當然可以和以前一樣正常使用了,但是還有一點需要註意的是6.0的系統裡面,用戶可以手動將該app的許可權關閉,如下圖

  
  那麼問題又來了,如果以前的老應用申請的許可權被用戶手動關閉了怎麼辦,應用會崩潰麽?我們來試一試
  這裡寫圖片描述
  好吧,可以慶幸了一下了,不會拋出異常,不會崩潰,只不過調用那些被用戶禁止許可權的api介面返回值都為null或者0,所以我們只需要做一下判空操作就可以了,不判空當然還是會崩潰的嘍。


三、普通許可權和危險許可權列表

  現在對於新版本的許可權變更應該有了基本的認識,那麼,是不是所有許可權都需要去進行特殊處理呢?當然不是,只有那些危險級別的許可權才需要。

 

PROTECTION_NORMAL類許可權

 

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

android.permission.ACCESS LOCATIONEXTRA_COMMANDS 
android.permission.ACCESS NETWORKSTATE 
android.permission.ACCESS NOTIFICATIONPOLICY 
android.permission.ACCESS WIFISTATE 
android.permission.ACCESS WIMAXSTATE 
android.permission.BLUETOOTH 
android.permission.BLUETOOTH_ADMIN 
android.permission.BROADCAST_STICKY 
android.permission.CHANGE NETWORKSTATE 
android.permission.CHANGE WIFIMULTICAST_STATE 
android.permission.CHANGE WIFISTATE 
android.permission.CHANGE WIMAXSTATE 
android.permission.DISABLE_KEYGUARD 
android.permission.EXPAND STATUSBAR 
android.permission.FLASHLIGHT 
android.permission.GET_ACCOUNTS 
android.permission.GET PACKAGESIZE 
android.permission.INTERNET 
android.permission.KILL BACKGROUNDPROCESSES 
android.permission.MODIFY AUDIOSETTINGS 
android.permission.NFC 
android.permission.READ SYNCSETTINGS 
android.permission.READ SYNCSTATS 
android.permission.RECEIVE BOOTCOMPLETED 
android.permission.REORDER_TASKS 
android.permission.REQUEST INSTALLPACKAGES 
android.permission.SET TIMEZONE 
android.permission.SET_WALLPAPER 
android.permission.SET WALLPAPERHINTS 
android.permission.SUBSCRIBED FEEDSREAD 
android.permission.TRANSMIT_IR 
android.permission.USE_FINGERPRINT 
android.permission.VIBRATE 
android.permission.WAKE_LOCK 
android.permission.WRITE SYNCSETTINGS 
com.android.alarm.permission.SET_ALARM 
com.android.launcher.permission.INSTALL_SHORTCUT 
com.android.launcher.permission.UNINSTALL_SHORTCUT

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

危險許可權

 

Permission GroupPermissions
android.permission-group.CALENDAR
  • android.permission.READ_CALENDAR
  • android.permission.WRITE_CALENDAR
android.permission-group.CAMERA
  • android.permission.CAMERA
android.permission-group.CONTACTS
  • android.permission.READ_CONTACTS
  • android.permission.WRITE_CONTACTS
  • android.permission.GET_ACCOUNTS
android.permission-group.LOCATION
  • android.permission.ACCESS_FINE_LOCATION
  • android.permission.ACCESS_COARSE_LOCATION
android.permission-group.MICROPHONE
  • android.permission.RECORD_AUDIO
android.permission-group.PHONE
  • android.permission.READ_PHONE_STATE
  • android.permission.CALL_PHONE
  • android.permission.READ_CALL_LOG
  • android.permission.WRITE_CALL_LOG
  • com.android.voicemail.permission.ADD_VOICEMAIL
  • android.permission.USE_SIP
  • android.permission.PROCESS_OUTGOING_CALLS
android.permission-group.SENSORS
  • android.permission.BODY_SENSORS
android.permission-group.SMS
  • android.permission.SEND_SMS
  • android.permission.RECEIVE_SMS
  • android.permission.READ_SMS
  • android.permission.RECEIVE_WAP_PUSH
  • android.permission.RECEIVE_MMS
  • android.permission.READ_CELL_BROADCASTS
android.permission-group.STORAGE
  • android.permission.READ_EXTERNAL_STORAGE
  • android.permission.WRITE_EXTERNAL_STORAGE

 

 

  android開發者官網也有相關描述:
  http://developer.android.com/training/permissions/requesting.html
  http://developer.android.com/guide/topics/security/permissions.html

  所以仔細去看看自己的app,對照列表,如果有需要申請其中的一個許可權,就需要進行特殊操作。還有一個比較人性的地方就是如果同一組的任何一個許可權被授權了,其他許可權也自動被授權。例如,一旦WRITE_EXTERNAL_STORAGE被授權了,app也有READ_EXTERNAL_STORAGE許可權了。

 

四、支持Marshmallow新版本許可權機制

關於許可權控制主要使用到

PermissionChecker類的checkSelfPermission();

ActivityCompat類的

   public static boolean shouldShowRequestPermissionRationale(@NonNull Activity activity,
            @NonNull String permission) 

Fragment類的

 public boolean shouldShowRequestPermissionRationale(@NonNull String permission) 

ActivityCompat類的

    public static void requestPermissions(final @NonNull Activity activity,
            final @NonNull String[] permissions, final int requestCode) 

Fragment類的

  public final void requestPermissions(@NonNull String[] permissions, int requestCode)

 

終於要開始支持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'
  修改完後,感興趣的朋友可以直接打包在手機上測試一下,看看是不是會出現類似於上面我說的那些崩潰日誌。
  接著下一步當然就是要修改代碼了,最原始代碼,無任何處理:

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");
    ....
}
  這段代碼需要訪問外部存儲(相冊圖片),屬於危險級別的許可權,直接使用會造成應用崩潰,所以在這段代碼執行之前我們需要進行特殊處理:

int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);

if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {

Activity activty=this;

        ActivityCompat.requestPermissions(activty,new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
                CODE_FOR_WRITE_PERMISSION);
    return;
}
  寫完這段代碼之後,就會出現如下系統dialog:
  
  緊接著就需要去處理DENY和ALLOW的回調了,重寫 Activity activity的ActivityCompat.OnRequestPermissionsResultCallback函數:

@Override
public 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();
        }
    }
}
  好了,這樣就算是簡單初步適配完成了。


五、處理不再提醒

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

  

  如果這個選項在拒絕授權前被用戶勾選了。下次為這個許可權請求requestPermissions時,對話框就不彈出來了,系統會直接回調onRequestPermissionsResult函數,回調結果為最後一次用戶的選擇。所以為了應對這種情況,系統提供了一個shouldShowRequestPermissionRationale()函數,這個函數的作用是幫助開發者找到需要向用戶額外解釋許可權的情況,這個函數:
應用安裝後第一次訪問,直接返回false;第一次請求許可權時,用戶拒絕了,下一次shouldShowRequestPermissionRationale()返回 true,這時候可以顯示一些為什麼需要這個許可權的說明;第二次請求許可權時,用戶拒絕了,並選擇了“不再提醒”的選項時:shouldShowRequestPermissionRationale()返回 false;設備的系統設置中禁止當前應用獲取這個許可權的授權,shouldShowRequestPermissionRationale()返回false;  註意:第二次請求許可權時,才會有“不再提醒”的選項,如果用戶一直拒絕,並沒有選擇“不再提醒”的選項,下次請求許可權時,會繼續有“不再提醒”的選項,並且shouldShowRequestPermissionRationale()也會一直返回true。
  所以利用這個函數我們可以進行相應的優化,針對shouldShowRequestPermissionRationale函數返回false的處理有兩種方案。第一種方案:如果應用是第一次請求該許可權,則直接調用requestPermissions函數去請求許可權;如果不是則代表用戶勾選了’不再提醒’,彈出dialog,告訴用戶為什麼你需要該許可權,讓用戶自己手動開啟該許可權。鏈接:http://stackoverflow.com/questions/32347532/android-m-permissions-confused-on-the-usage-of-shouldshowrequestpermissionrati 。第二種方案:在onRequestPermissionsResult函數中進行檢測,如果返回PERMISSION_DENIED,則去調用shouldShowRequestPermissionRationale函數,如果返回false代表用戶已經禁止該許可權(上面的3和4兩種情況),彈出dialog告訴用戶你需要該許可權的理由,讓用戶手動打開。鏈接:http://stackoverflow.com/questions/30719047/android-m-check-runtime-permission-how-to-determine-if-the-user-checked-nev  處理方法已經有了,修改一下代碼,我這裡就以第二種方案來處理了:
 
@Override
public 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{
            //用戶不同意,向用戶展示該許可權作用
            if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                AlertDialog dialog = new AlertDialog.Builder(this)
                        .setMessage("該相冊需要賦予訪問存儲的許可權,不開啟將無法正常工作!")
                        .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,提醒用戶該許可權的重要性:
  
  


六、使用相容庫


  以上的代碼在6.0版本上使用沒有問題,但是在之前就有問題了,最簡單粗暴的解決方法可能就是利用Build.VERSION.SDK_INT >= 23這個判斷語句來判斷了,方便的是SDK 23的v4包加入了專門類進行相關的處理:

ContextCompat.checkSelfPermission()被授權函數返回PERMISSION_GRANTED,否則返回PERMISSION_DENIED ,在所有版本都是如此。ActivityCompat.requestPermissions()這個方法在6.0之前版本調用,OnRequestPermissionsResultCallback 直接被調用,帶著正確的 PERMISSION_GRANTED或者PERMISSION_DENIED。ActivityCompat.shouldShowRequestPermissionRationale()在6.0之前版本調用,永遠返回false。  用v4包的這三方法,完美相容所有版本!下麵是代碼:
//使用相容庫就無需判斷系統版本
int hasWriteContactsPermission = ContextCompat.checkSelfPermission(getApplication(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (hasWriteContactsPermission == PackageManager.PERMISSION_GRANTED) {
    startGetImageThread();
}
//需要彈出dialog讓用戶手動賦予許可權
else{
    ActivityCompat.requestPermissions(PickOrTakeImageActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, CODE_FOR_WRITE_PERMISSION);

}

  onRequestPermissionsResult函數不變。後兩個方法,我們也可以在Fragment中使用,用v13相容包:FragmentCompat.requestPermissions() and FragmentCompat.shouldShowRequestPermissionRationale()和activity效果一樣。



七、一次請求多個許可權


  當然了有時候需要多個許可權,可以用上面方法一次請求多個許可權。當然最重要的是不要忘了為每個許可權檢查“不再提醒”的設置。
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);</string></string>
  最後在onRequestPermissionsResult函數中一個個處理返回結果即可。


八、第三方庫簡化代碼


  當然早就有第三方庫來幫忙做這些事情了:
  Github上的開源項目 PermissionHelper和hotchemi’s PermissionsDispatcher


九、APP處於運行狀態下,被撤銷許可權


  如果APP正在運行中,用戶進入設置-應用程式頁面去手動撤銷該APP許可權,會出現什麼情況呢?哈哈,系統又會接著彈出許可權請求對話框,挺好挺好:
  
  這樣就沒有問題了吧O(∩_∩)O~
  上面的測試環境為genymotion6.0模擬器,有朋友跟我反映在6.0nexus 6p真機上會直接退出應用,所以這個應該還和測試環境有關。


使用相容庫support-v4中的方法   ContextCompat.checkSelfPermission() ActivityCompat.requestPermissions() ActivityCompat.OnRequestPermissionsResultCallback ActivityCompat.shouldShowRequestPermissionRationale() The v4 support library also contains the PermissionChecker class, which provides several static utility methods for apps that use IPC to provide services for other apps. For example,PermissionChecker.checkCallingPermission() checks whether an IPC made by a particular package has a specified permission.   FragmentCompat.requestPermissions() FragmentCompat.shouldShowRequestPermissionRationale()      requestPermissions() 的一些說明:   Note: When your app calls the framework's requestPermissions() method, the system shows a standard dialog box to the user.  Your app cannot configure or alter that dialog box. If you need to provide any information or explanation to the user,  you should do that before you call requestPermissions(), as described in Explain why the app needs permissions.   當調用 requestPermissions() 時,系統會顯示一個獲取許可權的提示對話框,當前應用不能配置和修改這個對話框, 如果需要提示用戶一些這個許可權相關的信息或說明,需要在調用 requestPermissions() 之前處理。   shouldShowRequestPermissionRationale() 的一些說明:    

To help find the situations where you need to provide extra explanation, the system provides theshouldShowRequestPermissionRationale() method. 

This method returns true if the app has requested this permission previously and the user denied the request. 

That indicates that you should probably explain to the user why you need the permission.

 

 

If the user turned down the permission request in the past and chose the Don't ask again option in the permission request system dialog, this method returns false

The method also returns false if the device policy prohibits the app from having that permission.


 

1. 第一次請求許可權時,用戶拒絕了,下一次:shouldShowRequestPermissionRationale()  返回 true,應該顯示一些為什麼需要這個許可權的說明

2.第二次請求許可權時,用戶拒絕了,並選擇了“不在提醒”的選項時:shouldShowRequestPermissionRationale()  返回 false

3. 設備的策略禁止當前應用獲取這個許可權的授權:shouldShowRequestPermissionRationale()  返回 false 

 

註意:上面的:第二次請求許可權時,才會有“不在提醒”的選項,如果用戶一直拒絕,並沒有選擇“不在提醒”的選項,下次請求許可權時,會繼續有“不在提醒”的選項

 

十、shouldShowRequestPermissionRationale() 的方法說明:

 

 

 

Gets whether you should show UI with rationale for requesting a permission.

 You should do this only if you do not have the permission and the context in which the permission is requested does not clearly communicate to the user what would be the benefit from granting this permission.

 

For example, if you write a camera app, requesting the camera permission would be expected by the user and no rationale for why it is requested is needed. If however, the app needs location for tagging photos then a non-tech savvy user may wonder how location is related to taking photos. In this case you may choose to show UI with rationale of requesting this permission.

根據方法說明:
顯示許可權說明:是根據你的應用中使用的許可權分類來的:
1.用戶容易知道應用需要獲取的許可權:如一個拍照應用,需要攝像頭的許可權,是很正常,不用提示。
2.一些用戶感覺困惑的一些許可權:如:分享圖片,還需要獲取位置的許可權,這個需要提示用戶:為什麼需要這個許可權。

 
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • AOS 是一個用於在頁面滾動的時候呈現元素動畫的工具庫,你可能會覺得它和 WOWJS 一樣,的確他們效果是類似的。但是AOS是 CSS3 動畫驅動的庫,當你滾動頁面的時候能讓元素動起來,當頁面滾回頂部的時候,元素能夠回到前一個狀態,如此達到迴圈動畫的效果。 ...
  • 效果圖如下: ...
  • 效果圖: ...
  • 做App測試時監測使用期間的cpu,記憶體,流量,電量等指標時,發現的企鵝很好用的工具。 備份至此,方便後期查閱 以下內容摘抄自企鵝GT官網 http://code.tencent.com/gt.html http://gt.qq.com/ 文檔 http://gt.qq.com/docs.html ...
  • 開發第一應用 可以開發屬於自己的應用,是否有點小激動?好吧!讓我們開始,首先點擊Start a new Android Studio Project創建工程:接下來需要輸入應用名稱(第一個字母要大寫)、公司域以及指定應用存放目錄,點擊Next按鈕進入下一步: 如果第一個字母不是大寫,會提示:The ...
  • 遍歷可變數組的同時刪除數組元素 獲取系統當前語言 UITableView的Group樣式下頂部空白處理 UITableView的plain樣式下,取消區頭停滯效果 獲取某個view所在的控制器 兩種方法刪除NSUserDefaults所有記錄 列印系統所有已註冊的字體名稱 獲取圖片某一點的顏色 字元 ...
  • 最近半年以來,Android熱補丁技術熱潮繼續爆發,各大公司相繼推出自己的開源框架。Tinker在最近也順利完成了公司的審核,並非常榮幸的成為github.com/Tencent上第一個正式公開的項目。 ...
  • 蘋果在iOS10開放了siriKit介面給第三方應用。目前,QQ已經率先適配了Siri的發消息和打電話功能。這意味著在iOS10中你可以直接告訴Siri讓它幫你發QQ消息和打QQ電話了,聽起來是不是很酷炫? 那麼第三方應用使用Siri的體驗究竟如何?哪些應用可以接入SiriKit?接入SiriKi... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...