下拉快捷设置面板中都是一些设置的快捷开关,比如wifi,蓝牙,gps等,下面就介绍下添加一个NFC快捷开关的具体流程。
本文基于MTK 6.0
1.config.xml参数配置
- 源码位置 frameworks/base/packages/SystemUI/res/values/config.xml;
<!-- The default tiles to display in QuickSettings -->
<string name="quick_settings_tiles_default" translatable="false">
wifi,bt,inversion,dnd,cell,airplane,nfc<!-- ,rotation,flashlight,cast -->,hotspot
</string>
首先,在quick_settings_tiles_default中添加nfc字符,这个配置项确定了快捷设置面板上显示那些开关以及开关的显示顺序,它是在QSTileHost.java类中loadTileSpecs()方法中被调用,通过mContext.getResources().getString(R.string.quick_settings _tiles_default)获取默认加载的开关
2.创建SecNfcTile.java类
- 源码位置 frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/SecNfcTile.java;
package com.android.systemui.qs.tiles;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.provider.*;
import com.android.systemui.qs.QSTile;
import com.android.systemui.qs.QSTile.BooleanState;
import com.android.systemui.qs.QSTile.Host;
import com.android.systemui.qs.QSTile.ResourceIcon;
import com.android.systemui.R;
import android.nfc.NfcAdapter;
import android.nfc.NfcManager;
import com.android.internal.logging.MetricsLogger;
import android.util.Log;
public class SecNfcTile extends QSTile<QSTile.BooleanState>{
private static final String NFC_STATE_CHANGE = "com.android.NFC_STATE_CHANGE";
private IntentFilter mIntentFilter;
private int nfcState = NfcAdapter.STATE_OFF;
private Context mContext;
public SecNfcTile(Host host){
super(host);
mContext = host.getContext()
mIntentFilter = new IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
mContext.registerReceiver(mReceiver, mIntentFilter);
}
// 点击之后的逻辑处理
protected void handleClick(){
Intent intent = new Intent(NFC_STATE_CHANGE);
if(nfcState == NfcAdapter.STATE_ON) {
intent.putExtra(NfcAdapter.EXTRA_ADAPTER_STATE,NfcAdapter.STATE_OFF);
}else if(nfcState == NfcAdapter.STATE_OFF) {
intent.putExtra(NfcAdapter.EXTRA_ADAPTER_STATE,NfcAdapter.STATE_ON);
}
mContext.sendBroadcast(intent);
// refreshState();
}
// 刷新界面改变开关的状态
protected void handleUpdateState(QSTile.BooleanState paramBooleanState, Object paramObject){
paramBooleanState.visible = true;
paramBooleanState.label = mContext.getString(R.string.quick_settings_nfc_label);
if(nfcState == NfcAdapter.STATE_ON){
paramBooleanState.icon = QSTile.ResourceIcon.get(R.drawable.nfc_off);
}else if (nfcState == NfcAdapter.STATE_OFF) {
paramBooleanState.icon = QSTile.ResourceIcon.get(R.drawable.nfc_on);
}
}
protected QSTile.BooleanState newTileState(){
return new QSTile.BooleanState();
}
@Override
public int getMetricsCategory() {
return MetricsLogger.QS_NFC;
}
public void setListening(boolean paramBoolean){
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (NfcAdapter.ACTION_ADAPTER_STATE_CHANGED.equals(action)) {
nfcState = intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE,NfcAdapter.STATE_ON);
refreshState();
}
}
};
}
3.NFC使能
由于nfc的服务实在systemui之后起来的,在SecNfcTile中取获取NfcAdapter为null,所以发广播在PhoneStatusBar.java中实现nfc使能控制。
- 源码位置 frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+ IntentFilter nfcFilter = new IntentFilter();
+ nfcFilter.addAction("com.android.NFC_STATE_CHANGE");
+ context.registerReceiver(mNfcReceiver, nfcFilter);
+ private NfcAdapter mNfcAdapter;
+ private static final String NFC_STATE_CHANGE = "com.android.NFC_STATE_CHANGE";
+ private BroadcastReceiver mNfcReceiver = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ int nfcState = intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE,NfcAdapter.STATE_ON);
+ if (action.equals("com.android.NFC_STATE_CHANGE")) {
+ if (mNfcAdapter == null) {
+ mNfcAdapter = NfcAdapter.getDefaultAdapter(mContext);
+ }
+ if (mNfcAdapter != null) {
+ if (nfcState == NfcAdapter.STATE_ON) {
+ mNfcAdapter.enable();
+ }else if (nfcState == NfcAdapter.STATE_OFF) {
+ mNfcAdapter.disable();
+ }
+ }
+ Log.d("wxd"," mNfcReceiver :"+mNfcAdapter);
+ }
+ }
+ };
4.实例化SecNfcTile
- 源码位置 frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java;
在createTile()方法中添加nfc
protected QSTile<?> createTile(String tileSpec) {
IQuickSettingsPlugin quickSettingsPlugin = PluginFactory
.getQuickSettingsPlugin(mContext);
if (tileSpec.equals("wifi")) return new WifiTile(this);
else if (tileSpec.equals("bt")) return new BluetoothTile(this);
......
else if (tileSpec.equals("nfc")) return new SecNfcTile(this);
else if (tileSpec.startsWith(IntentTile.PREFIX)) return IntentTile.create(this,tileSpec);
else throw new IllegalArgumentException("Bad tile spec: " + tileSpec);
}
注意:添加的tileSpec需要与config.xml中一致
到这里,快捷开关的添加就ok了。