public class Config {

    final int retryCount;
    final int connectTimeout;
    final int readTimeout;
    final int writeTimeout;

    private Config(Builder builder) {
        this.retryCount = builder.retryCount;
        this.connectTimeout = builder.connectTimeout;
        this.readTimeout = builder.connectTimeout;
        this.writeTimeout = builder.writeTimeout;
    }

    public int retryCount() {
        return retryCount;
    }

    public int connectTimeout() {
        return connectTimeout;
    }

    public int readTimeout() {
        return readTimeout;
    }

    public int writeTimeout() {
        return writeTimeout;
    }

    public static Builder newBuilder() {
        return new Builder();
    }

    public static class Builder {

        int retryCount;
        int connectTimeout;
        int readTimeout;
        int writeTimeout;

        private Builder() {

        }

        public Builder retryCount(int retryCount) {
            this.retryCount = retryCount;
            return this;
        }

        public Builder connectTimeout(int connectTimeout, TimeUnit unit) {
            this.connectTimeout = Util.checkDuration("connectTimeout", connectTimeout, unit);
            return this;
        }

        public Builder readTimeout(int readTimeout, TimeUnit unit) {
            this.readTimeout = Util.checkDuration("connectTimeout", readTimeout, unit);
            return this;
        }

        public Builder writeTimeout(int writeTimeout, TimeUnit unit) {
            this.writeTimeout = Util.checkDuration("connectTimeout", writeTimeout, unit);
            return this;
        }

        public Config build() {
            return new Config(this);
        }

    }

} public class HttpExecutor {

    private OkHttpClient mOkHttpClient;

    public HttpExecutor(OkHttpClient okHttpClient) {
        mOkHttpClient = okHttpClient;
    }

    public void get(String url, Callback callback) {
        Request.Builder requestBuilder = new Request.Builder().url(url);
        requestBuilder.get();
        execute(requestBuilder.build(), callback);
    }

    public void post(String url, RequestBody requestBody, Callback callback) {
        Request.Builder requestBuilder = new Request.Builder().url(url);
        requestBuilder.post(requestBody);
        execute(requestBuilder.build(), callback);
    }

    public void put(String url, RequestBody requestBody, Callback callback) {
        Request.Builder requestBuilder = new Request.Builder().url(url);
        requestBuilder.put(requestBody);
        execute(requestBuilder.build(), callback);
    }

    public void delete(String url, Callback callback) {
        Request.Builder requestBuilder = new Request.Builder().url(url);
        requestBuilder.delete();
        execute(requestBuilder.build(), callback);
    }

    public void delete(String url, RequestBody requestBody, Callback callback) {
        Request.Builder requestBuilder = new Request.Builder().url(url);
        requestBuilder.delete(requestBody);
        execute(requestBuilder.build(), callback);
    }

    public void patch(String url, RequestBody requestBody, Callback callback) {
        Request.Builder requestBuilder = new Request.Builder().url(url);
        requestBuilder.patch(requestBody);
        execute(requestBuilder.build(), callback);
    }

    public void head(String url, Callback callback) {
        Request.Builder requestBuilder = new Request.Builder().url(url);
        requestBuilder.head();
        execute(requestBuilder.build(), callback);
    }

    private void execute(Request request, Callback callback) {
        Call call = mOkHttpClient.newCall(request);
        call.enqueue(callback);
    }

} public class RetryInterceptor implements Interceptor {
    public final int MAX_RETRY_COUNT;
    private int mRetried = 0;

    public RetryInterceptor() {
        this.MAX_RETRY_COUNT = 2;
    }

    public RetryInterceptor(int maxRetryCount) {
        this.MAX_RETRY_COUNT = maxRetryCount;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        return process(chain);
    }

    private Response process(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = null;
        try {
            response = chain.proceed(request);
            if (response != null && response.isSuccessful()) {
                return response;
            }
        } catch (IOException e) {
            if (mRetried >= MAX_RETRY_COUNT) {
                throw e;
            }
        }
        if (mRetried < MAX_RETRY_COUNT) {
            mRetried++;
            Log.e("chenglei", "retried " + mRetried + " times");
            response = process(chain);
        }
        return response;
    }
} public class Urls {

    public static String sScheme = "https";

    public static String sHost = "api.heclouds.com";

} public class ApiKey {

    public static String urlForAdding() {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("keys").toString();
    }

    public static String urlForUpdating(String key) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("keys")
                .addPathSegment(key).toString();
    }

    public static String urlForQuerying(String key, int page, int perPage, String deviceId) {
        HttpUrl.Builder builder = new HttpUrl.Builder();
        builder.scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("keys");
        if (key != null) {
            builder.addQueryParameter("key", key);
        }
        if (page > 0) {
            builder.addQueryParameter("page", String.valueOf(page));
        }
        if (perPage > 0) {
            builder.addQueryParameter("per_page", String.valueOf(perPage));
        }
        if (deviceId != null) {
            builder.addQueryParameter("device_id", deviceId);
        }
        return builder.toString();
    }

    public static String urlForDeleting(String key) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("keys")
                .addPathSegment(key).toString();
    }

} public class Binary {

    public static String urlForAdding(String deviceId, String dataStreamId) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("bindata")
                .addQueryParameter("device_id", deviceId)
                .addEncodedQueryParameter("datastream_id", dataStreamId).toString();
    }

    public static String urlForQuerying(String index) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("bindata")
                .addEncodedPathSegment(index).toString();
    }

} public class Command {

    public enum CommandType {
        TYPE_CMD_REQ, TYPE_PUSH_DATA
    }

    public static String urlForSending(String deviceId) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("cmds")
                .addQueryParameter("device_id", deviceId).toString();
    }

    public static String urlForSending(String deviceId, boolean needResponse, int timeout, CommandType type) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("cmds")
                .addQueryParameter("device_id", deviceId).addQueryParameter("qos", needResponse ? "1" : "0")
                .addQueryParameter("timeout", String.valueOf(timeout))
                .addQueryParameter("type", String.valueOf(type.ordinal())).toString();
    }

    public static String urlForQueryingStatus(String cmdUuid) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("cmds")
                .addPathSegment(cmdUuid).toString();
    }

    public static String urlForQueryingResponse(String cmdUuid) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("cmds")
                .addPathSegment(cmdUuid).addPathSegment("resp").toString();
    }

} public class DataPoint {

    public static String urlForAdding(String deviceId, String type) {
        HttpUrl.Builder builder = new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost)
                .addPathSegment("devices").addPathSegment(deviceId).addPathSegment("datapoints");
        if (type != null) {
            builder.addQueryParameter("type", type);
        }
        return builder.toString();
    }

    public static String urlForQuerying(String deviceId, Map<String, String> params) {
        HttpUrl.Builder builder = new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost)
                .addPathSegment("devices").addPathSegment(deviceId).addPathSegment("datapoints");
        if (params != null) {
            Iterator iterator = params.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry) iterator.next();
                String key = (String) entry.getKey();
                String value = (String) entry.getValue();
                builder.addEncodedQueryParameter(key, value);
            }
        }
        return builder.toString();
    }

} public class DataStream {

    public static String urlForAdding(String deviceId) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("devices")
                .addPathSegment(deviceId).addPathSegment("datastreams").toString();
    }

    public static String urlForUpdating(String deviceId, String dataStreamId) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("devices")
                .addPathSegment(deviceId).addPathSegment("datastreams")
                .addEncodedPathSegment(dataStreamId).toString();
    }

    public static String urlForQueryingSingle(String deviceId, String dataStreamId) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("devices")
                .addPathSegment(deviceId).addPathSegment("datastreams")
                .addEncodedPathSegment(dataStreamId).toString();
    }

    public static String urlForQueryingMulti(String deviceId, String[] dataStreamIds) {
        HttpUrl.Builder builder = new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("devices")
                .addPathSegment(deviceId).addPathSegment("datastreams");
        if (dataStreamIds != null && dataStreamIds.length > 0) {
            StringBuilder sb = new StringBuilder(dataStreamIds[0]);
            for (int i = 1; i < dataStreamIds.length; i++) {
                sb.append(",");
                sb.append(dataStreamIds[i]);
            }
            builder.addEncodedQueryParameter("datastream_ids", sb.toString());
        }
        return builder.toString();
    }

    public static String urlForDeleting(String deviceId, String dataStreamId) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("devices")
                .addPathSegment(deviceId).addPathSegment("datastreams")
                .addEncodedPathSegment(dataStreamId).toString();
    }

} public class Device {

    public static String urlForRegistering(String registerCode) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("register_de")
                .addQueryParameter("register_code", registerCode).toString();
    }

    public static String urlForAdding() {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("devices")
                .toString();
    }

    public static String urlForUpdating(String deviceId) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("devices")
                .addPathSegment(deviceId).toString();
    }

    public static String urlForQueryingSingle(String deviceId) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("devices")
                .addPathSegment(deviceId).toString();
    }

    public static String urlForfuzzyQuerying(Map<String, String> params) {
        HttpUrl.Builder builder = new HttpUrl.Builder()
                .scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("devices");
        if (params != null) {
            Iterator iterator = params.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry) iterator.next();
                String key = (String) entry.getKey();
                String value = (String) entry.getValue();
                builder.addEncodedQueryParameter(key, value);
            }
        }
        return builder.toString();
    }

    public static String urlForDeleting(String deviceId) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("devices")
                .addPathSegment(deviceId).toString();
    }

} public class Mqtt {

    public static String urlForSendingCmdByTopic(String topic) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("mqtt")
                .addEncodedQueryParameter("topic", topic).toString();
    }

    public static String urlForQueryingDevicesByTopic(String topic, int page, int perPage) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("mqtt")
                .addPathSegment("topic_device").addEncodedQueryParameter("topic", topic)
                .addQueryParameter("page", String.valueOf(page))
                .addQueryParameter("per_page", String.valueOf(perPage)).toString();
    }

    public static String urlForQueryingDeviceTopics(String deviceId) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("mqtt")
                .addPathSegment("device_topic").addPathSegment(deviceId).toString();
    }

    public static String urlForAddingTopic() {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("mqtt")
                .addPathSegment("topic").toString();
    }

    public static String urlForDeletingTopic(String topic) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("mqtt")
                .addPathSegment("topic").addEncodedQueryParameter("name", topic).toString();
    }

    public static String urlForQueryingTopics() {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("mqtt")
                .addPathSegment("topic").toString();
    }

} public class Trigger {

    public static String urlForAdding() {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("triggers")
                .toString();
    }

    public static String urlForUpdating(String triggerId) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("triggers")
                .addPathSegment(triggerId).toString();
    }

    public static String urlForQueryingSingle(String triggerId) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("triggers")
                .addPathSegment(triggerId).toString();
    }

    public static String urlForfuzzyQuerying(String name, int page, int perPage) {
        HttpUrl.Builder builder = new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("triggers");
        if (name != null && name.length() > 0) {
            builder.addEncodedQueryParameter("title", name);
        }
        if (page > 0) {
            builder.addQueryParameter("page", String.valueOf(page));
        }
        if (perPage > 0) {
            builder.addQueryParameter("per_page", String.valueOf(perPage));
        }
        return builder.toString();
    }

    public static String urlForDeleting(String triggerId) {
        return new HttpUrl.Builder().scheme(Urls.sScheme).host(Urls.sHost).addPathSegment("triggers")
                .addPathSegment(triggerId).toString();
    }

} public class Assertions {

    public static void assertUnreachable(String message) {
        throw new RuntimeException(message);
    }

    public static void assertCondition(boolean condition, String message) {
        if (!condition) {
            throw new RuntimeException(message);
        }
    }

    public static <T> T assertNotNull(T instance) {
        if (instance == null) {
            throw new RuntimeException("Expected object can not be null!");
        }
        return instance;
    }

} public class Meta {

    public static final String META_APIKEY = "com.chinamobile.iot.onenet.APP-KEY";
    public static final String META_SCHEME = "com.chinamobile.iot.onenet.SCHEME";
    public static final String META_HOST = "com.chinamobile.iot.onenet.HOST";

    public static String readAppKey(Application application) throws Exception {
        ApplicationInfo applicationInfo = application.getPackageManager()
                .getApplicationInfo(application.getPackageName(), PackageManager.GET_META_DATA);
        return applicationInfo.metaData.getString(META_APIKEY);
    }

    public static String readScheme(Application application) throws Exception {
        ApplicationInfo applicationInfo = application.getPackageManager()
                .getApplicationInfo(application.getPackageName(), PackageManager.GET_META_DATA);
        return applicationInfo.metaData.getString(META_SCHEME);
    }

    public static String readHost(Application application) throws Exception {
        ApplicationInfo applicationInfo = application.getPackageManager()
                .getApplicationInfo(application.getPackageName(), PackageManager.GET_META_DATA);
        return applicationInfo.metaData.getString(META_HOST);
    }

} public class OneNetLogger implements HttpLoggingInterceptor.Logger {
    @Override
    public void log(String message) {
        Log.i(OneNetApi.LOG_TAG, message);
    }
}
import android.app.Application;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import com.chinamobile.iot.onenet.http.Config;
import com.chinamobile.iot.onenet.http.HttpExecutor;
import com.chinamobile.iot.onenet.http.RetryInterceptor;
import com.chinamobile.iot.onenet.http.Urls;
import com.chinamobile.iot.onenet.module.ApiKey;
import com.chinamobile.iot.onenet.module.Binary;
import com.chinamobile.iot.onenet.module.Command;
import com.chinamobile.iot.onenet.module.DataPoint;
import com.chinamobile.iot.onenet.module.DataStream;
import com.chinamobile.iot.onenet.module.Device;
import com.chinamobile.iot.onenet.module.Mqtt;
import com.chinamobile.iot.onenet.module.Trigger;
import com.chinamobile.iot.onenet.util.Assertions;
import com.chinamobile.iot.onenet.util.Meta;
import com.chinamobile.iot.onenet.util.OneNetLogger;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
     * @param content
     * @param callback
     */
    public static void post(String url, byte[] content, OneNetApiCallback callback) {
        assertInitialized();
        assertSchemeConfigured();
        assertUrlConfigured();
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), content);
        sHttpExecutor.post(url, requestBody, new OneNetApiCallbackAdapter(callback));
    }

    /**
     * HTTP PUT method
     *
     * @param url
     * @param requestBodyString
     * @param callback
     */
    public static void put(String url, String requestBodyString, OneNetApiCallback callback) {
        assertInitialized();
        assertSchemeConfigured();
        assertUrlConfigured();
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), requestBodyString);
        sHttpExecutor.put(url, requestBody, new OneNetApiCallbackAdapter(callback));
    }

    /**
     * HTTP DELETE method
     *
     * @param url
     * @param callback
     */
    public static void delete(String url, OneNetApiCallback callback) {
        assertInitialized();
        assertSchemeConfigured();
        assertUrlConfigured();
        sHttpExecutor.delete(url, new OneNetApiCallbackAdapter(callback));
    }

    /******************** 设备相关api ********************/

    /**
     * 注册设备（该方法用于让设备终端自己在平台创建设备，不适用于APP）
     *
     * @param registerCode      设备注册码
     * @param requestBodyString HTTP内容 详见<a href="http://www.heclouds.com/doc/art262.html#68">
     *                          http://www.heclouds.com/doc/art262.html#68</a>
     * @param callback          回调接口对象
     */
    public static void registerDevice(String registerCode, String requestBodyString, OneNetApiCallback callback) {
        post(Device.urlForRegistering(registerCode), requestBodyString, callback);
    }

    /**
     * 新增设备
     *
     * @param requestBodyString HTTP内容 详见<a href="http://www.heclouds.com/doc/art262.html#68">
     *                          http://www.heclouds.com/doc/art262.html#68</a>
     * @param callback          回调接口对象
     */
    public static void addDevice(String requestBodyString, OneNetApiCallback callback) {
        post(Device.urlForAdding(), requestBodyString, callback);
    }

    /**
     * 更新设备
     *
     * @param deviceId          设备ID
     * @param requestBodyString HTTP内容 详见<a href="http://www.heclouds.com/doc/art262.html#68">
     *                          http://www.heclouds.com/doc/art262.html#68</a>
     * @param callback          回调接口对象
     */
    public static void updateDevice(String deviceId, String requestBodyString, OneNetApiCallback callback) {
        put(Device.urlForUpdating(deviceId), requestBodyString, callback);
    }

    /**
     * 精确查询单个设备
     *
     * @param deviceId 设备ID
     * @param callback 回调接口对象
     */
    public static void querySingleDevice(String deviceId, OneNetApiCallback callback) {
        get(Device.urlForQueryingSingle(deviceId), callback);
    }

    /**
     * 模糊查询设备
     *
     * @param params   URL参数 详见<a href="http://www.heclouds.com/doc/art262.html#68">
     *                 http://www.heclouds.com/doc/art262.html#68</a>
     * @param callback 回调接口对象
     */
    public static void fuzzyQueryDevices(Map<String, String> params, OneNetApiCallback callback) {
        get(Device.urlForfuzzyQuerying(params), callback);
    }

    /**
     * 删除设备
     *
     * @param deviceId 设备ID
     * @param callback 回调接口对象
     */
    public static void deleteDevice(String deviceId, OneNetApiCallback callback) {
        delete(Device.urlForDeleting(deviceId), callback);
    }

    /******************** END ********************/

    /******************** 数据流相关api ********************/

    /**
     * 新增数据流
     *
     * @param deviceId          设备ID
     * @param requestBodyString HTTP内容 详见 <a href="http://www.heclouds.com/doc/art261.html#68">
     *                          http://www.heclouds.com/doc/art261.html#68</a>
     * @param callback          回调接口对象
     */
    public static void addDataStream(String deviceId, String requestBodyString, OneNetApiCallback callback) {
        post(DataStream.urlForAdding(deviceId), requestBodyString, callback);