<file_sep>package com.txtled.gp_a209.model.net;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;


/**
 * Created by Mr.Quan on 2018/11/12.
 */

public class NetHelperImpl implements NetHelper {



    @Inject
    public NetHelperImpl() {
    }
}
<file_sep>package com.txtled.gp_a209.control.mvp;

import android.app.Activity;

import com.txtled.gp_a209.base.BasePresenter;
import com.txtled.gp_a209.base.BaseView;
import com.txtled.gp_a209.bean.IotCoreData;

/**
 * Created by Mr.Quan on 2020/3/19.
 */
public interface ControlContract {
    interface View extends BaseView{

        void mqttSuccess(int id);

        void mqttFail(int id);

        void hidLoadingView();

        void setData(IotCoreData iotCoreData);

        void powerChanged(boolean power);

        void volumeFail(int progress);

        void lightFail();

        void initFail();

        void resetView(IotCoreData iotCoreData);
    }

    interface Presenter extends BasePresenter<View>{
        void init(String endpoint, Activity activity);

        void sendMqtt(int id);

        void sendLight(int state);

        void onClick(int id,boolean power);

        void initData();

        void sendVolume(int progress);

        void destroy();

        void enableView();
    }
}
<file_sep>package com.txtled.gp_a209.login.mvp;

import android.app.Activity;
import android.net.wifi.WifiInfo;

import com.txtled.gp_a209.base.BasePresenter;
import com.txtled.gp_a209.base.BaseView;

/**
 * Created by Mr.Quan on 2020/3/12.
 */
public interface LoginContract {
    interface View extends BaseView {

        void hidLoadingView();

        void showLoadingView();

        void checkLocation();

        void setNoWifiView();

        void hidSnackBar();

        void setInfo(String ssid, WifiInfo info);

        void showLoginFail();

        void toMainView(boolean back);

        void signOut();

        void signOutFail();
    }
    interface Presenter extends BasePresenter<View>{

        void init(Activity activity);

        void viewClick(int id, int type);

        void onResume(boolean isShowing);

        void onDestroy(Activity activity);
    }
}
<file_sep>package com.txtled.gp_a209.model.prefs;

/**
 * Created by Mr.Quan on 2018/4/17.
 */

public interface PreferencesHelper {

    boolean isFirstIn();

    void setFirstIn(boolean first);

    String getUserId();

    void setUserId(String id);

    String getDeviceAddress();

    void setDeviceAddress(String address);

    void setUid(String uid);

    String getUid();

    String getEmail();

    void setEmail(String email);
}
<file_sep>package com.txtled.gp_a209.base;

import android.os.Bundle;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import com.google.android.material.snackbar.Snackbar;
import com.txtled.gp_a209.R;
import com.txtled.gp_a209.application.MyApplication;
import com.txtled.gp_a209.widget.ArialRoundTextView;

import butterknife.ButterKnife;


public abstract class BaseActivity extends AppCompatActivity {
    public static final String TAG = BaseActivity.class.getSimpleName();
    public ArialRoundTextView tvTitle;
    public boolean isBack = true;
    public boolean changeColor = true;
    private long mExitTime;
    private MyApplication mApplication;
    Toolbar toolbar;
    public Snackbar snackbar;
    private ImageView ivRight;

    public abstract void init();

    public abstract int getLayout();

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        beforeContentView();
        setContentView(getLayout());
        ButterKnife.bind(this);
//        if (!EventBus.getDefault().isRegistered(this)) {
//            EventBus.getDefault().register(this);
//        }

        mApplication = MyApplication.getInstance();
        addActivity();
        onCreateView();
        init();
    }

    protected abstract void beforeContentView();

    public void onCreateView() {

    }


    public void initToolbar() {
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        if (toolbar != null) {
            tvTitle = (ArialRoundTextView) findViewById(R.id.tv_title);
            ivRight = (ImageView) findViewById(R.id.iv_right);
            setSupportActionBar(toolbar);
            setTitle("");

            toolbar.setOnMenuItemClickListener(onMenuItemClick);
            toolbar.setNavigationOnClickListener(v -> {
                if (isBack){
                    onBackPressed();
                }else {
                    onLeftClick();
                }

            });
        }
    }

    public void onLeftClick() {
    }

    public void setNavigationIcon(boolean isBack) {
        this.isBack = isBack;
        if (isBack) {
            toolbar.setNavigationIcon(R.mipmap.logwifi_back_xhdpi);
        } else {
            toolbar.setNavigationIcon(R.mipmap.devicelist_left_xhdpi);
        }

    }

    public void setRightImg(boolean isShow, @Nullable int drawable, View.OnClickListener listener) {
        if (isShow) {
            ivRight.setVisibility(View.VISIBLE);
            ivRight.setImageResource(drawable);
            ivRight.setOnClickListener(listener);
        } else {
            ivRight.setVisibility(View.GONE);
        }

    }

    public Toolbar.OnMenuItemClickListener onMenuItemClick = new Toolbar.OnMenuItemClickListener() {
        @Override
        public boolean onMenuItemClick(MenuItem menuItem) {
            OnMenuItemClick(menuItem.getItemId());
            return true;
        }
    };

    public void OnMenuItemClick(int itemId) {

    }

    public boolean onExitActivity(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
            if ((System.currentTimeMillis() - mExitTime) > 2000) {
                Toast.makeText(this, R.string.exit_program_hint,
                        Toast.LENGTH_SHORT).show();
                mExitTime = System.currentTimeMillis();
            } else {
                removeAllActivity();
            }
            return true;
        } else {
            return super.onKeyDown(keyCode, event);
        }
    }
    @Override
    public void onBackPressed() {
        if (getFragmentManager().getBackStackEntryCount() > 0) {
            getFragmentManager().popBackStack();
        } else {
            super.onBackPressed();
        }
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
//        if (EventBus.getDefault().isRegistered(this)) {
//            EventBus.getDefault().unregister(this);
//        }
    }

    public void addActivity() {
        mApplication.addActivity(this);
    }


    public void removeAllActivity() {
        mApplication.removeAllActivity();
    }

    public void showSnackBar(View view, int str) {
        if (snackbar == null) {
            snackbar = Snackbar.make(view, str, Snackbar.LENGTH_INDEFINITE);
            snackbar.getView().setBackgroundColor(getResources().getColor(R.color.bg_snack));
        }
        snackbar.show();
    }

    public void showSnackBar(View view, int str, int btnStr, View.OnClickListener listener) {
        if (snackbar == null) {
            snackbar = Snackbar.make(view, str, Snackbar.LENGTH_INDEFINITE).setAction(btnStr,listener);
            snackbar.getView().setBackgroundColor(getResources().getColor(R.color.bg_snack));
            snackbar.setActionTextColor(getResources().getColor(R.color.white));
        }
        snackbar.show();
    }

//    public void showSnackBar(View view, int layoutId, int str) {
//        if (snackbar == null) {
//            snackbar = Snackbar.make(view, str, Snackbar.LENGTH_INDEFINITE);
//            snackbar.getView().setBackgroundColor(getResources().getColor(R.color.bg_snack));
//            View snackbarview = snackbar.getView();//获取snackbar的View(其实就是SnackbarLayout)
//
//            Snackbar.SnackbarLayout snackbarLayout=(Snackbar.SnackbarLayout)snackbarview;//将获取的View转换成SnackbarLayout
//
//            View add_view = LayoutInflater.from(snackbarview.getContext()).inflate(layoutId,null);//加载布局文件新建View
//
//            LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);//设置新建布局参数
//
//            p.gravity= Gravity.CENTER_VERTICAL;//设置新建布局在Snackbar内垂直居中显示
//
//            snackbarLayout.addView(add_view,1,p);//将新建布局添加进snackbarLayout相应位置
//        }
//        snackbar.show();
//    }

//    public void changeSnackBar(int str,int btnStr, boolean isShow, View.OnClickListener listener){
//        snackbar.setText(str);
//        View snackbarview = snackbar.getView();
//        ProgressBar bar = (ProgressBar) snackbarview.findViewById(R.id.clp_loading);
//        if (isShow){
//            bar.setVisibility(View.VISIBLE);
//            snackbar.setAction(null,null);
//        }else {
//            bar.setVisibility(View.GONE);
//            snackbar.setAction(btnStr,listener);
//        }
//
//    }

    public void hideSnackBar() {
        if (snackbar != null && snackbar.isShown()) {
            snackbar.dismiss();
            snackbar = null;
        }
    }

//    @Subscribe
//    public void onEventMainThread(String str) {
//
//    }
}
<file_sep>package com.txtled.gp_a209.add.listener;

/**
 * Created by Mr.Quan on 2020/1/3.
 */
public interface OnUdpSendRequest {
    void OnRequestListener(String result);
}
<file_sep>package com.txtled.gp_a209.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.util.AttributeSet;

import androidx.appcompat.widget.AppCompatEditText;

import com.txtled.gp_a209.R;

import static com.txtled.gp_a209.utils.Constants.BOLD;
import static com.txtled.gp_a209.utils.Constants.THIN;

/**
 * Created by Mr.Quan on 2020/3/17.
 */
public class ArialRoundEditText extends AppCompatEditText {
    public ArialRoundEditText(Context context) {
        this(context,null,0);
    }

    public ArialRoundEditText(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public ArialRoundEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        if (isInEditMode()) return;
        String fontName = "ArialRoundedMTStd.otf";
        if (attrs != null) {
            TypedArray typedArray = context.getTheme().
                    obtainStyledAttributes(attrs, R.styleable.ArialRound, defStyleAttr, 0);
            int fontType = typedArray.getInteger(R.styleable.ArialRound_text_type, 0);
            switch (fontType) {
                case THIN:
                    fontName = "ArialRoundedMTStd.otf";
                    break;
                case BOLD:
                    fontName = "ArialRoundedMTStd-ExtraBold.otf";
                    break;
            }
        }
        super.setTypeface(Typeface.createFromAsset(getContext().getAssets(),
                "fonts/" + fontName), defStyleAttr);
    }
}
<file_sep>apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.1"
    defaultConfig {
        applicationId "com.txtled.gp_a209"
        minSdkVersion 14
        targetSdkVersion 26
        versionCode 1
        versionName "1.1.1"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    implementation 'androidx.multidex:multidex:2.0.1'

    //黄油刀
    implementation 'com.google.dagger:dagger:2.0.2'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.0.2'
    implementation 'com.jakewharton:butterknife:8.2.1'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.2.1'
    //rx
    implementation 'io.reactivex.rxjava2:rxjava:2.1.2'
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
    //event bus
    //implementation 'org.greenrobot:eventbus:3.0.0'
    //implementation files('libs/universal-image-loader-1.9.5.jar')
    implementation 'org.glassfish:javax.annotation:10.0-b28'
    //权限
    implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar'
    //sql
    //implementation 'org.greenrobot:greendao:3.2.2'

    //design
    implementation 'com.google.android.material:material:1.1.0'
    implementation files('libs/login-with-amazon-sdk.jar')

    //DNS
    implementation 'org.apache.commons:commons-lang3:3.4'
    implementation 'com.yalantis:phoenix:1.2.3'
    implementation 'commons-io:commons-io:2.4'

    //ble
    implementation 'com.inuker.bluetooth:library:1.4.0'

    //aws iot
    implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.2'
    implementation 'com.amazonaws:aws-android-sdk-iot:2.16.6'
    // https://mvnrepository.com/artifact/com.amazonaws/aws-android-sdk-core
    implementation 'com.amazonaws:aws-android-sdk-core:2.16.6'
    implementation 'com.amazonaws:aws-iot-device-sdk-java:1.3.4'

    //ddb
    implementation "com.amazonaws:aws-android-sdk-ddb:2.16.6"
    implementation 'com.amazonaws:aws-android-sdk-ddb-mapper:2.16.6'

    //cognito
    implementation 'com.amazonaws:aws-android-sdk-cognito:2.16.6'
    implementation 'com.amazonaws:aws-android-sdk-cognitoidentityprovider:2.16.6'

    implementation project(':esptouch')
}
<file_sep>package com.txtled.gp_a209.model.operate;

import android.app.Activity;

import com.tbruyelle.rxpermissions2.Permission;
import com.tbruyelle.rxpermissions2.RxPermissions;

import javax.inject.Inject;

import io.reactivex.functions.Consumer;

/**
 * Created by Mr.Quan on 2019/3/6.
 */

public class OperateHelperImpl implements OperateHelper {

    @Inject
    public OperateHelperImpl() {
    }

    @Override
    public void requestPermissions(Activity activity, String[] permissions,
                                   final OnPermissionsListener permissionsListener) {
        RxPermissions rxPermission = new RxPermissions(activity);
        rxPermission.requestEach(permissions)
                .subscribe(new Consumer<Permission>() {
                    @Override
                    public void accept(Permission permission) throws Exception {
                        if (permission.granted) {
                            // 用户已经同意该权限
                            permissionsListener.onSuccess(permission.name);
                            //Log.d(TAG, permission.name + " is granted.");
                        } else if (permission.shouldShowRequestPermissionRationale) {
                            // 用户拒绝了该权限，没有选中『不再询问』（Never ask again）,那么下次再次启动时，还会提示请求权限的对话框
                            permissionsListener.onAskAgain();
                            //Log.d(TAG, permission.name + " is denied. More info should be provided.");
                        } else {
                            // 用户拒绝了该权限，并且选中『不再询问』
                            permissionsListener.onFailure();
                            //Log.d(TAG, permission.name + " is denied.");
                        }
                    }
                });
    }
}
<file_sep>package com.txtled.gp_a209.di.module;

import com.txtled.gp_a209.application.MyApplication;
import com.txtled.gp_a209.model.DataManagerModel;
import com.txtled.gp_a209.model.db.DBHelper;
import com.txtled.gp_a209.model.db.DBHelperImpl;
import com.txtled.gp_a209.model.net.NetHelper;
import com.txtled.gp_a209.model.net.NetHelperImpl;
import com.txtled.gp_a209.model.operate.OperateHelper;
import com.txtled.gp_a209.model.operate.OperateHelperImpl;
import com.txtled.gp_a209.model.prefs.PreferencesHelper;
import com.txtled.gp_a209.model.prefs.PreferencesHelperImpl;

import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;

/**
 * Created by KomoriWu
 * on 2017/9/15.
 */
@Module
public class AppModule {
    private MyApplication myApplication;

    public AppModule(MyApplication myApplication) {
        this.myApplication = myApplication;
    }

    @Provides
    @Singleton
    MyApplication provideMyApplication() {
        return myApplication;
    }

    @Provides
    @Singleton
    DBHelper provideDBHelper(DBHelperImpl dbHelper) {
        return dbHelper;
    }

    @Provides
    @Singleton
    PreferencesHelper providePreferencesHelper(PreferencesHelperImpl preferencesHelper) {
        return preferencesHelper;
    }

    @Provides
    @Singleton
    NetHelper provideNetHelper(NetHelperImpl netHelper) {
        return netHelper;
    }

    @Provides
    @Singleton
    OperateHelper provideOperateHelper(OperateHelperImpl operateHelper) {
        return operateHelper;
    }

    @Provides
    @Singleton
    DataManagerModel provideDataManagerModel(DBHelperImpl dbHelper,
                                             PreferencesHelperImpl preferencesHelper,
                                             NetHelperImpl netHelper, OperateHelperImpl operateHelper) {
        return new DataManagerModel(dbHelper, preferencesHelper,netHelper,operateHelper);
    }
}
<file_sep>include ':app', ':esptouch'
rootProject.name='GP-A209'
<file_sep>package com.txtled.gp_a209;

import androidx.lifecycle.ViewModel;

public class FragmentLightViewModel extends ViewModel {
    // TODO: Implement the ViewModel
}
<file_sep>package com.txtled.gp_a209.main;

import android.content.Intent;
import android.view.KeyEvent;
import android.view.View;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import com.txtled.gp_a209.R;
import com.txtled.gp_a209.add.AddDeviceActivity;
import com.txtled.gp_a209.appinfo.AppInfoActivity;
import com.txtled.gp_a209.base.MvpBaseActivity;
import com.txtled.gp_a209.bean.DeviceInfo;
import com.txtled.gp_a209.bean.WWADeviceInfo;
import com.txtled.gp_a209.control.ControlActivity;
import com.txtled.gp_a209.information.InfoActivity;
import com.txtled.gp_a209.main.mvp.MainContract;
import com.txtled.gp_a209.main.mvp.MainPresenter;
import com.txtled.gp_a209.utils.AlertUtils;
import com.txtled.gp_a209.widget.ArialRoundButton;

import java.util.List;

import butterknife.BindView;

import static com.txtled.gp_a209.utils.Constants.APP;
import static com.txtled.gp_a209.utils.Constants.ENDPOINT;
import static com.txtled.gp_a209.utils.Constants.INFO;
import static com.txtled.gp_a209.utils.Constants.NAME;
import static com.txtled.gp_a209.utils.Constants.OK;
import static com.txtled.gp_a209.utils.Constants.RESULT;
import static com.txtled.gp_a209.utils.Constants.THING_DIR;
import static com.txtled.gp_a209.utils.Constants.TYPE;
import static com.txtled.gp_a209.utils.Constants.VERSION;
import static com.txtled.gp_a209.utils.Constants.WIFI;

public class MainActivity extends MvpBaseActivity<MainPresenter> implements MainContract.View,
        SwipeRefreshLayout.OnRefreshListener, DeviceListAdapter.OnDeviceClickListener,
        View.OnClickListener {

    @BindView(R.id.rlv_device_list)
    RecyclerView rlvDeviceList;
    @BindView(R.id.srl_refresh)
    SwipeRefreshLayout srlRefresh;
    @BindView(R.id.abt_off_all)
    ArialRoundButton abtOffAll;

    private DeviceListAdapter listAdapter;
    private String userId;
    private String wifiName;
    private AlertDialog dialog;
    private String name;

    @Override
    protected void beforeContentView() {

    }

    @Override
    public void init() {
        initToolbar();
        setNavigationIcon(false);
        tvTitle.setText(R.string.device_list);
        userId = presenter.init(this);
        abtOffAll.setOnClickListener(this);
        setRightImg(true, R.mipmap.devicelist_add_xhdpi, v ->
                startActivityForResult(new Intent(MainActivity.this,
                        AddDeviceActivity.class).putExtra(TYPE,0), RESULT));
        srlRefresh.setOnRefreshListener(this);
        rlvDeviceList.setHasFixedSize(true);
        rlvDeviceList.setLayoutManager(new LinearLayoutManager(this));
        listAdapter = new DeviceListAdapter(this,this,userId);
        rlvDeviceList.setAdapter(listAdapter);
        srlRefresh.setRefreshing(true);
        onRefresh();
    }

    @Override
    public int getLayout() {
        return R.layout.activity_main;
    }


    @Override
    public void setInject() {
        getActivityComponent().inject(this);
    }

    @Override
    public void onRefresh() {
        presenter.onRefresh();
    }

    @Override
    public void getDeviceData(List<WWADeviceInfo> data) {
        srlRefresh.setRefreshing(false);
        if (!data.isEmpty())
            listAdapter.setData(data);
    }

    @Override
    public void hidSnackBar() {
        hideSnackBar();
    }

    @Override
    public void checkLocation() {
        showSnackBar(abtOffAll, R.string.open_location);
    }

    @Override
    public void setNoWifiView() {
        showSnackBar(abtOffAll, R.string.no_wifi);
    }

    @Override
    public void closeRefresh() {
        srlRefresh.setRefreshing(false);
    }

    @Override
    public void setData(List<WWADeviceInfo> refreshData) {
        //srlRefresh.setRefreshing(false);

        if (!refreshData.isEmpty()){
            hidSnackBar();
            listAdapter.setDiscoveryData(refreshData);
        }

    }

    @Override
    public void noDevice() {
        //srlRefresh.setRefreshing(false);
        hidSnackBar();
        //showSnackBar(abtOffAll,R.string.no_device);
        showSnackBar(abtOffAll,R.string.no_device, R.string.retry, v -> {
            presenter.discovery();
            hidSnackBar();
            showSnackBar(abtOffAll,R.string.searching_device);
        });
    }

    @Override
    public void getWifiName(String ssid) {
        wifiName = ssid;
    }

    @Override
    public void deleteError() {
        dialog.dismiss();
        hidSnackBar();
        showSnackBar(abtOffAll,R.string.already_deleted);
    }

    @Override
    public void deleteSuccess() {
        dialog.dismiss();
        listAdapter.deleteItem(name);
    }

    @Override
    public void mqttInitFail() {
        dialog.dismiss();
        hidSnackBar();
        showSnackBar(abtOffAll,R.string.try_again);
    }

    @Override
    public void success(boolean allOff) {
        dialog.dismiss();
        if (allOff){
            //on
            abtOffAll.setBackgroundColor(getResources().getColor(R.color.black));
            abtOffAll.setTextColor(getResources().getColor(R.color.yellow));
            abtOffAll.setText(R.string.on_all);
        }else {
            //off
            abtOffAll.setBackgroundColor(getResources().getColor(R.color.gray));
            abtOffAll.setTextColor(getResources().getColor(R.color.bg_snack));
            abtOffAll.setText(R.string.off_all);
        }
    }

    @Override
    public void fail() {
        dialog.dismiss();
        hidSnackBar();
        showSnackBar(abtOffAll,R.string.some_no_responding);
    }

    @Override
    public void showLoading() {
        dialog = AlertUtils.showLoadingDialog(this,R.layout.alert_progress);
        dialog.show();
    }

    @Override
    public void showSearching() {
        runOnUiThread(() -> {
            hidSnackBar();
            showSnackBar(abtOffAll, R.string.searching_device);
        });
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (snackbar != null && snackbar.isShown()){
            hidSnackBar();
            return false;
        }else {
            return onExitActivity(keyCode,event);
        }
    }

    /**
     * 列表点击事件
     * @param endpoint
     */
    @Override
    public void onDeviceClick(String endpoint,String name) {
        startActivity(new Intent(this, ControlActivity.class)
                .putExtra(ENDPOINT,endpoint).putExtra(NAME,name));
    }

    @Override
    public void onSettingClick(WWADeviceInfo data,String name) {
        startActivityForResult(new Intent(this, InfoActivity.class)
                .putExtra(NAME, data.getFriendlyNames())
                .putExtra(ENDPOINT,data.getIp()).putExtra(VERSION,data.getVer())
                .putExtra(WIFI,wifiName).putExtra(THING_DIR,data.getThing()),INFO);
    }

    /**
     * 侧滑删除按钮
     * @param data
     * @param name
     */
    @Override
    public void onDeleteClick(WWADeviceInfo data,String name) {
        this.name = name;
        dialog = AlertUtils.showLoadingDialog(this,R.layout.alert_progress);
        dialog.show();
        presenter.deleteDevice(data,name);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (requestCode == RESULT || requestCode == INFO || requestCode == APP){
            if (resultCode == OK){
                srlRefresh.setRefreshing(true);
                onRefresh();
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public void onLeftClick() {
        startActivityForResult(new Intent(this, AppInfoActivity.class),APP);
    }

    @Override
    public void onClick(View v) {
        presenter.onClick(v);
    }

    @Override
    public void onDestroy() {
        presenter.onDestroy();
        super.onDestroy();
    }
}
<file_sep>package com.txtled.gp_a209.main.mvp;

import android.app.Activity;
import android.content.Context;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.net.DhcpInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.view.View;

import androidx.core.location.LocationManagerCompat;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.CognitoCachingCredentialsProvider;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.AttributeValueUpdate;
import com.amazonaws.services.dynamodbv2.model.GetItemRequest;
import com.amazonaws.services.dynamodbv2.model.GetItemResult;
import com.amazonaws.services.dynamodbv2.model.UpdateItemRequest;
import com.amazonaws.services.iot.AWSIotClient;
import com.amazonaws.services.iot.client.AWSIotDevice;
import com.amazonaws.services.iot.client.AWSIotException;
import com.amazonaws.services.iot.client.AWSIotQos;
import com.amazonaws.services.iot.model.CertificateStatus;
import com.amazonaws.services.iot.model.DeleteThingRequest;
import com.amazonaws.services.iot.model.DeleteThingResult;
import com.amazonaws.services.iot.model.DetachPolicyRequest;
import com.amazonaws.services.iot.model.DetachSecurityProfileRequest;
import com.amazonaws.services.iot.model.DetachThingPrincipalRequest;
import com.amazonaws.services.iot.model.UpdateCertificateRequest;
import com.txtled.gp_a209.R;
import com.txtled.gp_a209.add.listener.OnUdpSendRequest;
import com.txtled.gp_a209.add.udp.UDPBuild;
import com.txtled.gp_a209.application.MyApplication;
import com.txtled.gp_a209.base.CommonSubscriber;
import com.txtled.gp_a209.base.RxPresenter;
import com.txtled.gp_a209.bean.DeviceInfo;
import com.txtled.gp_a209.bean.WWADeviceInfo;
import com.txtled.gp_a209.broadcast.MyBroadcastReceiver;
import com.txtled.gp_a209.control.mqtt.MqttClient;
import com.txtled.gp_a209.control.mqtt.MyShadowMessage;
import com.txtled.gp_a209.control.mqtt.listener.OnConnectListener;
import com.txtled.gp_a209.control.mqtt.listener.OnMessageListener;
import com.txtled.gp_a209.model.DataManagerModel;
import com.txtled.gp_a209.utils.RxUtil;
import com.txtled.gp_a209.utils.Utils;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.inject.Inject;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableOnSubscribe;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

import static com.txtled.gp_a209.base.BaseActivity.TAG;
import static com.txtled.gp_a209.utils.Constants.DATA_DEVICE;
import static com.txtled.gp_a209.utils.Constants.DB_NAME;
import static com.txtled.gp_a209.utils.Constants.DISCOVERY;
import static com.txtled.gp_a209.utils.Constants.FRIENDLY_NAME;
import static com.txtled.gp_a209.utils.Constants.MY_OIT_CE;
import static com.txtled.gp_a209.utils.Constants.PUBLISH;
import static com.txtled.gp_a209.utils.Constants.REST_API;
import static com.txtled.gp_a209.utils.Constants.SEND_THING_NAME;
import static com.txtled.gp_a209.utils.Constants.THING_DIR;
import static com.txtled.gp_a209.utils.Constants.USER_ID;
import static com.txtled.gp_a209.utils.ForUse.ACCESS_KEY;
import static com.txtled.gp_a209.utils.ForUse.SECRET_ACCESS_KEY;

/**
 * Created by Mr.Quan on 2019/12/9.
 */
public class MainPresenter extends RxPresenter<MainContract.View> implements MainContract.Presenter {

    private DataManagerModel mDataManagerModel;
    private CognitoCachingCredentialsProvider provider;
    private AmazonDynamoDB client;
    private String userId;
    private List<WWADeviceInfo> data;
    private boolean isNoWifi;
    private MyBroadcastReceiver mReceiver;
    private WifiInfo wifiInfo;
    private WifiManager myWifiManager;
    private DhcpInfo dhcpInfo;
    private Activity activity;
    private String broadCast;
    private List<WWADeviceInfo> refreshData;
    private String strReceive;
    private UDPBuild udpBuild;
    private Disposable timeCount;
    private int count;
    private AWSIotClient awsIot;
    private boolean allOff;

    @Inject
    public MainPresenter(DataManagerModel mDataManagerModel) {
        this.mDataManagerModel = mDataManagerModel;
    }

    @Override
    public String init(Activity activity) {
        this.activity = activity;
        provider = MyApplication.getCredentialsProvider();
        client = new AmazonDynamoDBClient(provider);
        userId = mDataManagerModel.getUserId();
        createIotService();

        IntentFilter filter = new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        if (isSDKAtLeastP()) {
            filter.addAction(LocationManager.PROVIDERS_CHANGED_ACTION);
        }

        mReceiver = new MyBroadcastReceiver((context, info) -> onChanged(context, info));
        activity.registerReceiver(mReceiver, filter);

        return userId;
    }

    /**
     * 创建service
     */
    private void createIotService() {
        try {
            AWSCredentials credentials = new BasicAWSCredentials(ACCESS_KEY, SECRET_ACCESS_KEY);

            ClientConfiguration clientConfig = new ClientConfiguration();

            clientConfig.setProtocol(Protocol.HTTPS);

            awsIot = new AWSIotClient(credentials, clientConfig);

        } catch (Exception e) {
            Utils.Logger(TAG, "IotServiceUtil.createIotService aws-iot创建连接异常", e.getMessage());
            //LOGGER.error("IotServiceUtil.createIotService aws-iot创建连接异常",e);
            awsIot = null;
        }
    }

    private void onChanged(Context context, WifiInfo info) {
        view.hidSnackBar();
        boolean disconnected = info == null
                || info.getNetworkId() == -1
                || "<unknown ssid>".equals(info.getSSID());
        if (disconnected) {
            isNoWifi = true;
            if (isSDKAtLeastP()) {
                LocationManager locationManager = (LocationManager) context
                        .getSystemService(Context.LOCATION_SERVICE);

                if (!(locationManager != null && LocationManagerCompat
                        .isLocationEnabled(locationManager))) {
                    //view.checkLocation();
                } else {

                    view.setNoWifiView();
                }
            } else {
                view.setNoWifiView();
            }
        } else {
            isNoWifi = false;
            wifiInfo = info;
            String ssid = info.getSSID();
            if (ssid.startsWith("\"") && ssid.endsWith("\"")) {
                ssid = ssid.substring(1, ssid.length() - 1);
            }
            view.getWifiName(ssid);
        }
    }

    public boolean isSDKAtLeastP() {
        return Build.VERSION.SDK_INT >= 28;
    }

    /**
     * 根据本机ip得出广播地址
     */
    private void getBroadCastIp() {
        myWifiManager = ((WifiManager) activity.getApplicationContext()
                .getSystemService(Context.WIFI_SERVICE));
        dhcpInfo = myWifiManager.getDhcpInfo();
        String ip = Utils.getWifiIp(dhcpInfo.ipAddress);
        String netMask = Utils.getWifiIp(dhcpInfo.netmask);
        String[] ipTemp = ip.split("\\.");
        String[] maskTemp = netMask.split("\\.");
        broadCast = "";
        for (int i = 0; i < maskTemp.length; i++) {
            if (maskTemp[i].equals("255")) {
                broadCast += (ipTemp[i] + ".");
            } else {
                broadCast += (255 - Integer.parseInt(maskTemp[i])) + (i == maskTemp.length - 1 ? "" : ".");

            }
        }
    }

    /**
     * 列表刷新
     */
    @Override
    public void onRefresh() {
        addSubscribe(Flowable.create((FlowableOnSubscribe<List<WWADeviceInfo>>) e -> {
            //查数据
            try {
                discovery();
                e.onNext(getDeviceData());
            }catch (Exception e1){
                refreshData = new ArrayList<>();
                e.onNext(refreshData);
            }
        }, BackpressureStrategy.BUFFER).compose(RxUtil.rxSchedulerHelper())
                .subscribeWith(new CommonSubscriber<List<WWADeviceInfo>>(view) {
                    @Override
                    public void onNext(List<WWADeviceInfo> data) {
                        //返回数据
                        view.getDeviceData(data);
                    }
                }));

    }

    private List<WWADeviceInfo> getDeviceData() {
        refreshData = new ArrayList<>();
        HashMap<String, AttributeValue> key = new HashMap<>();
        key.put(USER_ID, new AttributeValue().withS(userId));
        //获取数据
        GetItemResult itemResult = client.getItem(new GetItemRequest()
                .withTableName(DB_NAME).withKey(key));
        if (itemResult.getItem() != null) {
            Map<String, AttributeValue> resultItem = itemResult.getItem();
            AttributeValue cert_data = resultItem.get(THING_DIR);
            //设备名称
            String[] names = cert_data.getM().keySet().toArray(new String[cert_data.getM().size()]);
            //endpointId
            for (int i = 0; i < names.length; i++) {
                WWADeviceInfo info = new WWADeviceInfo();
                info.setFriendlyNames(userId+"_"+names[i]);
                info.setThing(cert_data.getM().get(names[i]).getS());
                refreshData.add(info);
            }
        }
        return refreshData;
    }

    /**
     * 删除设备
     * @param data
     * @param name
     */
    @Override
    public void deleteDevice(WWADeviceInfo data, String name) {
        broadCast = data.getIp();
        addSubscribe(Flowable.just(name).subscribeOn(Schedulers.io()).observeOn(Schedulers.io())
                    .subscribeWith(new CommonSubscriber<String>(view) {
                        @Override
                        public void onNext(String name) {
                            //查数据
                            try {
                                //delete DB
                                String[] names = data.getFriendlyNames().split(",");
                                if (names.length > 1){
                                    //只把自己的friendlyName部分删掉
                                    if (deleteDB(name)){
                                        StringBuffer buffer = new StringBuffer();
                                        for (int i = 0; i < names.length; i++) {
                                            if (!names[i].contains(userId)){
                                                buffer.append(names[i] + (i == names.length - 1 ? "" : ","));
                                            }
                                        }
                                        udpSend(String.format(FRIENDLY_NAME, buffer.toString()), result -> {
                                            if (result.contains("\"friendlyname\":1")){
                                                view.deleteSuccess();
                                            }else {
                                                udpBuild.sendMessage(String.format(FRIENDLY_NAME,
                                                        buffer.toString()),broadCast);
                                            }
                                        });
                                    }else {
                                        view.deleteError();
                                        hidSnackBarDelay();
                                    }
                                }else {
                                    //删除事物 未完成
                                    view.deleteSuccess();
//                                    awsIot.detachThingPrincipal(new DetachThingPrincipalRequest()
//                                            .withThingName(data.getThing())
//                                            .withPrincipal("<KEY>"));
//                                    awsIot.updateCertificate(new UpdateCertificateRequest()
//                                            .withCertificateId("1<KEY>")
//                                            .withNewStatus("INACTIVE"));
//                                    awsIot.detachPolicy(new DetachPolicyRequest()
//                                            .withPolicyName(MY_OIT_CE)
//                                            .withTarget("arn:aws:iot:us-east-1:612535970613:cert/1f29341c16b40760b8d2d6c8783682bcc6ecec6d828746fe459321f85e79b243"));
//                                    //awsIot.detachSecurityProfile(new DetachSecurityProfileRequest().)
//                                    awsIot.detachThingPrincipal(new DetachThingPrincipalRequest().withThingName(data.getThing()));

//                                    DeleteThingResult request = awsIot.deleteThing(new DeleteThingRequest()
//                                            .withThingName(data.getThing()));
//                                    //删除设备所有信息
//                                    if (deleteDB(name)){
//                                        //delete thing
//
//                                        if (!request.toString().isEmpty()) {
//                                            //写入设备
//                                            writeToDevice();
//                                            view.deleteSuccess();
//                                        }else {
//                                            view.deleteError();
//                                            hidSnackBarDelay();
//                                        }
//                                    }else {
//                                        view.deleteError();
//                                        hidSnackBarDelay();
//                                    }
                                }
                            } catch (Exception e1) {
                                view.deleteError();
                                hidSnackBarDelay();
                            }
                        }
                    }));

    }

    /**
     * 按钮点击事件
     * @param v
     */
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.abt_off_all:
                view.showLoading();
                if (!refreshData.isEmpty()){
                    for (WWADeviceInfo info : refreshData) {
                        MqttClient.getClient().initClient(info.getThing(), new OnConnectListener() {
                            @Override
                            public void onSuccess(AWSIotDevice device) {
                                AWSIotDevice iotDevice = device;
                                powerOff(iotDevice,info.getThing());
                            }
                            @Override
                            public void onFail() {
                                view.mqttInitFail();
                                hidSnackBarDelay();
                            }
                        });
                    }
                }
                break;
        }
    }

    @Override
    public void discovery() {
        if (!isNoWifi) {
            getBroadCastIp();
            view.showSearching();
            if (udpBuild != null){
                System.out.println("discovery执行111111111");
                udpBuild.stopUDPSocket();
            }
            udpSend(DISCOVERY, result -> {
            });

        }
    }

    @Override
    public void onDestroy() {
        activity.unregisterReceiver(mReceiver);
    }

    private void hidSnackBarDelay(){
        addSubscribe(Flowable.timer(3, TimeUnit.SECONDS)
                .compose(RxUtil.rxSchedulerHelper())
                .subscribeWith(new CommonSubscriber<Long>(view) {
                    @Override
                    public void onNext(Long aLong) {
                        view.hidSnackBar();
                    }
                }));
    }

    private void powerOff(AWSIotDevice iotDevice, String endpoint) {
        try {
            MyShadowMessage myMessage = new MyShadowMessage(String.format(PUBLISH,endpoint),
                    AWSIotQos.QOS0,String.format(DATA_DEVICE,allOff == true ? "\"on\"" : "\"off\""));
            myMessage.setListener(new OnMessageListener() {
                @Override
                public void onSuccess() {
                    allOff = !allOff;
                    view.success(allOff);
                }

                @Override
                public void onFailure() {
                    view.fail();
                    hidSnackBarDelay();
                }

                @Override
                public void onTimeout() {
                    view.fail();
                    hidSnackBarDelay();
                }
            });
            iotDevice.update(myMessage,5000);
        } catch (AWSIotException e) {
            e.printStackTrace();
        }
    }

    private void writeToDevice() {
        udpSend(String.format(FRIENDLY_NAME, ""), result -> {
            if (result.contains("\"friendlyname\"")){
                udpBuild.sendMessage(result.contains("1") ?
                        String.format(SEND_THING_NAME, REST_API, "") :
                        String.format(FRIENDLY_NAME,"") ,broadCast);
            }else {
                if (result.contains("\"endpoint\":1")){
                    view.deleteSuccess();
                }else {
                    udpBuild.sendMessage(String.format(SEND_THING_NAME, REST_API, ""),broadCast);
                }
            }
        });
    }

    /**
     * 发送udp数据
     * @param message 内容
     * @param listener 监听
     */
    private void udpSend(String message, OnUdpSendRequest listener) {
        data = new ArrayList<>();
        strReceive = "";
        udpBuild = UDPBuild.getUdpBuild();
        myWifiManager = ((WifiManager) activity.getApplicationContext()
                .getSystemService(Context.WIFI_SERVICE));
        dhcpInfo = myWifiManager.getDhcpInfo();
        udpBuild.setIgnoreIp(Utils.getWifiIp(dhcpInfo.ipAddress));
        udpBuild.setUdpReceiveCallback(result -> {
            strReceive = new String(result.getData(), 0, result.getLength());
            try {
                JSONObject deviceInfo = new JSONObject(strReceive);
                if (message.equals(DISCOVERY)) {
                    WWADeviceInfo info = new WWADeviceInfo(
                            deviceInfo.optString("ip"),
                            deviceInfo.optString("netmask"),
                            deviceInfo.optString("gw"),
                            deviceInfo.optString("host"),
                            deviceInfo.optString("port"),
                            deviceInfo.optString("cid"),
                            deviceInfo.optString("thing"),
                            deviceInfo.optString("friendlyname"),
                            deviceInfo.optString("ver")
                    );
                    data.add(info);
                    willStop();
                } else {
                    listener.OnRequestListener(strReceive);
                }

            } catch (JSONException e) {
                e.printStackTrace();
            }
        });
        udpBuild.sendMessage(message, broadCast);
        setTime(message, listener);
    }

    private void willStop() {
        if (timeCount != null) {
            timeCount.dispose();
        }
        timeCount = Observable.timer(5, TimeUnit.SECONDS).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()).subscribe(aLong -> {
                            if (!data.isEmpty()) {
                                for (int i = 0; i < data.size(); i++) {
                                    if (data.get(i).getFriendlyNames() != null) {
                                        if (!data.get(i).getFriendlyNames()
                                                .contains(userId)) {
                                            data.remove(i);
                                        }
                                    } else {
                                        data.remove(i);
                                    }
                                }
                                view.setData(data);
                                udpBuild.stopUDPSocket();
                                System.out.println("discovery执行");

                            }else {
                                view.noDevice();
                            }
                        }
                );
    }

    private void setTime(String message, OnUdpSendRequest listener) {

        addSubscribe(Flowable.timer(3, TimeUnit.SECONDS)
                .compose(RxUtil.rxSchedulerHelper())
                .subscribeWith(new CommonSubscriber<Long>(view) {

                    @Override
                    public void onNext(Long aLong) {
                        if (data.isEmpty()) {
                            count += 1;
                            if (count < 3) {
                                udpSend(message, listener);
                            } else {
                                count = 0;
                                view.noDevice();
                                //hidSnackBarDelay();
                            }
                            //udpBuild.sendMessage(message,broadCast);
                        } else {
                            count = 0;
                        }
                    }
                }));
    }

    /**
     * 删除数据库数据
     * @param name
     * @return
     */
    private boolean deleteDB(String name) {
        HashMap<String, AttributeValue> key = new HashMap<>();
        key.put(USER_ID, new AttributeValue().withS(userId));
        //获取数据
        GetItemResult itemResult = client.getItem(new GetItemRequest()
                .withTableName(DB_NAME).withKey(key));
        if (itemResult.getItem() != null) {
            Map<String, AttributeValue> resultItem = itemResult.getItem();
            AttributeValue cert_data = resultItem.get(THING_DIR);
            //删除设备
            cert_data.getM().remove(name);
            try{
                client.updateItem(new UpdateItemRequest().withTableName(DB_NAME)
                        .withKey(key).addAttributeUpdatesEntry(THING_DIR,
                                new AttributeValueUpdate()
                                        .withValue(cert_data)));
                return true;
            }catch (Exception e){
                view.deleteError();
                hidSnackBarDelay();
                return false;
            }
        }else {
            return false;
        }
    }
}
<file_sep>package com.txtled.gp_a209.light.mvp;

import android.app.Activity;

import com.txtled.gp_a209.base.RxPresenter;
import com.txtled.gp_a209.model.DataManagerModel;

import javax.inject.Inject;

/**
 * Created by Mr.Quan on 2020/5/25.
 */
public class LightPresenter extends RxPresenter<LightContract.View> implements LightContract.Presenter {
    private DataManagerModel dataManagerModel;
    @Inject
    public LightPresenter(DataManagerModel dataManagerModel) {
        this.dataManagerModel = dataManagerModel;
    }


}
<file_sep>package com.txtled.gp_a209.information.mvp;

import android.app.Activity;
import android.view.View;

import com.txtled.gp_a209.base.BasePresenter;
import com.txtled.gp_a209.base.BaseView;

/**
 * Created by Mr.Quan on 2020/3/23.
 */
public interface InfoContract {
    interface View extends BaseView{

    }

    interface Presenter extends BasePresenter<View>{

        void init(Activity activity);

        String getName(String friendlyName);
    }
}
<file_sep>package com.txtled.gp_a209.light;

import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.Nullable;

import com.txtled.gp_a209.R;
import com.txtled.gp_a209.base.MvpBaseFragment;
import com.txtled.gp_a209.light.mvp.LightContract;
import com.txtled.gp_a209.light.mvp.LightPresenter;
import com.txtled.gp_a209.widget.ArialRoundButton;
import com.txtled.gp_a209.widget.ArialRoundRadioButton;

import butterknife.BindView;

/**
 * Created by Mr.Quan on 2020/5/25.
 */
public class LightFragment extends MvpBaseFragment<LightPresenter> implements LightContract.View {

    @BindView(R.id.button_light_red)
    ArialRoundRadioButton cbRed;
    @BindView(R.id.button_light_orange)
    ArialRoundRadioButton cbOrange;
    @BindView(R.id.button_light_yellow)
    ArialRoundRadioButton cbYellow;
    @BindView(R.id.button_light_green)
    ArialRoundRadioButton cbGreen;
    @BindView(R.id.button_light_cy_blue)
    ArialRoundRadioButton cbCyblue;
    @BindView(R.id.button_light_blue)
    ArialRoundRadioButton cbBlue;
    @BindView(R.id.button_light_purple)
    ArialRoundRadioButton cbPurple;
    @BindView(R.id.button_light_white)
    ArialRoundRadioButton cbWhite;
    @BindView(R.id.button_light_cycle)
    ArialRoundRadioButton cbCycle;
    @BindView(R.id.light_button_switch)
    ArialRoundButton cbSwitch;

    //activity设置灯光回调
    public interface LightStateCall{
        public void lightCallVotic(int state);
    }


    private LightStateCall lightCall;


    public void setLightCall(LightStateCall lightCall) {
        this.lightCall = lightCall;
    }

    private int currentid;
    private int lastid;
    private int lightState;
    private View view;
    //参数用来判断：界面初始化完成之前activity有设置灯光状态
    boolean setState;

    //设置灯光失败
    public void setLightFail(){
        setLightBtn(lastid,false);
    }

    //设置当前的被选中按钮，提供给activity使用的
    public void setCurrentid(int currentid){
        System.out.println("当前的灯光id"+currentid);
        if (currentid<0||currentid>9){
            return;
        }
        this.lightState = currentid;
        setState = true;
        if (view==null){
            return;
        }
        switch (currentid){
            case 0:
                setLightBtn(R.id.light_button_switch,false);
                break;
            case 1:
                setLightBtn(R.id.button_light_red,false);
                break;
            case 2:
                setLightBtn(R.id.button_light_orange,false);
                break;
            case 3:
                setLightBtn(R.id.button_light_yellow,false);
                break;
            case 4:
                setLightBtn(R.id.button_light_green,false);
                break;
            case 5:
                setLightBtn(R.id.button_light_cy_blue,false);
                break;
            case 6:
                setLightBtn(R.id.button_light_blue,false);
                break;
            case 7:
                setLightBtn(R.id.button_light_purple,false);
                break;
            case 8:
                setLightBtn(R.id.button_light_white,false);
                break;
            default:
                setLightBtn(R.id.button_light_cycle,false);
                break;
        }
    }

    @Override
    protected void initInject() {
        getFragmentComponent().inject(this);
    }

    @Override
    public View initView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_light_fragment, container, false);
        return view;
    }

    //设置按钮的背景色和透明度
    public void setBtnColor(ArialRoundRadioButton btn, int color, int alpha) {
        GradientDrawable myGrad = (GradientDrawable) btn.getBackground();
        myGrad.setColor(color);
        myGrad.setAlpha(alpha);
    }

    @Override
    public void onDetach() {
        super.onDetach();
    }
/*

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {

    }
*/

    public void onClicks(View v) {
        setLightBtn(v.getId(),true);
    }

    //改变被选中的灯光按钮状态，先把原来的按钮状态清空，在设置选中的按钮
    public void setLightBtn(int btnid ,boolean isClick){
            System.out.println("调用setLightBtn"+btnid);
            if (currentid != btnid) {
                if (btnid!=R.id.light_button_switch){
                    lastid = currentid;
                    currentid = btnid;
                    System.out.println("currentid"+currentid);
                    if (lastid!=0){
                        changeBtnState(lastid, false);
                    }
                    changeBtnState(currentid, true);
                }
                else {
                    if (currentid!=0)changeBtnState(currentid, false);
                    currentid = btnid;
                    lastid = currentid;
                    lightState = 0;
                    cbSwitch.setText(R.string.turn_off);
                }
                if (lightCall!=null&&isClick){
                    btnIdToLightState(btnid);
                    lightCall.lightCallVotic(lightState);
                }
            }

    }

    //按钮的id转换成灯光的状态
    public void btnIdToLightState(int btnid){
            switch (btnid){
                case R.id.light_button_switch:
                    lightState=0;
                    break;
                case R.id.button_light_red:
                    lightState=1;
                    break;
                case R.id.button_light_orange:
                    lightState=2;
                    break;
                case R.id.button_light_yellow:
                    lightState=3;
                    break;
                case R.id.button_light_green:
                    lightState=4;
                    break;
                case R.id.button_light_cy_blue:
                    lightState=5;
                    break;
                case R.id.button_light_blue:
                    lightState=6;
                    break;
                case R.id.button_light_purple:
                    lightState=7;
                    break;
                case R.id.button_light_white:
                    lightState=8;
                    break;
                case R.id.button_light_cycle:
                    lightState=9;
                    break;

            }

    }

    //改变按钮的状态
    public void changeBtnState(int btnid, boolean select) {
        if (btnid==R.id.light_button_switch)return;
        System.out.println("调用changeBtnState"+btnid);
        int colors = Color.BLACK;
        switch (btnid){
            case R.id.button_light_red:
                System.out.println("红色red");
                colors = Color.RED;
                lightState = 1;
                break;
            case R.id.button_light_orange:
                System.out.println("橙色red2");
                lightState = 2;
                colors = Color.rgb(255, 165, 0);
                break;
            case R.id.button_light_yellow:
                System.out.println("黄色red3");
                lightState = 3;
                colors = Color.YELLOW;
                break;
            case R.id.button_light_green:
                colors = Color.GREEN;
                lightState = 4;
                System.out.println("红色red4");

                break;
            case R.id.button_light_cy_blue:
                colors = Color.rgb(75, 0, 130);
                lightState = 5;
                System.out.println("红色red5");

                break;
            case R.id.button_light_blue:
                colors = Color.BLUE;
                lightState = 6;
                System.out.println("红色red6");

                break;
            case R.id.button_light_purple:
                System.out.println("红色red7");
                lightState = 7;
                colors = Color.rgb(128, 0, 128);
                break;
            case R.id.button_light_white:
                System.out.println("红色red8");
                lightState = 8;
                colors = Color.WHITE;
                break;
            case R.id.button_light_cycle:
                System.out.println("红色red9");
                lightState = 9;
                colors = Color.GRAY;
                break;

        }

        int alpha = select == true ? 255 : 50;
        if (view==null)System.out.println("view是空的");
        ArialRoundRadioButton btn = (ArialRoundRadioButton)view.findViewById(btnid);

        GradientDrawable myGrad = (GradientDrawable) btn.getBackground();
/*
            myGrad.setColor(colors);
*/
        myGrad.setAlpha(alpha);

    }

    @Override
    public void onResume() {
        super.onResume();
    }

    @Override
    public void init() {

        setBtnColor(cbRed, Color.RED, 50);
        setBtnColor(cbOrange, Color.rgb(255, 165, 0), 50);
        setBtnColor(cbYellow, Color.YELLOW, 50);
        setBtnColor(cbGreen, Color.GREEN, 50);
        setBtnColor(cbCyblue, Color.rgb(75, 0, 130), 50);
        setBtnColor(cbBlue, Color.BLUE, 50);
        setBtnColor(cbPurple, Color.rgb(128, 0, 128), 50);
        setBtnColor(cbWhite, Color.WHITE, 50);
        setBtnColor(cbCycle,Color.GRAY,50);
        currentid  = R.id.button_light_red;
        lastid = R.id.button_light_red;

        View.OnClickListener listener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                System.out.println("点击了按钮1");
                onClicks(v);
            }
        };
        cbRed.setOnClickListener(listener);
        cbOrange.setOnClickListener(listener);
        cbYellow.setOnClickListener(listener);
        cbGreen.setOnClickListener(listener);
        cbCyblue.setOnClickListener(listener);
        cbBlue.setOnClickListener(listener);
        cbPurple.setOnClickListener(listener);
        cbWhite.setOnClickListener(listener);
        cbCycle.setOnClickListener(listener);
        cbSwitch.setOnClickListener(listener);
        if (setState==true){
            setCurrentid(lightState);
        }

/*
        cbRed.setOnClickListener(this);
*/


//        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext()) {
//            @Override
//            public boolean canScrollVertically() {
//                // 直接禁止垂直滑动
//                return false;
//            }
//        };


    }


}

<file_sep>package com.txtled.gp_a209.utils;


import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.animation.AlphaAnimation;
import android.view.animation.AnimationSet;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;

import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.TextInputEditText;
import com.txtled.gp_a209.R;
import com.txtled.gp_a209.widget.ArialRoundButton;
import com.txtled.gp_a209.widget.ArialRoundTextView;


public class AlertUtils {
    //private static OnCreateThingListener thingListener;
    private static boolean canClose = false;
    public static OnConfirmClickListener clickListener;

    public static void showErrorMessage(Context context, int titleRes,
                                        String errorCode, DialogInterface.OnClickListener listener) {
//        if (!((Activity) context).isFinishing()) {
//            AlertDialog.Builder builder = new AlertDialog.Builder(context)
//                    .setMessage(context.getResources().getIdentifier("ERROR_CODE_" + errorCode,
//                            "string", context.getPackageName()));
//            if (titleRes != 0) {
//                builder.setTitle(titleRes);
//            }
//            if (listener == null) {
//                builder.setNegativeButton(R.string.ok, new DialogInterface.OnClickListener() {
//                    @Override
//                    public void onClick(DialogInterface dialogInterface, int i) {
//                        dialogInterface.dismiss();
//                    }
//                });
//            } else {
//                builder.setNegativeButton(R.string.ok, listener);
//            }
//            Dialog dialog = builder.create();
//            dialog.setCancelable(true);
//            dialog.show();
//        }
    }

    public static void showErrorMessage(Context context, String errorCode) {
        showErrorMessage(context, 0, errorCode, null);
    }

    public static void showErrorMessage(Context context,
                                        String errorCode, DialogInterface.OnClickListener listener) {
        showErrorMessage(context, 0, errorCode, listener);
    }

    public static void showAlertDialog(Context context, String message,
                                       DialogInterface.OnClickListener listener0,
                                       DialogInterface.OnClickListener listener1) {
//        if (!((Activity) context).isFinishing()) {
//            AlertDialog dialog = new AlertDialog.Builder(context)
//                    .setMessage(message)
//                    .setNegativeButton(R.string.cancel, listener0)
//                    .setPositiveButton(R.string.confirm, listener1)
//                    .create();
//            dialog.setCancelable(true);
//            dialog.show();
//        }
    }

    public interface OnConfirmClickListener{
        void onConfirmClick(boolean b);
    }

    public static void setListener(OnConfirmClickListener listener){
        clickListener = listener;
    }

//    public static OnCreateThingListener getThingListener(){
//        return thingListener;
//    }

    public static int width;

    public static void showHintDialog(Context context, int viewId,String title,
                                      int msg, boolean isConfig){
        if (!((Activity) context).isFinishing()){
            LayoutInflater inflater = LayoutInflater.from(context);
            View view = inflater.inflate(viewId,null);
            ArialRoundButton abtOk = view.findViewById(R.id.abt_ok);
            ArialRoundTextView atvHintTitle = view.findViewById(R.id.atv_hint_title);
            ArialRoundTextView atvHintMsg = view.findViewById(R.id.atv_hint_msg);
            atvHintTitle.setText(title);
            atvHintMsg.setText(msg);
            abtOk.setText(isConfig ? R.string.next : R.string.ok);
            AlertDialog dialog = new AlertDialog.Builder(context)
                    .setView(view)
                    .create();
            dialog.setCancelable(true);
            dialog.show();
            Window window = dialog.getWindow();
            window.setWindowAnimations(R.style.dialogWindowAnimInToOut);
            window.setBackgroundDrawable(context.getResources()
                    .getDrawable(R.drawable.background_white));
            abtOk.setOnClickListener(v -> {
                dialog.dismiss();
                clickListener.onConfirmClick(isConfig);
            });
        }
    }

    public static AlertDialog showProgressDialog(Context context,String wifiName,String pass){
        if (!((Activity) context).isFinishing()){
            LayoutInflater inflater = LayoutInflater.from(context);
            View config = inflater.inflate(R.layout.alert_configure,null);
            ArialRoundTextView atvWifi = config.findViewById(R.id.atv_wifi);
            ArialRoundTextView atvPass = config.findViewById(R.id.atv_pass);
            atvWifi.setText(context.getString(R.string.config_wifi,wifiName));
            atvPass.setText(pass);
            AlertDialog configDialog = new AlertDialog.Builder(context,R.style.TransparentDialog)
                    .setView(config)
                    .create();
            configDialog.setCancelable(false);
            configDialog.show();
            Window cWindow = configDialog.getWindow();

            ViewTreeObserver vto = atvWifi.getViewTreeObserver();
            vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                public boolean onPreDraw() {
                    atvWifi.getViewTreeObserver().removeOnPreDrawListener(this);
                    width = atvWifi.getMeasuredWidth();
                    return true;
                }
            });

            ViewTreeObserver passVto = atvPass.getViewTreeObserver();
            passVto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                public boolean onPreDraw() {
                    atvPass.getViewTreeObserver().removeOnPreDrawListener(this);
                    width = atvPass.getMeasuredWidth() > width ?
                            atvPass.getMeasuredWidth() : width;
                    cWindow.setLayout(width+60, RelativeLayout.LayoutParams.WRAP_CONTENT);
                    return true;
                }
            });
            cWindow.setWindowAnimations(R.style.dialogWindowAnimInToOut);
            cWindow.setBackgroundDrawable(context.getResources()
                    .getDrawable(R.drawable.background_white));
            return configDialog;
        }else {
            return null;
        }
    }

    public static AlertDialog showProgressDialog(Context context){
        if (!((Activity) context).isFinishing()){
            LayoutInflater inflater = LayoutInflater.from(context);
            View config = inflater.inflate(R.layout.alert_configure,null);
            ArialRoundTextView atvWifi = config.findViewById(R.id.atv_wifi);
            ArialRoundTextView atvPass = config.findViewById(R.id.atv_pass);
            atvWifi.setText(R.string.uploading);
            atvPass.setVisibility(View.INVISIBLE);
            AlertDialog configDialog = new AlertDialog.Builder(context,R.style.TransparentDialog)
                    .setView(config)
                    .create();
            configDialog.setCancelable(false);
            configDialog.show();
            Window cWindow = configDialog.getWindow();

            ViewTreeObserver vto = atvWifi.getViewTreeObserver();
            vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                public boolean onPreDraw() {
                    atvWifi.getViewTreeObserver().removeOnPreDrawListener(this);
                    width = atvWifi.getMeasuredWidth();
                    cWindow.setLayout(width+60, RelativeLayout.LayoutParams.WRAP_CONTENT);
                    return true;
                }
            });
            cWindow.setWindowAnimations(R.style.dialogWindowAnimInToOut);
            cWindow.setBackgroundDrawable(context.getResources()
                    .getDrawable(R.drawable.background_yellow));
            return configDialog;
        }else {
            return null;
        }
    }

    private static void setAlphaAnimation(View view){
        AlphaAnimation animation = new AlphaAnimation(0f, 1f);
        animation.setDuration(500);
        view.setAnimation(animation);
        animation.start();
    }

    public static AlertDialog showLoadingDialog(Context context, int viewId){
        if (!((Activity) context).isFinishing()) {
            LayoutInflater layoutInflater = LayoutInflater.from(context);
            View view = layoutInflater.inflate(viewId, null);
            AlertDialog dialog = new AlertDialog.Builder(context, R.style.TransparentDialog)
                    .setView(view)
                    .create();
            dialog.setCancelable(false);
            return dialog;
        }else {
            return null;
        }
    }

    public static void showAlertDialog(Context context, int title, int message) {
        if (!((Activity) context).isFinishing()) {
            AlertDialog dialog = new AlertDialog.Builder(context)
                    .setTitle(title)
                    .setMessage(message)
                    .setNegativeButton(R.string.ok, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            dialogInterface.dismiss();
                        }
                    })
                    .create();
            dialog.setCancelable(true);
            dialog.show();
        }
    }

    public static void showAlertDialog(Context context, String message) {
        if (!((Activity) context).isFinishing()) {
            AlertDialog dialog = new AlertDialog.Builder(context)
                    .setMessage(message)
                    .setPositiveButton(R.string.ok, (dialog1, which) -> dialog1.dismiss())
                    .create();
            dialog.setCancelable(true);
            dialog.show();
        }
    }

    public static void showAlertDialog(Context context, int messageRes) {
        if (!((Activity) context).isFinishing()) {
            AlertDialog dialog = new AlertDialog.Builder(context)
                    .setMessage(messageRes)
                    .setPositiveButton(R.string.ok, (dialog1, which) -> dialog1.dismiss())
                    .create();
            dialog.setCancelable(true);
            if (!dialog.isShowing()) {
                dialog.show();
                Window window = dialog.getWindow();
                window.setWindowAnimations(R.style.dialogWindowAnimInToOut);
                window.setBackgroundDrawable(context.getResources()
                        .getDrawable(R.drawable.background_white));
            }
        }
    }

    public static void showAlertDialog(Context context, int messageRes,
                                       DialogInterface.OnClickListener listener) {
        if (!((Activity) context).isFinishing()) {
            AlertDialog dialog = new AlertDialog.Builder(context)
                    .setMessage(messageRes)
                    .setPositiveButton(R.string.ok, listener)
                    .create();
            dialog.setCancelable(false);
            dialog.show();
            Window window = dialog.getWindow();
            window.setWindowAnimations(R.style.dialogWindowAnimInToOut);
            window.setBackgroundDrawable(context.getResources()
                    .getDrawable(R.drawable.background_white));
        }
    }

    public static void showProgressDialog(Context context, int id) {
        ProgressDialog progressDialog = new ProgressDialog(context);
        progressDialog.setMessage(context.getString(id));
        progressDialog.show();
    }
}
<file_sep>package com.txtled.gp_a209.di.module;

import android.app.Activity;
import android.content.Intent;

import com.txtled.gp_a209.di.scope.ActivityScope;

import dagger.Module;
import dagger.Provides;

/**
 * Created by KomoriWu
 *  on 2017/9/15.
 */
@Module
public class ActivityModule {
    private Activity activity;

    public ActivityModule(Activity activity) {
        this.activity = activity;
    }

    @Provides
    @ActivityScope
    Activity provideActivity() {
        return activity;
    }


    @Provides
    Intent provideIntent() {
        return new Intent();
    }
}
<file_sep>package com.txtled.gp_a209.appinfo.mvp;

import com.txtled.gp_a209.base.RxPresenter;
import com.txtled.gp_a209.model.DataManagerModel;

import javax.inject.Inject;

/**
 * Created by Mr.Quan on 2020/3/24.
 */
public class AppInfoPresenter extends RxPresenter<AppInfoConteact.View> implements AppInfoConteact.Presenter {
    private DataManagerModel dataManagerModel;

    @Inject
    public AppInfoPresenter(DataManagerModel dataManagerModel) {
        this.dataManagerModel = dataManagerModel;
    }

    @Override
    public String geEmail() {
        return dataManagerModel.getEmail();
    }
}
<file_sep>package com.txtled.gp_a209.utils;

import android.app.Activity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;

import androidx.annotation.ColorRes;
import androidx.annotation.DrawableRes;
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;

/**
 * Created by Mr.Quan on 2019/12/9.
 */
public class Utils {
    public static final boolean isLog = true;
    static final char[] hexArray = "0123456789ABCDEF".toCharArray();

    public static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }

    public static String asciiToString(String value) {
        StringBuffer sbu = new StringBuffer();
        String[] chars = value.split(",");
        for (int i = 0; i < chars.length; i++) {
            sbu.append((char) Integer.parseInt(chars[i]));
        }
        return sbu.toString();
    }

    public static String formatHex(int data) {
        String s = ((Integer) data).toHexString(data);
        return data < 16 ? "0" + s : s + "";
    }

    public static String getWifiSSID(Activity activity) {
        String ssid="unknown id";

        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O||Build.VERSION.SDK_INT==Build.VERSION_CODES.P) {

            WifiManager mWifiManager = (WifiManager) activity.getApplicationContext().getSystemService(Context.WIFI_SERVICE);

            assert mWifiManager != null;
            WifiInfo info = mWifiManager.getConnectionInfo();

            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
                return info.getSSID();
            } else {
                return info.getSSID().replace("\"", "");
            }
        } else if (Build.VERSION.SDK_INT==Build.VERSION_CODES.O_MR1){

            ConnectivityManager connManager = (ConnectivityManager) activity.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
            assert connManager != null;
            NetworkInfo networkInfo = connManager.getActiveNetworkInfo();
            if (networkInfo.isConnected()) {
                if (networkInfo.getExtraInfo()!=null){
                    return networkInfo.getExtraInfo().replace("\"","");
                }
            }
        }
        return ssid;
    }

    public static String getWifiIp(int i){

        return (i & 0xFF) + "." +
                ((i >> 8) & 0xFF) + "." +
                ((i >> 16) & 0xFF) + "." +
                (i >> 24 & 0xFF);
    }

    public static VectorDrawableCompat changeSVGColor(@DrawableRes int drawable, @ColorRes int color
            , Context context) {
        VectorDrawableCompat vectorDrawableCompat = VectorDrawableCompat.create(
                context.getResources(), drawable, context.getTheme());
        vectorDrawableCompat.setTint(context.getResources().getColor(color));
        return vectorDrawableCompat;

    }

    public static void Logger(String TAG, String type, String value) {
        if (!isLog)
            return;
        Log.i(TAG, type + ":------" + value);
    }

    /**
     * 隐藏软键盘(可用于Activity，Fragment)
     */
    public static void hideSoftKeyboard(Context context, View view) {
        if (view == null) return;

        InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
        inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);

    }
}
<file_sep>package com.txtled.gp_a209.control.mqtt.listener;

public interface OnMessageListener {
    void onSuccess();
    void onFailure();
    void onTimeout();
}
<file_sep>package com.txtled.gp_a209.di.component;

import android.app.Activity;

import com.txtled.gp_a209.di.module.FragmentModule;
import com.txtled.gp_a209.di.scope.FragmentScope;
import com.txtled.gp_a209.light.LightFragment;

import dagger.Component;

/**
 * Created by KomoriWu
 * on 2017-09-01.
 */

@FragmentScope
@Component(dependencies = AppComponent.class, modules = FragmentModule.class)
public interface FragmentComponent {
    Activity getActivity();

    void inject(LightFragment lightFragment);
    //void inject(IntroductionFragment introductionFragment);
}
<file_sep>package com.txtled.gp_a209.model.operate;

import android.app.Activity;

/**
 * Created by Mr.Quan on 2019/3/6.
 */

public interface OperateHelper {
    void requestPermissions(Activity activity, String[] permissions, OnPermissionsListener
            permissionsListener);

    interface OnPermissionsListener {
        void onSuccess(String name);

        void onFailure();

        void onAskAgain();
    }
}
<file_sep>package com.txtled.gp_a209.control.mqtt;

import com.amazonaws.services.iot.client.AWSIotMessage;
import com.amazonaws.services.iot.client.AWSIotQos;
import com.amazonaws.services.iot.client.AWSIotTopic;
import com.txtled.gp_a209.control.mqtt.listener.OnSuccessListener;

public class MyTopic extends AWSIotTopic {
    private OnSuccessListener listener;

    public MyTopic(String topic, AWSIotQos qos) {
        super(topic, qos);
    }

    public void setListener(OnSuccessListener listener) {
        this.listener = listener;
    }

    @Override
    public void onSuccess() {
        listener.onSuccess();
        System.out.println("MyTopiconononSuccess");

        super.onSuccess();
    }

    @Override
    public void onMessage(AWSIotMessage message) {
        System.out.println("TopicMessagePayload"+message.getStringPayload());
        System.out.println("TopicMessageTopic"+message.getTopic());
        listener.onMessage(message);
        super.onMessage(message);
    }

    @Override
    public void onFailure() {
        listener.onFailure();
        System.out.println("MyTopiconFailure");

        super.onFailure();
    }

    @Override
    public void onTimeout() {
        listener.onTimeout();
        System.out.println("MyTopicononTimeout");

        super.onTimeout();
    }
}
<file_sep>package com.txtled.gp_a209.utils;

import android.Manifest;

/**
 * Created by Mr.Quan on 2020/3/11.
 */
public class Constants {
    public static String[] permissions = new String[]{
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION };
    public static final int THIN = 0;
    public static final int BOLD = 1;
    public static final String TOPIC = "topic";
    public static final String MESSAGE = "message";
    public static final int WHAT = 0x11;
    public static final int RESULT = 2000;
    public static final int NAME_RESULT = 2001;
    public static final int WIFI_RESULT = 2002;
    public static final int INFO = 2003;
    public static final int LOGIN = 2004;
    public static final int APP = 2005;
    public static final int OK = 200;
    public static final String PUBLISH = "$aws/things/%s/shadow/update";
    public static final String SUBSCRIBE = "$aws/things/%s/shadow/update/accepted";
    public static final String REJECTED = "$aws/things/%s/shadow/update/rejected";
    public static final String GET_DATA = "$aws/things/%s/shadow/get";
    public static final String DATA_SOUND = "{\"state\":{\"desired\":{\"sound\":%d}}}";
    public static final String DATA_VOLUME = "{\"state\":{\"desired\":{\"volume\":%d}}}";
    public static final String DATA_LIGHT = "{\"state\":{\"desired\":{\"light\":%d}}}";
    public static final String DATA_DEVICE = "{\"state\":{\"desired\":{\"device\":%s}}}";
    public static final String DATA_DURATION = "{\"state\":{\"desired\":{\"duration\":%d}}}";
    public static final String IDENTITY_POOL_ID = "us-east-1:fdd912d6-7ba0-4ce9-8a7f-9d3398b21540";
    public static final String USER_ID = "UserId";
    public static final String DB_NAME = "FOX";
    public static final String THING_DIR = "ThingDir";
    public static final int SOCKET_UDP_PORT = 9001;
    public static final String MY_OIT_CE = "myiotce";
    public static final String ENDPOINT = "endpoint";
    public static final String NAME = "name";
    public static final String VERSION = "version";
    public static final String WIFI = "wifi";
    public static final String TYPE = "type";
    public static final String DISCOVERY = "{\"discovery\":1}";
    public static final String SEND_THING_NAME = "{\"endpoint\":\"%s\",\"thing\":\"%s\"}";
    public static final String SEND_CA_ONE = "{\"ca0\":\"%s\"}";
    public static final String SEND_CA_TWO = "{\"ca1\":\"%s\"}";
    public static final String SEND_CERT_ONE = "{\"cert0\":\"%s\"}";
    public static final String SEND_CERT_TWO = "{\"cert1\":\"%s\"}";
    public static final String SEND_KEY_ONE = "{\"key0\":\"%s\"}";
    public static final String SEND_KEY_TWO = "{\"key1\":\"%s\"}";
    public static final String REBOOT = "{\"reboot\":1}";
    public static final String FRIENDLY_NAME = "{\"friendlyname\":\"%s\"}";
    public static final String REST_API = "a311cdvk7hqtsk-ats.iot.us-east-1.amazonaws.com";
    public static final String POLICY_JSON = "{\n" +
            "  \"Version\": \"2012-10-17\",\n" +
            "  \"Statement\": [\n" +
            "    {\n" +
            "      \"Effect\": \"Allow\",\n" +
            "      \"Action\": \"iot:*\",\n" +
            "      \"Resource\": \"*\"\n" +
            "    }\n" +
            "  ]\n" +
            "}";
    public static final String CA = "-----BEGIN CERTIFICATE-----\n" +
            "MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\n" +
            "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n" +
            "b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\n" +
            "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\n" +
            "b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\n" +
            "ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\n" +
            "9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\n" +
            "IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\n" +
            "VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\n" +
            "93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\n" +
            "jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n" +
            "AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA\n" +
            "A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\n" +
            "U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\n" +
            "N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\n" +
            "o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\n" +
            "<KEY>" +
            "rq<KEY>\n" +
            "-----END CERTIFICATE-----\n";
}
<file_sep>package com.txtled.gp_a209.control.mqtt;

import com.amazonaws.services.iot.client.AWSIotMessage;
import com.amazonaws.services.iot.client.AWSIotQos;
import com.txtled.gp_a209.control.mqtt.listener.OnMessageListener;

public class MyShadowMessage extends AWSIotMessage {
    private OnMessageListener listener;

    public void setListener(OnMessageListener listener){
        this.listener = listener;
    }
    public MyShadowMessage(){
        super(null,null);
    }
    public MyShadowMessage(String topic, AWSIotQos qos) {
        super(topic, qos);
    }

    public MyShadowMessage(String topic, AWSIotQos qos, byte[] payload) {
        super(topic, qos, payload);
    }

    public MyShadowMessage(String topic, AWSIotQos qos, String payload) {
        super(topic, qos, payload);
    }

    @Override
    public void onSuccess() {
        listener.onSuccess();
        super.onSuccess();
    }

    @Override
    public void onFailure() {
        listener.onFailure();
        super.onFailure();
    }

    @Override
    public void onTimeout() {
        listener.onTimeout();
        super.onTimeout();
    }
}
<file_sep>package com.txtled.gp_a209.main.mvp;

import android.app.Activity;
import android.view.View;

import com.txtled.gp_a209.base.BasePresenter;
import com.txtled.gp_a209.base.BaseView;
import com.txtled.gp_a209.bean.DeviceInfo;
import com.txtled.gp_a209.bean.WWADeviceInfo;

import java.util.List;

/**
 * Created by Mr.Quan on 2019/12/9.
 */
public interface MainContract {

    interface View extends BaseView {

        void getDeviceData(List<WWADeviceInfo> data);

        void hidSnackBar();

        void checkLocation();

        void setNoWifiView();

        void closeRefresh();

        void setData(List<WWADeviceInfo> refreshData);

        void noDevice();

        void getWifiName(String ssid);

        void deleteError();

        void deleteSuccess();

        void mqttInitFail();

        void success(boolean allOff);

        void fail();

        void showLoading();

        void showSearching();
    }

    interface Presenter extends BasePresenter<View> {

        String init(Activity activity);

        void onRefresh();

        void deleteDevice(WWADeviceInfo data, String name);

        void onClick(android.view.View v);

        void discovery();

        void onDestroy();
    }
}
