使Nest Thermostat与Android App配合使用

时间:2016-04-07 23:38:02

标签: android nest nest-api

我正在尝试在github和示例代码上关注Nest SDK。我的片段代码如下 -

/**
 * A placeholder fragment containing a simple view.
 */
public class ThermoActivityFragment extends Fragment implements View.OnClickListener {
    private static final String TAG = ThermoActivity.class.getSimpleName();     // for log

    // Nest API instance holder
    private NestAPI tNest;
    private NestToken tToken;
    private Thermostat tThermo;
    private Structure tStruct;

    // Save the ID's and secret
    private static final String CLIENT_ID = Constants.CLIENT_ID;
    private static final String CLIENT_SECRET = Constants.CLIENT_SECRET;
    private static final String REDIRECT_URL = Constants.REDIRECT_URL;
    private static final int AUTH_TOKEN_REQUEST_CODE = 111;
    private static final int RESULT_OK = -1;

    private static final String THERMOSTAT_KEY = "thermostat_key";
    private static final String STRUCTURE_KEY = "structure_key";
    private static final String DEG_F = "%d°F";

    // Text View
    private TextView tTempIncr;
    private TextView tTempDecr;
    private TextView tSetTemp;

    public ThermoActivityFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_thermo, container, false);

        tTempIncr = (TextView) view.findViewById(R.id.temp_incr);
        tTempDecr = (TextView) view.findViewById(R.id.temp_decr);
        tSetTemp = (TextView) view.findViewById(R.id.temp_value);

        view.findViewById(R.id.temp_incr).setOnClickListener(this);
        view.findViewById(R.id.temp_decr).setOnClickListener(this);

        NestAPI.setAndroidContext(getContext());
        tNest = NestAPI.getInstance();
        tNest.setConfig(CLIENT_ID, CLIENT_SECRET, REDIRECT_URL);

        // Auth flow
        tToken = ThermoSettings.loadAuthToken(getContext());

        if (tToken != null) {
            authenticate(tToken);
        } else {
            tNest.launchAuthFlow(getActivity(), AUTH_TOKEN_REQUEST_CODE);
        }

        if (savedInstanceState != null) {
            tThermo = savedInstanceState.getParcelable(THERMOSTAT_KEY);
            tStruct = savedInstanceState.getParcelable(STRUCTURE_KEY);
            //updateViews();
        }

        return view;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable(THERMOSTAT_KEY, tThermo);
        outState.putParcelable(STRUCTURE_KEY, tStruct);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if (resultCode != RESULT_OK || requestCode != AUTH_TOKEN_REQUEST_CODE) {
            Log.e(TAG, "Finished with no result.");
            return;
        }

        tToken = NestAPI.getAccessTokenFromIntent(intent);
        if (tToken != null) {
            ThermoSettings.saveAuthToken(getContext(), tToken);
            authenticate(tToken);
        } else {
            Log.e(TAG, "Unable to resolve access token from payload.");
        }
    }

    @Override
    public void onStop() {
        Log.d(TAG, "onStop");
        super.onStop();
        tNest.removeAllListeners();
    }

    @Override
    public void onClick(View v) {
        if (tThermo == null || tStruct == null)
            return;

        String tThermoId = tThermo.getDeviceId();
        long temp = tThermo.getTargetTemperatureF();

        switch (v.getId()) {
            case R.id.temp_incr:
                System.out.println("Temp Incr");
                ++temp;
                tSetTemp.setText(String.format(DEG_F, temp));
                tNest.thermostats.setTargetTemperatureF(tThermoId, temp);
                break;
            case R.id.temp_decr:
                --temp;
                tSetTemp.setText(String.format(DEG_F, temp));
                tNest.thermostats.setTargetTemperatureF(tThermoId, temp);
                break;
        }
    }

    /**
     * Authenticate with the Nest API and start listening for updates.
     *
     * @param token the token used to authenticate.
     */
    private void authenticate(NestToken token) {
        //NestAPI nest = NestAPI.getInstance();

        tNest.authWithToken(token, new NestListener.AuthListener() {

            @Override
            public void onAuthSuccess() {
                Log.v(TAG, "Authentication succeeded.");
                fetchData();
            }

            @Override
            public void onAuthFailure(NestException exception) {
                Log.e(TAG, "Authentication failed with error: " + exception.getMessage());
                ThermoSettings.saveAuthToken(getActivity(), null);
                tNest.launchAuthFlow(getActivity(), AUTH_TOKEN_REQUEST_CODE);
            }

            @Override
            public void onAuthRevoked() {
                Log.e(TAG, "Auth token was revoked!");
                ThermoSettings.saveAuthToken(getActivity(), null);
                tNest.launchAuthFlow(getActivity(), AUTH_TOKEN_REQUEST_CODE);
            }
        });
    }

    /**
     * Setup global listener, start listening, and update view when update received.
     */
    private void fetchData() {
        tNest.addGlobalListener(new NestListener.GlobalListener() {
            @Override
            public void onUpdate(@NonNull GlobalUpdate update) {
                tThermo = update.getThermostats().get(0);
                //System.out.println(tThermo);
                tStruct = update.getStructures().get(0);
                //updateViews();
            }
        });
    }
}

我保存令牌的设置文件如下 -

public class ThermoSettings {
    private static final String TOKEN_KEY = "token";
    private static final String EXPIRATION_KEY = "expiration";

    public static void saveAuthToken(Context context, NestToken token) {
        if (token == null) {
            getPrefs(context).edit().remove(TOKEN_KEY).remove(EXPIRATION_KEY).commit();
            return;
        }
        getPrefs(context).edit()
                .putString(TOKEN_KEY, token.getToken())
                .putLong(EXPIRATION_KEY, token.getExpiresIn())
                .commit();
    }

    public static NestToken loadAuthToken(Context context) {
        final SharedPreferences prefs = getPrefs(context);
        final String token = prefs.getString(TOKEN_KEY, null);
        final long expirationDate = prefs.getLong(EXPIRATION_KEY, -1);

        if (token == null || expirationDate == -1) {
            return null;
        }

        return new NestToken(token, expirationDate);
    }

    private static SharedPreferences getPrefs(Context context) {
        return context.getSharedPreferences(NestToken.class.getSimpleName(), 0);
    }

}

我正在尝试做什么 - 我正在使用主页上的按钮进入活动。当我按下按钮时,我看到Nest授权网页,当我点击“接受”时,我看到了我的用户界面,但没有在日志中看到“验证成功”消息。 有人能告诉我我做错了吗?

1 个答案:

答案 0 :(得分:0)

我终于开始工作了。早些时候我试图让它从片段中发挥作用。删除片段并将代码移动到MainActivity后,它开始工作。