Android GNSS开发前置知识——Android基础开发

Posted 叶孤城plus

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android GNSS开发前置知识——Android基础开发相关的知识,希望对你有一定的参考价值。

1 引言

毕业设计做了一些android和Android GNSS的开发工作,做完后老师给换了方向,后面大概率不会再涉及这一块了,因此写个总结,如果将来再碰到,可以做个参考

另外,Android体系太庞大了,细说起来太复杂(实则笔者功力不够),因此写得比较简单,主要写一下常见、基本的用法和笔者印象比较深的几个问题

2 开发环境配置

2.1 Android Studio

笔者没有体验过别的IDE,但Android Studio应该是公认的安卓开发大杀器
Android Studio官网下载
在Android Studio中,依次选择Settings —— Appearance & Behavior —— System Settings —— Android SDK,分别下载SDK Platforms(运行平台)、SDK Tools(开发工具)中你需要的组件

2.2 JDK

Android使用Java语言进行最上层的开发,所以需要安装JDK
JDK官网下载
下载后进行安装、配置环境变量

3 Android基础开发

3.1 Activity活动

打开Android Studio创建一个Empty Activity,IDE会生成一个 MainActivity.java 和 activity_main.xml(在 res/layout 目录下),其中前者是Java代码,后者是xml布局文件

package ...  // 包名

import ...

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    	// 调用父类方法进行初始化
        super.onCreate(savedInstanceState);
        // 为该活动设置布局文件
        setContentView(R.layout.activity_main);
    }
}

MainActivity是我们的app启动时的第一个活动 ,也称为主活动,其初始代码如上,onCreate() 方法是活动生命周期中的一环,系统会根据不同的交互情况自动调用活动生命周期中的一系列函数,我们要做的就是在其中一个或几个函数中自定义行为。在 onCreate() 方法中,为该活动设置了布局文件,另外,初始化操作也应在该方法中完成,类似 C/C++ 中的 main() 函数。

activity_main.xml是该活动的布局文件,它定义了主活动的可视化界面。
IDE默认创建的布局文件使用约束布局,我们可以修改布局方式为线性布局、相对布局、帧布局等,下面的布局文件使用了线性布局,其中有一个TextView控件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">  // context指明上下文,即对应的类

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />  // 宽度和高度适应控件大小,显示文本为"Hello World!"

</LinearLayout>

3.1.1 Intent

Intent的作用:启动下一个活动

  1. 指明当前组件想要执行的动作
  2. 在不同组件之间传递数据

Intent分为显示和隐式,显式即在代码中通过调用 startActivity() 或者 startActivityForResult() 来使用Intent;隐式则是在 AndroidManifest.xml 中配置 <activity> 标签下的 <intent-filter>

笔者主要使用显式Intent,因为方便:只需要使用①当前活动的类实例②目的活动的类创建一个 Intent 对象,再调用相应的方法就能启动下一个活动。
Intent使用实例:

/**
 * 初始化视图
 */
public void initView(){
    button = findViewById(R.id.button);
    //为按钮添加监听器
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {  // onClick()方法会在 button按下时自动调用
            // 显示 Intent
            Intent intent = new Intent(MainActivity.this, SecondActivity.class);
            startActivity(intent);
            // 隐式 Intent
            Intent intent = new Intent("com.example.activitytest1.START_ACTION");
            startActivity(intent);
            // 传递数据
            Intent intent = new Intent(MainActivity.this, SecondActivity.class);
            intent.putExtra("Data", "Hello SecondActivity, this is MainActivity");
            startActivity(intent);
            startActivityForResult(intent, 1);
        }
    });
}

/**
 * 处理 startActivityForResult()的返回结果
 */
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode){
    	// 根据请求码来判断是哪一次请求
        case 1:
        	// 根据结果码判断是否正确返回
            if ( resultCode==RESULT_OK ) {
                String returnData = data.getStringExtra("data_return");
                // 打印日志
                Log.d("MainActivity", returnData);
            }
            break;
    }
}

3.1.2 活动的生命周期

在这里插入图片描述

  1. onCreate():在活动第一次被创建时调用,初始化操作需要在这个函数中完成,包括页面布局、控件响应函数的定义等等
  2. onStart():活动由不可见变为可见时调用
  3. onResume():活动准备好和用户交互时调用
  4. onPause():系统准备去启动或恢复另一个活动时调用,即被其它活动遮挡
  5. onStop():活动完全不可见时调用,即被完全遮挡
  6. onDestroy():活动被销毁之前调用
  7. onRestart():活动由停止状态变为运行状态之前调用

在活动1中启动活动2,然后点击back回到活动1,在点击back的动作中,活动1先onRestart(),活动2再onDestroy()

3.2 XML布局

布局是一种可用于放置很多控件的容器,使用XML(扩展标记语言)来定义其内部的元素及规则,它可以按照一定的规律调整内部控件的位置,布局的内部也可以放置布局,形成嵌套

3.2.1 线性布局

线性布局是笔者最常用的布局方式,用它可以实现大多数布局效果

一. android:orientation 指定了排列方向(horizontal/vertical),默认是horizontal

二. 线性布局允许使用 比例 的方式来指定控件的大小,这点非常重要而且时长会用到:
① 下面的代码中,两个Button的宽度被设为"0dp",而其 android:layout_weight 属性值为1,这表示两个Button将平分该布局的宽度(因为线性布局为默认horizontal)。
② android:layout_weight 属性值可以给任意正整数,系统最后会根据 [ 当前控件的weight分量值 / 当前布局中所有控件的weight值之和 ] 来确定当前控件的宽度/高度(取决于布局为水平还是垂直)

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="8dp"
    android:padding="8dp">
    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Reset"
        android:textAllCaps="false"/>
    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Send"
        android:textAllCaps="false"/>
</LinearLayout>

另外,在布局中,也可以只指定一部分控件的 android:layout_weight 属性值,例如下面的代码,该布局的效果为:首先满足 TextView 的宽度,然后将剩下所有的宽度分配给 Button。

使用这种方式编写的界面,不仅在各种屏幕的适配方面会非常好,而且看起来也更加舒服。

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="8dp"
    android:padding="8dp">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Input..."
        android:textAllCaps="false"/>
    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Send"
        android:textAllCaps="false"/>
</LinearLayout>

3.2.2 相对布局

当有一定数量的控件需要按它们之间的相对位置来摆放时,需要用到相对布局。
常见的指定相对位置的方式有:

  1. android:layout_alignParent[ Top / Bottom / Left / Right ] =“true”
  2. android:layout_center[ Horizontal / InParent / Vertical ] =“true”
  3. android:layout_[ above / below / toLeftOf / toRightOf ] ="@id/${相对的控件id}" 使控件位于相对控件的上/下/左/右位置
  4. android:layout_align[ Top / Bottom / Left / Right ] ="@id/${相对的控件id}" 使控件和相对控件的上/下/左/右边缘对齐

3.2.3 帧布局

帧布局笔者的使用情况仅限于作为碎片Fragment加载的容器/对象

3.2.4 常用属性

下表列出了包括布局、控件在内的各种XML元素的常用属性

属性意义
android:layout_gravity指定控件在布局中的对齐方式
android:gravity指定控件中文字的对齐方式
android:alpha指定控件的透明度,0(全透明)~ 1(全不透)
android:layout_margin[ Top / Bottom / Left / Right ] ="_dp"指定控件和上/下/左/右的外边缘
android:padding[ Top / Bottom / Left / Right ] ="_dp"指定控件上/下/左/右的内边缘(空白)
android:textSize ="_sp"指定字体的大小
android:background指定控件背景,一般为XML定义的形状+颜色
android:text指定控件的文本
android:id指定控件的标识名,不能重复
android:textColor ="#ff0000"指定控件的文本颜色,16进制定义RGB

3.3 常用控件

3.3.1 TextView

TextView 主要用于在界面上显示一段文本信息
几个重要的属性有:

android:text、android:gravity、android:textSize、android:textColor、android:textStyle、android:background

<TextView
    android:id="@+id/tv_title"
    android:text="这是TextView的内容"
    android:padding="10dp"
    android:textSize="18sp"
    android:textColor="#ff0000"
    android:background="#999999"
    android:gravity="center"
    android:textStyle="bold"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

还有很多属性就不一一介绍了,这里有 包索引开发者指南 两篇文档供开发者查阅相关属性,在开发的时候,我们的重点不是记住了一个控件的多少属性,而是为了实现我们的目的,我们要意识到它应该有哪些属性,如果是熟悉的,直接写,如果不熟,再去查阅文档

3.3.2 Button

Button是程序用于和用户交互的一个重要控件
Button的可配置的属性和TextView差不多,不同的是我们可以为Button注册监听器,相应点击事件:
我们先在布局文件中添加一个Button控件,XML代码如下

<Button
    android:id="@+id/btn_submit"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="提交"
    android:textSize="18sp"
    android:padding="10dp"/>

然后在布局文件对应的context中,获取该控件,并为其注册监听器,代码如下

public class RegisterActivity extends AppCompatActivity {
    private Button btnSubmit;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
        initView();
    }

    public void initView() {
        btnSubmit = findViewById(R.id.btn_submit);  // XML中为控件指定的 id        
        btnSubmit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(RegisterActivity.this, "Submit", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

也可以使用实现接口的方式来注册监听器,代码如下所示:

public class RegisterActivity extends AppCompatActivity implements View.OnClickListener {
	private Button btnSubmit;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
        initView();
    }

    public void initView() {
        btnSubmit = findViewById(R.id.btn_submit);  // XML中为控件指定的 id        
        btnSubmit.setOnClickListener(this);
    }
	
	// 实现 View.OnClickListener 接口必须重写该方法
	@Override
	public void onClick(View v){
		switch (v.getId()) {
			case R.id.btn_submit:
				Toast.makeText(RegisterActivity.this, "Submit", Toast.LENGTH_SHORT).show();
				break;
			default:
				break;
		}
	}
}

3.3.3 EditText

EditText是程序用于和用户交互的另一个重要控件,它允许用户在控件里输入和编辑内容,并可以在程序中对这些内容进行处理。

Android控件的用法基本上都很相似:给空间定义一个id,再指定控件的宽度和高度,然后在适当加入一些控件特有的属性就差不多了。

EditText特有的属性有:
android:hint 指定一段提示性的文本,当输入任何内容时,提示文本会消失
android:maxLines 指定EditText的最大行数为两行,当输入的内容超过两行时,文本就会向上滚动,而EditText则不会再继续拉伸

3.3.4 ImageView

ImageView用于在界面上展示图片,使用前要提前准备好图片,图片通常放在以"drawable"开头的目录下,项目初建时有一个空的drawable目录,但它没有指定具体的分辨率,可以在res目录下新建一个drawable-xhpi(xhpi指定对应的分辨率),将图片放入后就可以引用

通过 android:src 属性即可指定要引用的图片

<ImageView
    android:id="@+id/iv_image"
    android:layout_width="wrap_content"
    android:layout_height="311dp"
    android:layout_gravity="top"
    android:background="@android:drawable/picture_frame"
    android:src="@drawable/girl" />

也可以在Java代码中动态指定,代码如下

public class SimpleUIComponentActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_simple_uicomponent);
        ImageView imageView = findViewById(R.id.iv_image);
        imageView.setImageResource(R.drawable.girl);  // 指定 ImageView 显示的图片
    }
}

3.4 日志工具

Android 中的日志工具类是Log(android.util.Log),这个类中提供了如下5个方法来供我们打印日志:

  1. Log.v() 对应级别verbose
  2. Log.d() 对应级别debug
  3. Log.i() 对应级别info
  4. Log.w() 对应级别warn
  5. Log.e() 对应级别error

不同级别的信息区别主要体现在Log的过滤中,笔者一般直接使用Log.e(),因为其它信息较少,可以直接看到我们打印的信息。

下方的代码中,我们在主活动的onCreate()方法中添加了一行Log.e()打印错误信息,该方法传入两个参数:第一个参数是tag,一般传入当前类名,主要用于对打印信息进行过滤。第二个参数是msg,即想要打印的具体内容。

package ...

import ...

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.e("MainActivity:", "onCreate()");  // 通过打印信息显示执行了 onCreate() 方法
    }
}

3.5 Fragment碎片

碎片是一种可以嵌入在活动当中的UI片段,它和活动非常相似,同样都能包含布局,同样都有自己的生命周期。

在Android Studio中新建一个碎片,IDE会给出一个碎片类(Java代码)和一个XML布局文件

3.5.1 动态添加碎片

我们在新建的碎片的布局文件中做一点简单的修改(此处我们仅修改一下背景颜色),然后去主活动(MainActivity)中通过代码动态地加载它,主活动的布局文件如下,其整个布局由上方一个Button,下方一个FrameLayout组成,由于这里仅需要在子布局里放入一个碎片,不需要任何定位,因此非常适合使用FrameLayout。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_load_fragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Load Fragment"
        android:textAllCaps="false" />

    <FrameLayout
        android:id="@+id/frag"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />  // 使碎片铺满余下的高度

</LinearLayout>

主活动的代码如下,在该段代码里,我们于主活动的onCreate()方法中,对btnLoad进行初始化,将其绑定至布局文件中的控件对象,然后为其设置监听器,当点击Button时,将执行replaceFragment()函数,动态地替换帧布局(R.id.frag)的内容。

package ...

import ...

public class MainActivity extends AppCompatActivity {
    private Button btnLoad;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnLoad = findViewById(R.id.btn_load_fragment);
        bt

以上是关于Android GNSS开发前置知识——Android基础开发的主要内容,如果未能解决你的问题,请参考以下文章

Android GNSS开发前置知识——Android基础开发

RK3399平台开发系列讲解(系统篇)1.20 Android 9.0 下中科微 GNSS HAL 的移植过程

Android 获取星历数据和 gnss 测量值

Android GNSS原始观测值的含义及伪距计算

Android Gnss信息获取 & 绘制卫星图

Android Gnss信息获取 & 绘制卫星图