সমাধান সংক্রান্ত ডায়ালগ

ইন্টিগ্রিটি ফলাফল সংক্রান্ত সমস্যা কীভাবে সমাধান করতে হয় তা এই পৃষ্ঠায় বর্ণনা করা হয়েছে।

ইন্টিগ্রিটি টোকেনের অনুরোধ করা হলে, আপনার কাছে ব্যবহারকারীকে Google Play ডায়ালগ দেখানোর বিকল্প থাকে। ইন্টিগ্রিটি ফলাফলে এক বা একাধিক সমস্যা থাকলে অথবা Integrity API অনুরোধের সময় কোনও ব্যতিক্রম ঘটলে আপনি ডায়ালগ দেখাতে পারেন। ডায়ালগ বন্ধ হয়ে গেলে, আপনি যাচাই করতে পারবেন যে অন্য ইন্টিগ্রিটি টোকেন অনুরোধের মাধ্যমে সমস্যাটি সমাধান করা হয়েছে কিনা। আপনি স্ট্যান্ডার্ড অনুরোধ করলে, নতুন রায় পেতে আপনাকে আবার টোকেন প্রদানকারীকে ওয়ার্ম আপ করতে হবে।

রায় সংক্রান্ত সমস্যার সমাধান করতে ইন্টিগ্রিটি ডায়ালগের অনুরোধ করুন

ক্লায়েন্ট ইন্টিগ্রিটি টোকেনের অনুরোধ করলে, আপনি StandardIntegrityToken (স্ট্যান্ডার্ড API) এবং IntegrityTokenResponse (ক্লাসিক API)-এ অফার করা পদ্ধতি ব্যবহার করতে পারবেন: showDialog(Activity activity, int integrityDialogTypeCode).

GET_LICENSED ডায়ালগ কোড ব্যবহার করে কীভাবে আপনি Play Integrity API-এর মাধ্যমে প্রতিকার ডায়ালগ দেখাতে পারবেন তা নিম্নলিখিত ধাপে উল্লেখ করা হয়েছে। আপনার অ্যাপ অনুরোধ করতে পারে এমন অন্যান্য ডায়ালগ কোড এই বিভাগের পরে তালিকাভুক্ত করা হয়েছে।

  1. আপনার অ্যাপ থেকে ইন্টিগ্রিটি টোকেনের অনুরোধ করুন এবং আপনার সার্ভারে টোকেন পাঠান। আপনি স্ট্যান্ডার্ড বা ক্লাসিক অনুরোধ ব্যবহার করতে পারেন।

    Kotlin

    // Request an integrity token
    val tokenResponse: StandardIntegrityToken = requestIntegrityToken()
    // Send token to app server and get response on what to do next
    val yourServerResponse: YourServerResponse = sendToServer(tokenResponse.token())  

    জাভা

    // Request an integrity token
    StandardIntegrityToken tokenResponse = requestIntegrityToken();
    // Send token to app server and get response on what to do next
    YourServerResponse yourServerResponse = sendToServer(tokenResponse.token());  

    Unity

    // Request an integrity token
    StandardIntegrityToken tokenResponse = RequestIntegrityToken();
    // Send token to app server and get response on what to do next
    YourServerResponse yourServerResponse = sendToServer(tokenResponse.Token); 

    Unreal Engine

    // Request an integrity token
    StandardIntegrityToken* Response = RequestIntegrityToken();
    // Send token to app server and get response on what to do next
    YourServerResponse YourServerResponse = SendToServer(Response->Token); 

    নেটিভ

    /// Request an integrity token
    StandardIntegrityToken* response = requestIntegrityToken();
    /// Send token to app server and get response on what to do next
    YourServerResponse yourServerResponse = sendToServer(StandardIntegrityToken_getToken(response));
  2. আপনার সার্ভারে, ইন্টিগ্রিটি টোকেন ডিক্রিপ্ট করুন এবং appLicensingVerdict ফিল্ড চেক করুন। এটি দেখতে এইরকম হতে পারে:

    // Licensing issue
    {
      ...
      "accountDetails": {
          "appLicensingVerdict": "UNLICENSED"
      }
    }
  3. টোকেনে appLicensingVerdict: "UNLICENSED" থাকলে, আপনার অ্যাপ ক্লায়েন্টকে উত্তর দিন, লাইসেন্সিং ডায়ালগ দেখানোর জন্য অনুরোধ করুন:

    Kotlin

    private fun getDialogTypeCode(integrityToken: String): Int{
      // Get licensing verdict from decrypted and verified integritytoken
      val licensingVerdict: String = getLicensingVerdictFromDecryptedToken(integrityToken)
    
      return if (licensingVerdict == "UNLICENSED") {
              1 // GET_LICENSED
          } else 0
    }

    জাভা

    private int getDialogTypeCode(String integrityToken) {
      // Get licensing verdict from decrypted and verified integrityToken
      String licensingVerdict = getLicensingVerdictFromDecryptedToken(integrityToken);
    
      if (licensingVerdict.equals("UNLICENSED")) {
        return 1; // GET_LICENSED
      }
      return 0;
    }

    Unity

    private int GetDialogTypeCode(string IntegrityToken) {
      // Get licensing verdict from decrypted and verified integrityToken
      string licensingVerdict = GetLicensingVerdictFromDecryptedToken(IntegrityToken);
    
      if (licensingVerdict == "UNLICENSED") {
        return 1; // GET_LICENSED
      }
      return 0;
    } 

    Unreal Engine

    private int GetDialogTypeCode(FString IntegrityToken) {
      // Get licensing verdict from decrypted and verified integrityToken
      FString LicensingVerdict = GetLicensingVerdictFromDecryptedToken(IntegrityToken);
    
      if (LicensingVerdict == "UNLICENSED") {
        return 1; // GET_LICENSED
      }
      return 0;
    } 

    নেটিভ

    private int getDialogTypeCode(string integrity_token) {
      /// Get licensing verdict from decrypted and verified integrityToken
      string licensing_verdict = getLicensingVerdictFromDecryptedToken(integrity_token);
    
      if (licensing_verdict == "UNLICENSED") {
        return 1; // GET_LICENSED
      }
      return 0;
    }
  4. আপনার অ্যাপে, আপনার সার্ভার থেকে পাওয়া অনুরোধ করা কোড সহ showDialog কল করুন:

    Kotlin

    // Show dialog as indicated by the server
    val showDialogType: Int? = yourServerResponse.integrityDialogTypeCode()
    if (showDialogType == null) {
       return
    }
    
    // Create dialog request
    val dialogRequest = StandardIntegrityDialogRequest.builder()
            .setActivity(activity)
            .setTypeCode(showDialogType)
            .setStandardIntegrityResponse(StandardIntegrityResponse.TokenResponse(token))
            .build()
    
    // Call showDialog, the dialog will be shown on top of the provided activity
    // and the task will complete when the dialog is closed.
    val result: Task<Int> = standardIntegrityManager.showDialog(dialogRequest)
    
    // Handle response code, call the Integrity API again to confirm that the
    // verdict issue has been resolved. 

    জাভা

    // Show dialog as indicated by the server
    @Nullable Integer showDialogType = yourServerResponse.integrityDialogTypeCode();
    if (showDialogType == null) {
       return;
    }
    
    // Create dialog request
    StandardIntegrityDialogRequest dialogRequest =
        StandardIntegrityDialogRequest.builder()
            .setActivity(getActivity())
            .setTypeCode(showDialogTypeCode)
            .setStandardIntegrityResponse(new StandardIntegrityResponse.TokenResponse(token))
            .build();
    
    // Call showDialog, the dialog will be shown on top of the provided activity
    // and the task will complete when the dialog is closed.
    Task<Integer> result = standardIntegrityManager.showDialog(dialogRequest);
    
    // Handle response code, call the Integrity API again to confirm that the
    // verdict issue has been resolved.

    Unity

    // Initialize the V2 manager. Requires Play Integrity Unity Plugin v2.0.0 or
    // higher.
    var standardIntegrityManager = new StandardIntegrityManagerV2();
    IEnumerator ShowDialogCoroutine() {
      int showDialogType = yourServerResponse.IntegrityDialogTypeCode();
    
      PlayAsyncOperation<IntegrityDialogResponseCode, StandardIntegrityError> showDialogTask;
    
      using (var activity = UnityPlayerHelper.GetCurrentActivity())
      {
          // Create a dialog request
          var dialogRequest = new StandardIntegrityDialogRequest(tokenResponse, activity, showDialogType);
    
          // Call showDialog with the request, the dialog will be shown on top of the
          // provided activity and complete when the dialog is closed.
          showDialogTask = standardIntegrityManager.ShowDialog(dialogRequest);
      }
    
      // Wait for PlayAsyncOperation to complete.
      yield return showDialogTask;
    
      // Handle response code, call the Integrity API again to confirm that the
      // verdict issue been resolved.
    } 

    Unreal Engine

    // .h
    void MyClass::OnShowDialogCompleted(
      EStandardIntegrityErrorCode Error,
      EIntegrityDialogResponseCode Response)
    {
      // Handle response code, call the Integrity API again to confirm that the
      // verdict issue has been resolved.
    }
    
    // .cpp
    void MyClass::RequestIntegrityToken()
    {
      UStandardIntegrityToken* Response = ...
      int TypeCode = YourServerResponse.integrityDialogTypeCode();
    
      // Create a delegate to bind the callback function.
      FShowDialogStandardOperationCompletedDelegate Delegate;
    
      // Bind the completion handler (OnShowDialogCompleted) to the delegate.
      Delegate.BindDynamic(this, &MyClass::OnShowDialogCompleted);
    
      // Call ShowDialog with TypeCode which completes when the dialog is closed.
      Response->ShowDialog(TypeCode, Delegate);
    }

    নেটিভ

    // Show dialog as indicated by the server
    int show_dialog_type = yourServerResponse.integrityDialogTypeCode();
    if(show_dialog_type == 0){
    return;
    }
    
    /// Create dialog request
    StandardIntegrityDialogRequest* dialog_request;
    StandardIntegrityDialogRequest_create(&dialog_request);
    StandardIntegrityDialogRequest_setTypeCode(dialog_request, show_dialog_type);
    StandardIntegrityDialogRequest_setActivity(dialog_request, activity);
    StandardIntegrityDialogRequest_setStandardIntegrityToken(dialog_request,
                                                  token_response);
    
    /// Call showDialog with the dialog request. The dialog will be shown on top
    /// of the provided activity and complete when the dialog is closed by the
    /// user.
    StandardIntegrityDialogResponse* dialog_response;
    StandardIntegrityErrorCode error_code =
      StandardIntegrityManager_showDialog(dialog_request, &dialog_response);
    
    /// Use polling to wait for the async operation to complete. Note, the polling
    /// shouldn't block the thread where the StandardIntegrityManager is running.
    IntegrityDialogResponseCode response_code = INTEGRITY_DIALOG_RESPONSE_UNKNOWN;
    while (error_code == STANDARD_INTEGRITY_NO_ERROR) {
      error_code = StandardIntegrityDialogResponse_getResponseCode(dialog_response, &response_code);
      if(response_code != INTEGRITY_DIALOG_RESPONSE_UNKNOWN){
        break;
      }
    }
    
    /// Free memory
    StandardIntegrityDialogRequest_destroy(dialog_request);
    StandardIntegrityDialogResponse_destroy(dialog_response);
    
    /// Handle response code, call the Integrity API again to confirm that the
    /// verdict issues have been resolved.
  5. প্রদান করা অ্যাক্টিভিটির উপরে ডায়ালগ দেখানো হয়। ব্যবহারকারী ডায়ালগ বন্ধ করে দিলে, রেসপন্স কোড সহ টাস্ক সম্পূর্ণ হয়।

  6. (ঐচ্ছিক) আরও ডায়ালগ দেখানোর জন্য অন্য টোকেনের অনুরোধ করুন। আপনি স্ট্যান্ডার্ড অনুরোধ করলে, নতুন রায় পেতে আপনাকে আবার টোকেন প্রদানকারীকে ওয়ার্ম আপ করতে হবে।

ক্লায়েন্ট সাইড এক্সেপশন ঠিক করার জন্য ইন্টিগ্রিটি ডায়ালগের অনুরোধ করুন

Integrity API অনুরোধ StandardIntegrityException (Standard API) বা IntegrityServiceException (Classic API) সহ ব্যর্থ হলে এবং ব্যতিক্রমটি সংশোধনযোগ্য হলে, আপনি সমস্যাটি সমাধান করতে GET_INTEGRITY বা GET_STRONG_INTEGRITY ডায়ালগ ব্যবহার করতে পারেন।

Integrity API-এর মাধ্যমে রিপোর্ট করা ক্লায়েন্ট-সাইডের সমাধানযোগ্য সমস্যা ঠিক করতে, আপনি কীভাবে GET_INTEGRITY ডায়ালগ ব্যবহার করতে পারবেন তা নিম্নলিখিত ধাপগুলিতে উল্লেখ করা হয়েছে।

  1. ইন্টিগ্রিটি API অনুরোধ থেকে পাওয়া ব্যতিক্রমটি সমাধানযোগ্য কিনা তা চেক করুন।

    Kotlin

    private fun isExceptionRemediable(exception: ExecutionException): Boolean {
      val cause = exception.cause
      if (cause is StandardIntegrityException && cause.isRemediable) {
          return true
      }
      return false
    }

    জাভা

    private boolean isExceptionRemediable(ExecutionException exception) {
      Throwable cause = exception.getCause();
      if (cause instanceof StandardIntegrityException integrityException
    && integrityException.isRemediable()) {
          return true;
      }
      return false;
    }

    Unity

    private bool IsExceptionRemediable(StandardIntegrityError error) {
      // Check if the operation resulted in a remediable error
      if (error != null && error.ErrorCode != StandardIntegrityErrorCode.NoError && error.IsRemediable) {
          return true;
      }
      return false;
    }

    নেটিভ

    bool IsErrorRemediable(StandardIntegrityToken* token) {
      /// Check if the error associated with the token is remediable
      bool isRemediable = false;
      if(StandardIntegrityToken_getIsRemediable(response, &isRemediable) == STANDARD_INTEGRITY_NO_ERROR){
        return isRemediable;
      }
      return false;
    }
  2. ব্যতিক্রমটি সংশোধনযোগ্য হলে, ফেরত আসা ব্যতিক্রম ব্যবহার করে GET_INTEGRITY ডায়ালগের অনুরোধ করুন। প্রদান করা অ্যাক্টিভিটির উপরে ডায়ালগ দেখানো হবে এবং ব্যবহারকারী ডায়ালগ বন্ধ করার পরে রেসপন্স কোড সহ ফেরত আসা টাস্ক সম্পূর্ণ হবে।

    Kotlin

    private fun showDialog(exception: StandardIntegrityException) {
      // Create a dialog request
      val standardIntegrityDialogRequest =
          StandardIntegrityDialogRequest.builder()
              .setActivity(activity)
              .setType(IntegrityDialogTypeCode.GET_INTEGRITY)
              .setStandardIntegrityResponse(ExceptionDetails(exception))
              .build()
    
      // Request dialog
      val responseCode: Task<Int> =
            standardIntegrityManager.showDialog(standardIntegrityDialogRequest)
    }
     

    জাভা

    private void showDialog(StandardIntegrityException exception) {
      // Create a dialog request
      StandardIntegrityDialogRequest standardIntegrityDialogRequest =
          StandardIntegrityDialogRequest.builder()
              .setActivity(this.activity)
              .setType(IntegrityDialogTypeCode.GET_INTEGRITY)
              .setStandardIntegrityResponse(new ExceptionDetails(exception))
              .build();
    
      // Request dialog
      Task<Integer> responseCode =
            standardIntegrityManager.showDialog(standardIntegrityDialogRequest);
    }  

    Unity

    // Initialize the V2 manager. Requires Play Integrity Unity Plugin v2.0.0 or
    // higher.
    var standardIntegrityManager = new StandardIntegrityManagerV2();
    IEnumerator ShowDialogToFixError(StandardIntegrityError error) {
      PlayAsyncOperation<IntegrityDialogResponseCode, StandardIntegrityError> showDialogTask;
    
      using (var activity = UnityPlayerHelper.GetCurrentActivity())
      {
          // Create a dialog request using the error
          var dialogRequest = new StandardIntegrityDialogRequest(error, activity, GET_INTEGRITY_DIALOG);
    
          // Request dialog
          showDialogTask = standardIntegrityManager.ShowDialog(dialogRequest);
      }
    
      // Wait for PlayAsyncOperation to complete.
      yield return showDialogTask;
    }

    নেটিভ

    private void showDialogToFixError(StandardIntegrityToken* token) {
      /// If the token request failed, and the underlying error is not fixable
      /// then return early
      if(isErrorRemediable(token)) {
        return;
      }
    
      /// Create dialog request
      StandardIntegrityDialogRequest* dialog_request;
      StandardIntegrityDialogRequest_create(&dialog_request);
      StandardIntegrityDialogRequest_setTypeCode(dialog_request,
                                         kGetIntegrityDialogTypeCode);
      StandardIntegrityDialogRequest_setActivity(dialog_request, activity);
      StandardIntegrityDialogRequest_setStandardIntegrityToken(dialog_request,
                                                      token_response);
    
      /// Call showDialog with the dialog request. The dialog will be shown on
      /// top of the provided activity and complete when the dialog is closed by
      /// the user.
      StandardIntegrityDialogResponse* dialog_response;
      StandardIntegrityErrorCode error_code =
          StandardIntegrityManager_showDialog(dialog_request, &dialog_response);
    
      /// Use polling to wait for the async operation to complete.
      /// Note, the polling shouldn't block the thread where the
      /// StandardIntegrityManager is running.
      IntegrityDialogResponseCode response_code = INTEGRITY_DIALOG_RESPONSE_UNKNOWN;
      while (error_code == STANDARD_INTEGRITY_NO_ERROR) {
          error_code = StandardIntegrityDialogResponse_getResponseCode(response, &response_code);
          if(response_code != INTEGRITY_DIALOG_RESPONSE_UNKNOWN){
            break;
          }
      }
    
      /// Free memory
      StandardIntegrityDialogRequest_destroy(dialog_request);
      StandardIntegrityDialogResponse_destroy(dialog_response);
    
    }
  3. ফেরত আসা রেসপন্স কোড যদি সফল হওয়ার ইঙ্গিত দেয়, তাহলে ইন্টিগ্রিটি টোকেনের জন্য পরবর্তী অনুরোধ কোনও ব্যতিক্রম ছাড়াই সফল হবে। আপনি স্ট্যান্ডার্ড অনুরোধ করলে, নতুন রায় পেতে আপনাকে টোকেন প্রদানকারীকে আবার ওয়ার্ম আপ করতে হবে।

ইন্টিগ্রিটি ডায়ালগ কোড

GET_LICENSED (টাইপ কোড ১)

ভার্ডিক্ট সংক্রান্ত সমস্যা

এই ডায়ালগ দুটি সমস্যার জন্য উপযুক্ত:

  • অননুমোদিত অ্যাক্সেস: appLicensingVerdict: "UNLICENSED"। এর অর্থ হল, ব্যবহারকারীর অ্যাকাউন্টে আপনার অ্যাপের জন্য কোনও এনটাইটেলমেন্ট নেই, যা হতে পারে যদি ব্যবহারকারী এটি সাইডলোড করে থাকেন বা Google Play ছাড়া অন্য কোনও অ্যাপ স্টোর থেকে এটি অর্জন করে থাকেন।
  • টেম্পার করা অ্যাপ: appRecognitionVerdict: "UNRECOGNIZED_VERSION". এর অর্থ হল আপনার অ্যাপের বাইনারি পরিবর্তন করা হয়েছে অথবা এটি Google Play-এর স্বীকৃত ভার্সন নয়।

সমাধান

Google Play থেকে আসল অ্যাপ ডাউনলোড করার জন্য ব্যবহারকারীকে প্রম্পট করতে আপনি GET_LICENSED ডায়ালগ দেখাতে পারেন। এই একটি ডায়ালগ দুটি পরিস্থিতিই কভার করে:

  • লাইসেন্স নেই এমন ব্যবহারকারীর ক্ষেত্রে, এটি তাকে Play লাইসেন্স প্রদান করে। এটি ব্যবহারকারীকে Google Play থেকে অ্যাপ আপডেট পেতে দেয়।
  • টেম্পার করা অ্যাপ ভার্সন ব্যবহারকারীকে এটি Google Play থেকে পরিবর্তন না করা অ্যাপ ইনস্টল করার জন্য নির্দেশ দেয়।

ব্যবহারকারী ডায়ালগ সম্পূর্ণ করলে, পরবর্তী ইন্টিগ্রিটি চেক appLicensingVerdict: "LICENSED" এবং appRecognitionVerdict: "PLAY_RECOGNIZED" রিটার্ন করে।

উদাহরণ UX

ছবি ১. GET_LICENSED Play ডায়ালগ।

CLOSE_UNKNOWN_ACCESS_RISK (টাইপ কোড ২)

ভার্ডিক্ট সংক্রান্ত সমস্যা

environmentDetails.appAccessRiskVerdict.appsDetected-এ "UNKNOWN_CAPTURING" বা "UNKNOWN_CONTROLLING" থাকলে, এর অর্থ হল ডিভাইসে অন্যান্য অ্যাপ (Google Play-এর মাধ্যমে ইনস্টল করা হয়নি বা ডিভাইস প্রস্তুতকারকের মাধ্যমে সিস্টেম পার্টিশনে প্রিলোড করা হয়নি) চলছে যা স্ক্রিন ক্যাপচার করতে বা ডিভাইস নিয়ন্ত্রণ করতে পারে।

সমাধান

স্ক্রিন ক্যাপচার বা ডিভাইস কন্ট্রোল করতে পারে এমন সব অজানা অ্যাপ বন্ধ করার জন্য ব্যবহারকারীকে প্রম্পট করতে আপনি CLOSE_UNKNOWN_ACCESS_RISK ডায়ালগ দেখাতে পারেন। ব্যবহারকারী Close all বোতামে ট্যাপ করলে, এই ধরনের সব অ্যাপ বন্ধ হয়ে যায়।

উদাহরণ UX

ছবি ২. অজানা অ্যাক্সেস সংক্রান্ত ঝুঁকি বন্ধ করার জন্য ডায়ালগ।

CLOSE_ALL_ACCESS_RISK (টাইপ কোড ৩)

ভার্ডিক্ট সংক্রান্ত সমস্যা

environmentDetails.appAccessRiskVerdict.appsDetected-এ "KNOWN_CAPTURING", "KNOWN_CONTROLLING","UNKNOWN_CAPTURING" বা "UNKNOWN_CONTROLLING"-এর মধ্যে যেকোনও একটি থাকলে, তার অর্থ হল ডিভাইসে এমন অ্যাপ চলছে যা স্ক্রিন ক্যাপচার করতে বা ডিভাইস নিয়ন্ত্রণ করতে পারে।

সমাধান

স্ক্রিন ক্যাপচার বা ডিভাইস কন্ট্রোল করতে পারে এমন সব অ্যাপ বন্ধ করার জন্য ব্যবহারকারীকে প্রম্পট করতে আপনি CLOSE_ALL_ACCESS_RISK ডায়ালগ দেখাতে পারেন। ব্যবহারকারী Close all বোতামে ট্যাপ করলে, ডিভাইসে এই ধরনের সব অ্যাপ বন্ধ হয়ে যায়।

উদাহরণ UX

ছবি ৩. সব অ্যাক্সেস সংক্রান্ত ঝুঁকি বন্ধ করার জন্য ডায়ালগ।

GET_INTEGRITY (টাইপ কোড ৪)

ভার্ডিক্ট সংক্রান্ত সমস্যা

নিম্নলিখিত যেকোনও সমস্যার জন্য এই ডায়ালগ উপযুক্ত:

  • ডিভাইসের দুর্বল ইন্টিগ্রিটি: deviceRecognitionVerdict-এ MEETS_DEVICE_INTEGRITY না থাকলে, ডিভাইসটি আসল এবং সার্টিফায়েড Android ডিভাইস নাও হতে পারে। এটি হতে পারে, যেমন, ডিভাইসের বুটলোডার আনলক করা থাকলে বা লোড করা Android OS সার্টিফায়েড প্রস্তুতকারকের ইমেজ না হলে।

  • অননুমোদিত অ্যাক্সেস: appLicensingVerdict: "UNLICENSED"। এর অর্থ হল, ব্যবহারকারীর অ্যাকাউন্টে আপনার অ্যাপের জন্য কোনও এনটাইটেলমেন্ট নেই, যা হতে পারে যদি ব্যবহারকারী এটি সাইডলোড করে থাকেন বা Google Play ছাড়া অন্য কোনও অ্যাপ স্টোর থেকে এটি অর্জন করে থাকেন।

  • টেম্পার করা অ্যাপ: appRecognitionVerdict: "UNRECOGNIZED_VERSION". এর অর্থ হল, আপনার অ্যাপের বাইনারি পরিবর্তন করা হয়েছে অথবা এটি এমন একটি ভার্সন যা Google Play শনাক্ত করতে পারছে না।

  • ক্লায়েন্ট সাইড এক্সেপশন: Integrity API অনুরোধের সময় প্রতিকারযোগ্য এক্সেপশন হলে। প্রতিকারযোগ্য ব্যতিক্রম হল Integrity API ব্যতিক্রম যার সাথে PLAY_SERVICES_VERSION_OUTDATED, NETWORK_ERROR, PLAY_SERVICES_NOT_FOUND, ইত্যাদির মতো ত্রুটি কোড থাকে। কোনও ব্যতিক্রম ডায়ালগের মাধ্যমে সমাধানযোগ্য কিনা তা চেক করতে আপনি exception.isRemediable() পদ্ধতি ব্যবহার করতে পারেন।

সমাধান

GET_INTEGRITY ডায়ালগটি এমনভাবে ডিজাইন করা হয়েছে যাতে একটি নিরবচ্ছিন্ন ফ্লোয়ের মধ্যে একাধিক প্রতিকারমূলক পদক্ষেপ গ্রহণ করে ব্যবহারকারীর অভিজ্ঞতাকে আরও সহজ করা যায়। এর ফলে ব্যবহারকারীকে বিভিন্ন সমস্যা সমাধান করার জন্য একাধিক আলাদা আলাদা ডায়ালগের সাথে ইন্টার‍্যাক্ট করতে হয় না।

আপনি ডায়ালগের জন্য অনুরোধ করলে, এটি অটোমেটিক শনাক্ত করে যে টার্গেট করা রায় সংক্রান্ত সমস্যার মধ্যে কোনটি উপস্থিত আছে এবং উপযুক্ত প্রতিকারমূলক পদক্ষেপ প্রদান করে। এর অর্থ হল, একটি ডায়ালগ অনুরোধের মাধ্যমে একসাথে একাধিক সমস্যার সমাধান করা যেতে পারে, যার মধ্যে রয়েছে:

  • ডিভাইস ইন্টিগ্রিটি: ডিভাইস ইন্টিগ্রিটি সংক্রান্ত কোনও সমস্যা শনাক্ত করা হলে, MEETS_DEVICE_INTEGRITY রায় পাওয়ার জন্য প্রয়োজনীয়তা পূরণ করতে, ডিভাইসের নিরাপত্তা স্ট্যাটাস উন্নত করার ব্যাপারে ডায়ালগ ব্যবহারকারীকে নির্দেশ দেবে।
  • অ্যাপ ইন্টিগ্রিটি: অননুমোদিত অ্যাক্সেস বা অ্যাপ টেম্পারিংয়ের মতো সমস্যা শনাক্ত করা হলে, ডায়ালগ ব্যবহারকারীকে Play Store থেকে অ্যাপটি ডাউনলোড করতে নির্দেশ দেবে যাতে সমস্যাটি সমাধান করা যায়।
  • ক্লায়েন্ট-সাইড ব্যতিক্রম: ডায়ালগটি চেক করে এবং Integrity API ব্যতিক্রমের কারণ হতে পারে এমন কোনও সমস্যা সমাধান করার চেষ্টা করে। যেমন, এটি ব্যবহারকারীকে Google Play পরিষেবার পুরনো ভার্সন আপডেট করার জন্য প্রম্পট করতে পারে।

উদাহরণ UX

ছবি ৪. GET_INTEGRITY ডায়ালগ নেটওয়ার্কের সমস্যা সমাধানের ফ্লো

GET_STRONG_INTEGRITY (টাইপ কোড ৫)

ভার্ডিক্ট সংক্রান্ত সমস্যা

এই ডায়ালগটি এমনভাবে ডিজাইন করা হয়েছে যাতে GET_INTEGRITY যেসব সমস্যার সমাধান করে, সেইসব সমস্যার সমাধান করা যায়। এর সাথে, কোনও ডিভাইস যাতে MEETS_STRONG_INTEGRITY রায় পেতে পারে এবং Play Protect রায় সংক্রান্ত সমস্যার সমাধান করতে পারে, সেই জন্য অতিরিক্ত ক্ষমতাও প্রদান করা হয়।

সমাধান

GET_STRONG_INTEGRITY-এর ডিজাইন এমনভাবে করা হয়েছে যাতে একটিই নিরবচ্ছিন্ন ফ্লোয়ের মধ্যে একাধিক প্রতিকারমূলক পদক্ষেপ গ্রহণ করে ব্যবহারকারীর অভিজ্ঞতাকে আরও সহজ করে তোলা যায়। ডায়ালগ অটোমেটিক কোনও ঠিকানার ক্ষেত্রে প্রযোজ্য ইন্টিগ্রিটি সংক্রান্ত সমস্যা চেক করে, যার মধ্যে এগুলি অন্তর্ভুক্ত:

  • ডিভাইস ইন্টিগ্রিটি: ডিভাইস ইন্টিগ্রিটি সংক্রান্ত কোনও সমস্যা শনাক্ত করা হলে, MEETS_STRONG_INTEGRITY রায় পাওয়ার জন্য প্রয়োজনীয়তা পূরণ করতে, ডিভাইসের নিরাপত্তা স্ট্যাটাস উন্নত করার ব্যাপারে ডায়ালগ ব্যবহারকারীকে নির্দেশ দেবে।
  • Play Protect স্ট্যাটাস: playProtectVerdict কোনও সমস্যা নির্দেশ করলে, ডায়ালগ ব্যবহারকারীকে সেটি সমাধান করার জন্য নির্দেশ দেবে:

    • Play Protect বন্ধ করা থাকলে (playProtectVerdict == POSSIBLE_RISK), ডায়ালগ ব্যবহারকারীকে এটি চালু করতে এবং ডিভাইসের সব অ্যাপ স্ক্যান করতে প্রম্পট করবে।
    • ক্ষতিকারক অ্যাপ শনাক্ত করা হলে (playProtectVerdict == MEDIUM_RISK বা HIGH_RISK), ডায়ালগটি ব্যবহারকারীকে Google Play Protect ব্যবহার করে সেগুলি আনইনস্টল করার নির্দেশ দেবে।
  • অ্যাপ ইন্টিগ্রিটি: অননুমোদিত অ্যাক্সেস বা অ্যাপ টেম্পারিংয়ের মতো সমস্যা শনাক্ত করা হলে, সমস্যা সমাধান করার জন্য ব্যবহারকারীকে Play Store থেকে অ্যাপটি ডাউনলোড করার জন্য ডায়ালগ প্রম্পট করবে।

  • ক্লায়েন্ট-সাইড ব্যতিক্রম: এছাড়াও, ডায়ালগটি Integrity API ব্যতিক্রমের কারণ হওয়া যেকোনও অন্তর্নিহিত সমস্যার সমাধান করার চেষ্টা করে। যেমন, Google Play পরিষেবা বন্ধ করা থাকলে, এটি ব্যবহারকারীকে তা চালু করার জন্য প্রম্পট করতে পারে। সমাধানযোগ্য ব্যতিক্রম হল Integrity API ব্যতিক্রম যার সাথে এই ধরনের ত্রুটি কোড থাকে PLAY_SERVICES_VERSION_OUTDATED, NETWORK_ERROR, অথবা PLAY_SERVICES_NOT_FOUND. আপনি exception.isRemediable() পদ্ধতি ব্যবহার করে চেক করতে পারবেন যে কোনও সমস্যা ডায়ালগের মাধ্যমে সমাধান করা যাবে কিনা।

উদাহরণ UX

ছবি ৫. GET_STRONG_INTEGRITY ডায়ালগ Play পরিষেবা আপডেট করছে।