com.android.gpstest.GpsSatelliteFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.android.gpstest.GpsSatelliteFragment.java

Source

/*
 * Copyright (C) 2008-2013 The Android Open Source Project,
 * Sean J. Barbeau
 *
 * 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.android.gpstest;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.location.*;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.gpstest.util.GnssType;
import com.android.gpstest.util.GpsTestUtil;

import java.text.SimpleDateFormat;
import java.util.Iterator;

public class GpsSatelliteFragment extends Fragment implements GpsTestListener {

    private final static String TAG = "GpsStatusFragment";

    private static final int PRN_COLUMN = 0;

    private static final int FLAG_IMAGE_COLUMN = 1;

    private static final int SNR_COLUMN = 2;

    private static final int ELEVATION_COLUMN = 5;

    private static final int AZIMUTH_COLUMN = 4;

    private static final int FLAGS_COLUMN = 3;

    private static final int COLUMN_COUNT = 4;

    private Resources mRes;

    private SvGridAdapter mAdapter;

    private int mSvCount, mPrns[], mConstellationType[], mUsedInFixCount;

    private float mSnrCn0s[], mSvElevations[], mSvAzimuths[];

    private String mSnrCn0Title;

    private boolean mHasEphemeris[], mHasAlmanac[], mUsedInFix[];

    private boolean mNavigating, mGotFix;

    private Drawable mFlagUsa, mFlagRussia, mFlagJapan, mFlagChina, mFlagGalileo;

    @Override
    public void onLocationChanged(Location location) {

    }

    public void onStatusChanged(String provider, int status, Bundle extras) {
    }

    public void onProviderEnabled(String provider) {
    }

    public void onProviderDisabled(String provider) {
    }

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

        mRes = getResources();
        View v = inflater.inflate(R.layout.gps_satellite, container, false);

        mFlagUsa = ContextCompat.getDrawable(getActivity(), R.drawable.ic_flag_usa);
        mFlagRussia = ContextCompat.getDrawable(getActivity(), R.drawable.ic_flag_russia);

        mFlagJapan = ContextCompat.getDrawable(getActivity(), R.drawable.ic_flag_japan);
        mFlagChina = ContextCompat.getDrawable(getActivity(), R.drawable.ic_flag_china);
        mFlagGalileo = ContextCompat.getDrawable(getActivity(), R.drawable.ic_flag_galileo);

        GridView gridView = (GridView) v.findViewById(R.id.sv_grid);
        mAdapter = new SvGridAdapter(getActivity());
        gridView.setAdapter(mAdapter);
        gridView.setFocusable(false);
        gridView.setFocusableInTouchMode(false);

        GpsTestActivity.getInstance().addListener(this);

        return v;
    }

    private void setStarted(boolean navigating) {
        if (navigating != mNavigating) {
            if (!navigating) {
                mSvCount = 0;
                mAdapter.notifyDataSetChanged();
            }
            mNavigating = navigating;
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        GpsTestActivity gta = GpsTestActivity.getInstance();
        setStarted(gta.mStarted);
    }

    public void onGpsStarted() {
        setStarted(true);
    }

    public void onGpsStopped() {
        setStarted(false);
    }

    @SuppressLint("NewApi")
    public void gpsStart() {
        //Reset flag for detecting first fix
        mGotFix = false;
    }

    public void gpsStop() {
    }

    @Override
    public void onGnssFirstFix(int ttffMillis) {

    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public void onSatelliteStatusChanged(GnssStatus status) {
        updateGnssStatus(status);
    }

    @Override
    public void onGnssStarted() {
        setStarted(true);
    }

    @Override
    public void onGnssStopped() {
        setStarted(false);
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public void onGnssMeasurementsReceived(GnssMeasurementsEvent event) {
        // No-op
    }

    @Override
    public void onOrientationChanged(double orientation, double tilt) {
    }

    @Override
    public void onNmeaMessage(String message, long timestamp) {
        if (!isAdded()) {
            // Do nothing if the Fragment isn't added
            return;
        }
        if (message.startsWith("$GPGGA") || message.startsWith("$GNGNS")) {
            Double altitudeMsl = GpsTestUtil.getAltitudeMeanSeaLevel(message);
            if (altitudeMsl != null && mNavigating) {

            }
        }
        if (message.startsWith("$GNGSA") || message.startsWith("$GPGSA")) {
            DilutionOfPrecision dop = GpsTestUtil.getDop(message);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    private void updateGnssStatus(GnssStatus status) {
        setStarted(true);

        mSnrCn0Title = mRes.getString(R.string.gps_cn0_column_label);

        if (mPrns == null) {
            /**
             * We need to allocate arrays big enough so we don't overflow them.  Per
             * https://developer.android.com/reference/android/location/GnssStatus.html#getSvid(int)
             * 255 should be enough to contain all known satellites world-wide.
             */
            final int MAX_LENGTH = 255;
            mPrns = new int[MAX_LENGTH];
            mSnrCn0s = new float[MAX_LENGTH];
            mSvElevations = new float[MAX_LENGTH];
            mSvAzimuths = new float[MAX_LENGTH];
            mConstellationType = new int[MAX_LENGTH];
            mHasEphemeris = new boolean[MAX_LENGTH];
            mHasAlmanac = new boolean[MAX_LENGTH];
            mUsedInFix = new boolean[MAX_LENGTH];
        }

        final int length = status.getSatelliteCount();
        mSvCount = 0;
        mUsedInFixCount = 0;
        while (mSvCount < length) {
            int prn = status.getSvid(mSvCount);
            mPrns[mSvCount] = prn;
            mConstellationType[mSvCount] = status.getConstellationType(mSvCount);
            mSnrCn0s[mSvCount] = status.getCn0DbHz(mSvCount);
            mSvElevations[mSvCount] = status.getElevationDegrees(mSvCount);
            mSvAzimuths[mSvCount] = status.getAzimuthDegrees(mSvCount);
            mHasEphemeris[mSvCount] = status.hasEphemerisData(mSvCount);
            mHasAlmanac[mSvCount] = status.hasAlmanacData(mSvCount);
            mUsedInFix[mSvCount] = status.usedInFix(mSvCount);
            if (status.usedInFix(mSvCount)) {
                mUsedInFixCount++;
            }

            mSvCount++;
        }

        mAdapter.notifyDataSetChanged();
    }

    private class SvGridAdapter extends BaseAdapter {

        private Context mContext;

        public SvGridAdapter(Context c) {
            mContext = c;
        }

        public int getCount() {
            // add 1 for header row
            return (mSvCount + 1) * COLUMN_COUNT;
        }

        public Object getItem(int position) {
            Log.d(TAG, "getItem(" + position + ")");
            return "foo";
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            TextView textView = null;
            ImageView imageView = null;

            int row = position / COLUMN_COUNT;
            int column = position % COLUMN_COUNT;

            if (convertView != null) {
                if (convertView instanceof ImageView) {
                    imageView = (ImageView) convertView;
                } else if (convertView instanceof TextView) {
                    textView = (TextView) convertView;
                }
            }

            CharSequence text = null;

            if (row == 0) {
                switch (column) {
                case PRN_COLUMN:
                    text = mRes.getString(R.string.gps_prn_column_label);
                    break;
                case FLAG_IMAGE_COLUMN:
                    text = mRes.getString(R.string.gps_flag_image_label);
                    break;
                case SNR_COLUMN:
                    text = mSnrCn0Title;
                    break;
                case ELEVATION_COLUMN:
                    text = mRes.getString(R.string.gps_elevation_column_label);
                    break;
                case AZIMUTH_COLUMN:
                    text = mRes.getString(R.string.gps_azimuth_column_label);
                    break;
                case FLAGS_COLUMN:
                    text = mRes.getString(R.string.gps_flags_column_label);
                    break;
                }
            } else {
                row--;
                switch (column) {
                case PRN_COLUMN:
                    text = Integer.toString(mPrns[row]);
                    break;
                case FLAG_IMAGE_COLUMN:
                    if (imageView == null) {
                        imageView = new ImageView(mContext);
                        imageView.setScaleType(ImageView.ScaleType.FIT_START);
                    }
                    GnssType type;
                    if (GpsTestUtil.isGnssStatusListenerSupported()) {
                        type = GpsTestUtil.getGnssConstellationType(mConstellationType[row]);
                    } else {

                        type = GnssType.QZSS; // TODO: fixme
                    }
                    switch (type) {
                    case NAVSTAR:
                        imageView.setImageDrawable(mFlagUsa);
                        break;
                    case GLONASS:
                        imageView.setImageDrawable(mFlagRussia);
                        break;
                    case QZSS:
                        imageView.setImageDrawable(mFlagJapan);
                        break;
                    case BEIDOU:
                        imageView.setImageDrawable(mFlagChina);
                        break;
                    case GALILEO:
                        imageView.setImageDrawable(mFlagGalileo);
                        break;
                    }
                    return imageView;
                case SNR_COLUMN:
                    if (mSnrCn0s[row] != 0.0f) {
                        text = Float.toString(mSnrCn0s[row]);
                    } else {
                        text = "";
                    }
                    break;
                case ELEVATION_COLUMN:
                    if (mSvElevations[row] != 0.0f) {
                        text = getString(R.string.gps_elevation_column_value, Float.toString(mSvElevations[row]));
                    } else {
                        text = "";
                    }
                    break;
                case AZIMUTH_COLUMN:
                    if (mSvAzimuths[row] != 0.0f) {
                        text = getString(R.string.gps_azimuth_column_value, Float.toString(mSvAzimuths[row]));
                    } else {
                        text = "";
                    }
                    break;
                case FLAGS_COLUMN:
                    char[] flags = new char[3];
                    flags[0] = !mHasEphemeris[row] ? ' ' : 'E';
                    flags[1] = !mHasAlmanac[row] ? ' ' : 'A';
                    flags[2] = !mUsedInFix[row] ? ' ' : 'U';
                    text = new String(flags);
                    break;
                }
            }

            if (textView == null) {
                textView = new TextView(mContext);
            }

            textView.setText(text);
            return textView;
        }
    }
}