@Override
  protected void onAttachedToWindow() {
    super.onAttachedToWindow();

    DJIBaseProduct product = DJISampleApplication.getProductInstance();

    if (product == null || !product.isConnected()) {
      Utils.setResultToToast(mContext, "Disconnect");
      mMissionManager = null;
      mFlightController = null;
      return;
    } else {
      mMissionManager = product.getMissionManager();
      if (product instanceof DJIAircraft) {
        mFlightController = ((DJIAircraft) product).getFlightController();
      }

      if (mMissionManager != null) {
        // The callback method is implemented in the subclasses
        mMissionManager.setMissionProgressStatusCallback(this);
      }

      if (mFlightController != null) {

        mFlightController.setUpdateSystemStateCallback(
            new DJIFlightControllerDelegate.FlightControllerUpdateSystemStateCallback() {

              @Override
              public void onResult(
                  DJIFlightControllerDataType.DJIFlightControllerCurrentState state) {

                mHomeLatitude = state.getHomeLocation().getLatitude();
                mHomeLongitude = state.getHomeLocation().getLongitude();
                flightState = state.getFlightMode();

                Utils.setResultToText(
                    mContext,
                    mFCPushInfoTV,
                    "home point latitude: "
                        + mHomeLatitude
                        + "\nhome point longitude: "
                        + mHomeLongitude
                        + "\nFlight state: "
                        + flightState.name());
              }
            });
      }
    }
  }
  @Override
  protected void onAttachedToWindow() {
    super.onAttachedToWindow();

    if (DJIModuleVerificationUtil.isFlightControllerAvailable()) {

      flightController =
          ((DJIAircraft) DJISampleApplication.getProductInstance()).getFlightController();

      intelligentFlightAssistant = flightController.getIntelligentFlightAssistant();

      if (intelligentFlightAssistant != null) {

        intelligentFlightAssistant.setVisionDetectionStateUpdatedCallback(
            new DJIIntelligentFlightAssistant.VisionDetectionStateUpdatedCallback() {
              @Override
              public void onStateUpdated(
                  DJIIntelligentFlightAssistant.DJIVisionDetectionState djiVisionDetectionState) {
                if (null != djiVisionDetectionState) {
                  mStringBuffer.delete(0, mStringBuffer.length());

                  List<DJIIntelligentFlightAssistant.DJIVisionDetectionSector>
                      visionDetectionSectorList = djiVisionDetectionState.getDetectionSectors();

                  for (DJIIntelligentFlightAssistant.DJIVisionDetectionSector
                      visionDetectionSector : visionDetectionSectorList) {

                    visionDetectionSector.getObstacleDistanceInMeters();
                    visionDetectionSector.getWarningLevel();

                    mStringBuffer
                        .append("Obstacle distance: ")
                        .append(visionDetectionSector.getObstacleDistanceInMeters())
                        .append("\n");
                    mStringBuffer
                        .append("Distance warning: ")
                        .append(visionDetectionSector.getWarningLevel())
                        .append("\n");
                  }

                  mStringBuffer
                      .append("WarningLevel: ")
                      .append(djiVisionDetectionState.getWarningLevel().toString())
                      .append("\n");
                  mStringBuffer
                      .append("Braking state: ")
                      .append(djiVisionDetectionState.isBraking())
                      .append("\n");
                  mStringBuffer
                      .append("Sensor state: ")
                      .append(djiVisionDetectionState.isSensorWorking())
                      .append("\n");

                  mHandler.sendEmptyMessage(SET_CHANGE_STATUS);
                }
              }
            });
      }

    } else {
      Log.i("$$$$$$$$$$$$$$$$$$$", "onAttachedToWindow FC NOT Available");
    }
  }
  @Override
  public void onClick(View v) {
    mMissionManager = DJIMissionManager.getInstance();

    if (DJISampleApplication.getProductInstance() instanceof DJIAircraft
        && !Utils.checkGpsCoordinate(mHomeLatitude, mHomeLongitude)
        && mFlightController != null) {
      final CountDownLatch cdl = new CountDownLatch(1);
      mFlightController.getHomeLocation(
          new DJIBaseComponent.DJICompletionCallbackWith<
              DJIFlightControllerDataType.DJILocationCoordinate2D>() {

            @Override
            public void onSuccess(DJIFlightControllerDataType.DJILocationCoordinate2D t) {
              mHomeLatitude = t.getLatitude();
              mHomeLongitude = t.getLongitude();
              Utils.setResultToText(
                  mContext,
                  mFCPushInfoTV,
                  "home point latitude: "
                      + mHomeLatitude
                      + "\nhome point longitude: "
                      + mHomeLongitude
                      + "\nFlight state: "
                      + (flightState == null ? "" : flightState.name()));
            }

            @Override
            public void onFailure(DJIError error) {
              cdl.countDown();
            }
          });
      try {
        cdl.await(500, TimeUnit.MILLISECONDS);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }

      if (!Utils.checkGpsCoordinate(mHomeLatitude, mHomeLongitude)) {
        Utils.setResultToToast(mContext, "Home coordinates not yet set...");
        return;
      }
    }
    switch (v.getId()) {
      case R.id.btn_prepare:
        mDJIMission = initMission();
        if (mDJIMission == null) {
          Utils.setResultToToast(mContext, "Please choose a mission type...");
        }
        mMissionManager.prepareMission(
            mDJIMission,
            new DJIMission.DJIMissionProgressHandler() {

              @Override
              public void onProgress(DJIMission.DJIProgressType type, float progress) {
                setProgressBar((int) (progress * 100f));
              }
            },
            new DJICompletionCallback() {

              @Override
              public void onResult(DJIError error) {
                if (error == null) {
                  Utils.setResultToToast(mContext, "Success!");
                } else {
                  Utils.setResultToToast(mContext, "Prepare: " + error.getDescription());
                }
              }
            });
        break;
      case R.id.btn_start:
        if (mDJIMission != null) {
          mMissionManager.setMissionExecutionFinishedCallback(
              new DJICompletionCallback() {

                @Override
                public void onResult(DJIError error) {
                  Utils.setResultToToast(
                      mContext,
                      "Mission executing result: "
                          + (error == null ? "Success" : error.getDescription()));
                  if (mDJIMission instanceof DJIPanoramaMission) {
                    try {
                      Thread.sleep(1500);
                    } catch (InterruptedException e) {
                      e.printStackTrace();
                    }
                    ((DJIPanoramaMission) mDJIMission)
                        .getPanoramaMediaFile(
                            new DJIBaseComponent.DJICompletionCallbackWith<DJIMedia>() {
                              @Override
                              public void onSuccess(DJIMedia djiMedia) {
                                Utils.setResultToToast(mContext, "Index: " + djiMedia.getId());
                              }

                              @Override
                              public void onFailure(DJIError djiError) {
                                Utils.setResultToToast(mContext, "Get panorama media file failed!");
                              }
                            });
                  }
                }
              });
        }
        // For the panorama mission, there will be no callback in some cases, we will fix it in next
        // version.
        mMissionManager.startMissionExecution(
            new DJICompletionCallback() {

              @Override
              public void onResult(DJIError mError) {

                if (mError == null) {
                  if (mDJIMission instanceof DJIFollowMeMission && mUpdateSimLocateThread == null) {
                    mUpdateSimLocateThread =
                        new UpdateFollowmeSimLocationThread(
                            mDJIMission, mHomeLatitude, mHomeLongitude);
                    mUpdateSimLocateThread.start();
                  }
                } else {
                  Utils.setResultToToast(mContext, "Start: " + mError.getDescription());
                }
              }
            });
        break;
      case R.id.btn_stop:
        mMissionManager.stopMissionExecution(
            new DJICompletionCallback() {

              @Override
              public void onResult(DJIError mError) {
                if (mError == null) {
                  Utils.setResultToToast(mContext, "Success!");
                  if (mUpdateSimLocateThread != null) {
                    mUpdateSimLocateThread.stopRunning();
                    mUpdateSimLocateThread = null;
                  }
                } else {
                  Utils.setResultToToast(mContext, "Stop: " + mError.getDescription());
                }
              }
            });
        break;
      case R.id.btn_pause:
        mMissionManager.pauseMissionExecution(
            new DJICompletionCallback() {

              @Override
              public void onResult(DJIError mError) {
                if (mError == null) {
                  Utils.setResultToToast(mContext, "Success!");
                  if (mUpdateSimLocateThread != null) {
                    mUpdateSimLocateThread.setIsPause(true);
                  }
                } else {
                  Utils.setResultToToast(mContext, "Pause: " + mError.getDescription());
                }
              }
            });
        break;
      case R.id.btn_resume:
        mMissionManager.resumeMissionExecution(
            new DJICompletionCallback() {

              @Override
              public void onResult(DJIError mError) {
                if (mError == null) {
                  Utils.setResultToToast(mContext, "Success!");
                  if (mUpdateSimLocateThread != null) {
                    mUpdateSimLocateThread.setIsPause(false);
                  }
                } else {
                  Utils.setResultToToast(mContext, "Resume" + mError.getDescription());
                }
              }
            });
        break;
      case R.id.btn_download:
        // download action only downloads the currently executing missions' data
        mMissionManager.downloadMission(
            new DJIMission.DJIMissionProgressHandler() {

              @Override
              public void onProgress(DJIMission.DJIProgressType type, float progress) {
                setProgressBar((int) (progress * 100f));
              }
            },
            new DJIBaseComponent.DJICompletionCallbackWith<DJIMission>() {

              @Override
              public void onSuccess(DJIMission mission) {
                StringBuffer sb = new StringBuffer();
                // we do this check to ensure the download data is only for the
                // currently executing mission and is independent of the
                // view the user is looking at
                if (mission instanceof DJIWaypointMission) {
                  Utils.addLineToSB(sb, "Repeat num", ((DJIWaypointMission) mission).repeatNum);
                  Utils.addLineToSB(sb, "Heading mode", ((DJIWaypointMission) mission).headingMode);
                  Utils.addLineToSB(
                      sb, "Finish action", ((DJIWaypointMission) mission).finishedAction);
                  Utils.addLineToSB(
                      sb, "Flight path mode", ((DJIWaypointMission) mission).flightPathMode);
                  Utils.addLineToSB(
                      sb, "Max flight speed", ((DJIWaypointMission) mission).maxFlightSpeed);
                  Utils.addLineToSB(
                      sb, "Auto flight speed", ((DJIWaypointMission) mission).autoFlightSpeed);
                } else if (mission instanceof DJIHotPointMission) {
                  Utils.addLineToSB(sb, "Latitude", ((DJIHotPointMission) mission).latitude);
                  Utils.addLineToSB(sb, "Longitude", ((DJIHotPointMission) mission).longitude);
                  Utils.addLineToSB(sb, "Altitude", ((DJIHotPointMission) mission).altitude);
                  Utils.addLineToSB(sb, "Surround radius", ((DJIHotPointMission) mission).radius);
                  Utils.addLineToSB(
                      sb, "Angular velocity", ((DJIHotPointMission) mission).angularVelocity);
                  Utils.addLineToSB(sb, "Is clockwise", ((DJIHotPointMission) mission).isClockwise);
                  Utils.addLineToSB(sb, "Entry point", ((DJIHotPointMission) mission).startPoint);
                  Utils.addLineToSB(sb, "Heading mode", ((DJIHotPointMission) mission).heading);
                } else if (mission instanceof DJIFollowMeMission) {
                  Utils.addLineToSB(sb, "Heading mode", ((DJIFollowMeMission) mission).heading);
                } else {
                  sb.append("Unknown mission instance!");
                }
                Utils.setResultToToast(mContext, sb.toString());
              }

              public void onFailure(DJIError error) {
                Utils.setResultToToast(mContext, "Download: " + error.getDescription());
              }
            });
        break;
      default:
        break;
    }
  }