系列文章解读&说明:
Android Framework 输入子系统 的 分析主要分为以下部分:
(01)核心机制 inotify和epoll
(02)核心机制 双向通信(socketpair+binder)
(03)输入系统框架
(04)InputReader解读
(05)InputDispatcher解读
(06)Global Key 一键启动 应用程序案例
(07)APP建立联系
(08)activity window decor view
(09)InputStage简介
(10)Input系统常见工具(getevent & sendevent & input)
本模块分享的内容:Global Key 一键启动 应用程序案例
本章关键点总结 & 说明:
这里主要关注➕ 案例 部分即可,主要是Global Key 一键启动应用的一个实际案例。
1 实现原理
通过配置framework层的global_keys.xml来实现,Global Key直接实现发送广播的功能,再写一个可以接收此广播的APP即可。于是就实现了一键启动应用的功能。在这里首先注册广播,使用 手动 发广播的方式启动APP,如下所示:
am broadcast -a android.intent.action.GLOBAL_BUTTON -n com.thisway.app_0001_leddemo/.MyBroadcastReceiver
测试APP接收广播后可以启动,这样测试通过后,开始framework层的配置,如下:
修改 /work/android-5.0.2/frameworks/base/core/res/res/xml/global_keys.xml
添加其中一项:
<key keyCode="KEYCODE_TV" component="com.thisway.app_0001_leddemo/.MyBroadcastReceiver" />
接下来开始编译:
mmm frameworks/base/core/res
此时会生成 framework-res.apk,把它拷贝到设备上替换/整体编译即可实现该功能。接下来给出一份参考测试APP。
2 APP测试应用相关代码说明
@1 这里以一个简单启动APP的流程为案例,APP相关代码如下,MainActivity.java的实现如下:
package com.thisway.app_0001_leddemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.view.View;
import android.widget.CheckBox;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private boolean ledon = false;
private Button button = null;
private CheckBox checkBoxLed1 = null;
class MyButtonListener implements View.OnClickListener {
@Override
public void onClick(View v) {
ledon = !ledon;
if (ledon) {
button.setText("ALL OFF");
checkBoxLed1.setChecked(true);
}
else {
button.setText("ALL ON");
checkBoxLed1.setChecked(false);
}
}
}
public void onCheckboxClicked(View view) {
// Is the view now checked?
boolean checked = ((CheckBox) view).isChecked();
// Check which checkbox was clicked
switch(view.getId()) {
case R.id.LED1:
if (checked) {
// Put some meat on the sandwich
Toast.makeText(getApplicationContext(), "LED1 on", Toast.LENGTH_SHORT).show();
}
else {
// Remove the meat
Toast.makeText(getApplicationContext(), "LED1 off", Toast.LENGTH_SHORT).show();
}
break;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.BUTTON);
checkBoxLed1 = (CheckBox) findViewById(R.id.LED1);
button.setOnClickListener(new MyButtonListener());
}
//...
}
@2 MyBroadcastReceiver的代码实现如下:
package com.thisway.app_0001_leddemo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Get BroadcastReceiver", Toast.LENGTH_SHORT).show();
Intent intentNewTask =new Intent(context, MainActivity.class);
intentNewTask.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intentNewTask);
}
}
@3 Layout布局代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
android:orientation="vertical"
>
<TextView android:text="www.100ask.net, 100ask.taobao.com, for LEDDemo"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/BUTTON"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="ALL ON"
/>
<CheckBox
android:id="@+id/LED1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="LED1"
android:onClick="onCheckboxClicked"
/>
</LinearLayout>
@4 整个APP的代码架构如下所示:
├── AndroidManifest.xml
├── java
│ └── com
│ └── thisway
│ └── app_0001_leddemo
│ ├── MainActivity.java
│ └── MyBroadcastReceiver.java
└── res
├── layout
│ └── activity_main.xml
├── menu
│ └── menu_main.xml
├── mipmap-hdpi
│ └── ic_launcher.png
├── mipmap-mdpi
│ └── ic_launcher.png
├── mipmap-xhdpi
│ └── ic_launcher.png
├── mipmap-xxhdpi
│ └── ic_launcher.png
├── values
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
└── values-w820dp
└── dimens.xml
在这里仅仅是一个简单的案例,实际上大家也可以直接使用自己写的APP,关键在于有Broadcastreceiver的注册和启动即可,原理都是类似的。