com.google.android.apps.santatracker.service.LocalApiProcessor.java Source code

Java tutorial

Introduction

Here is the source code for com.google.android.apps.santatracker.service.LocalApiProcessor.java

Source

/*
 * Copyright (C) 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.apps.santatracker.service;

import android.os.Environment;
import android.util.Log;

import com.google.android.apps.santatracker.data.DestinationDbHelper;
import com.google.android.apps.santatracker.data.SantaPreferences;
import com.google.android.apps.santatracker.data.StreamDbHelper;
import com.google.android.apps.santatracker.data.Switches;
import com.google.android.apps.santatracker.util.SantaLog;

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

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * ApiProcessor that loads data from a local file (/sdcard/santa.json).
 *
 * If the <code>now</code> parameter in the file is negative, the current system time is used
 * instead.
 *
 * <b><NOTE: It is best to leave the "refresh" value high (days).
 * If the fingerprint is unchanged and the file contains the same locations the next time it is
 * read in (and data has not been cleared), the application will fail.
 * </b> (The application expects correct behavior, ie. the API will return following locations if
 * the fingerprint is unchanged.
 */
public class LocalApiProcessor extends APIProcessor {

    private static final String FILENAME = "santa.json";
    private static final String TAG = "SantaLocalApiProcessor";
    protected final static String FIELD_CLIENT_SPECIFIC = "clientSpecific";

    private File mFile;
    private JSONObject mClientConfig;

    public LocalApiProcessor(SantaPreferences mPreferences, DestinationDbHelper mDBHelper,
            StreamDbHelper streamDBHelper, APICallback mCallback) {
        super(mPreferences, mDBHelper, streamDBHelper, mCallback);
        mFile = new File(Environment.getExternalStorageDirectory(), FILENAME);

        Log.d(TAG, "Reading from file: " + mFile.getAbsolutePath());
    }

    @Override
    public JSONObject loadApi(String url) {

        SantaLog.d(TAG, "Loading local data.");
        // read the santa json file from the SD card
        String data = null;
        try {
            data = loadLocalFile();
        } catch (IOException e) {
            Log.d(TAG, "Communication Error 101");
            return null;
        }

        if (data == null) {
            Log.d(TAG, "Communication Error 102");
            return null;
        }

        SantaLog.d(TAG, "Local File accessed, old data removed.");

        // Parse data as JSON
        try {
            JSONObject result = parseData(data);
            mClientConfig = result.getJSONObject(FIELD_CLIENT_SPECIFIC);
            return result;
        } catch (JSONException e) {
            e.printStackTrace();
            Log.d(TAG, "Communication Error 103");
        }

        return null;
    }

    @Override
    protected Switches getSwitches() {
        if (mClientConfig == null) {
            throw new IllegalStateException("Can't call getSwitches() before successful loadApi()");
        }

        try {
            Switches config = new Switches();

            config.disableCastButton = mClientConfig.getBoolean(FIELD_DISABLE_CASTBUTTON);
            config.disableDestinationPhoto = mClientConfig.getBoolean(FIELD_DISABLE_PHOTO);

            config.gameState.disableGumballGame = mClientConfig.getBoolean(FIELD_DISABLE_GUMBALLGAME);
            config.gameState.disableJetpackGame = mClientConfig.getBoolean(FIELD_DISABLE_JETPACKGAME);
            config.gameState.disableMemoryGame = mClientConfig.getBoolean(FIELD_DISABLE_MEMORYGAME);
            config.gameState.disableRocketGame = mClientConfig.getBoolean(FIELD_DISABLE_ROCKETGAME);
            config.gameState.disableDancerGame = mClientConfig.getBoolean(FIELD_DISABLE_DANCERGAME);
            config.gameState.disableSnowdownGame = mClientConfig.getBoolean(FIELD_DISABLE_SNOWDOWNGAME);
            config.gameState.disableSwimmingGame = mClientConfig.getBoolean(FIELD_DISABLE_SWIMMINGGAME);
            config.gameState.disableBmxGame = mClientConfig.getBoolean(FIELD_DISABLE_BMXGAME);
            config.gameState.disableRunningGame = mClientConfig.getBoolean(FIELD_DISABLE_RUNNINGGAME);
            config.gameState.disableTennisGame = mClientConfig.getBoolean(FIELD_DISABLE_TENNISGAME);
            config.gameState.disableWaterpoloGame = mClientConfig.getBoolean(FIELD_DISABLE_WATERPOLOGAME);

            config.video1 = mClientConfig.getString(FIELD_VIDEO_1);
            config.video15 = mClientConfig.getString(FIELD_VIDEO_15);
            config.video23 = mClientConfig.getString(FIELD_VIDEO_23);

            return config;
        } catch (JSONException e) {
            Log.d(TAG, "Communication Error 104");
            return null;
        }
    }

    private JSONObject parseData(String data) throws JSONException {
        JSONObject json = new JSONObject(data);

        // Replace the offset with a hardcoded offset

        // Set the current time to now if the now timestamp is negative
        if (json.getLong(FIELD_NOW) < 0L) {
            json.put(FIELD_NOW, System.currentTimeMillis());
        }

        // Reset the fingerprint with each request for testing
        // json.put(FIELD_FINGERPRINT, Long.toString(System.currentTimeMillis()));

        return json;
    }

    private String loadLocalFile() throws IOException {
        if (!mFile.isFile() || !mFile.canRead()) {
            // Could not open file for reading
            return null;
        }

        FileInputStream fis = null;
        try {
            fis = new FileInputStream(mFile);
            return read(fis).toString();
        } finally {
            if (fis != null) {
                fis.close();
            }
        }
    }
}