Android 6.0下为全志A64进行系统定制
关于安卓的定制、移植,网上相关的教程已经很多了,我收集了一些适用于我自己项目的,发到博客上记录一下。
全志官方是提供了 A64 Android_M快速移植指南.pdf,但是对这个项目来说还不够全,所以增加了些内容。
资料的话可以查看:
全志 Allwinner A64 硬件开发资料 参考PCB设计 SDK开发文档 – 吴川斌的博客 (mr-wu.cn)
编译阶段
1.修改WIFI
workspace/a64/android/out/target/product/设备名/system/etc/wifi
workspace/a64/android/external/wpa_supplicant_8/wpa_supplicant
update_config=1
eapol_version=1
ap_scan=1
fast_reauth=1
pmf=1
ctrl_interface=/var/run/wpa_supplicant
update_config=1
network={
ssid="WIFI名字"
psk="密码"
key_mgmt=WPA-PSK
}
2.关闭双击两次电源键打开相机
<!-- Allow the gesture to double tap the power button twice to start the camera while the device
is non-interactive. -->
<bool name="config_cameraDoubleTapPowerGestureEnabled">false</bool>
4.关闭电源键短按事件和长按时弹出交互框
如果不需要短按电源键休眠屏幕和长按电源键弹出关机重启交互框,那也可以将其禁用。
workspace/a64/android/frameworks/base/services/core/java/com/android/server/policy
PhoneWindowManager.java
private void powerPress(long eventTime, boolean interactive, int count) {
if (mScreenOnEarly && !mScreenOnFully) {
Slog.i(TAG, "Suppressed redundant power key press while "
+ "already in the process of turning the screen on.");
return;
}
//恒等于2,短按不休眠屏幕
count = 2;
if (count == 2) {
powerMultiPressAction(eventTime, interactive, mDoublePressOnPowerBehavior);
} else if (count == 3) {
powerMultiPressAction(eventTime, interactive, mTriplePressOnPowerBehavior);
} else if (interactive && !mBeganFromNonInteractive) {
switch (mShortPressOnPowerBehavior) {
case SHORT_PRESS_POWER_NOTHING:
break;
case SHORT_PRESS_POWER_GO_TO_SLEEP:
mPowerManager.goToSleep(eventTime,
PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
break;
case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP:
mPowerManager.goToSleep(eventTime,
PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
break;
case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:
mPowerManager.goToSleep(eventTime,
PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
launchHomeFromHotKey();
break;
case SHORT_PRESS_POWER_GO_HOME:
launchHomeFromHotKey(true /* awakenFromDreams */, false /*respectKeyguard*/);
break;
}
}
}
private void powerLongPress() {
final int behavior = getResolvedLongPressOnPowerBehavior();
switch (behavior) {
case LONG_PRESS_POWER_NOTHING:
break;
case LONG_PRESS_POWER_GLOBAL_ACTIONS:
mPowerKeyHandled = true;
if (!performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false)) {
performAuditoryFeedbackForAccessibilityIfNeed();
}
//弹出选择关机还是重启的对话框
// showGlobalActionsInternal();
break;
case LONG_PRESS_POWER_SHUT_OFF:
case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:
mPowerKeyHandled = true;
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
mWindowManagerFuncs.shutdown(behavior == LONG_PRESS_POWER_SHUT_OFF);
break;
}
}
5.修改欲打包的程序
workspace/a64/android/device/softwinner/设备名
设备名.mk
#PRODUCT_PACKAGES += Launcher3
PRODUCT_PACKAGES += \
# ESFileExplorer \
# VideoPlayer \
Bluetooth \
sendPhotos
# PartnerChromeCustomizationsProvider
去掉不需要的程序。
6.修改产品设备名
PRODUCT_BRAND := Allwinner
PRODUCT_NAME := cyqsda64_v1
PRODUCT_DEVICE := cyqsda64-v1
PRODUCT_MODEL := CyqsdA64 v1
PRODUCT_MANUFACTURER := cyqsd
8.去除原有启动器启动权限
我使用的安卓源码是自带有启动器com.android.launcher3.Launcher的,如果定制开发的程序是启动器类型的,那么旧的启动器就需要去除,当然可以直接删除改启动的源码,我使用的办法比较偷懒,是去除intent。
<activity
android:name="com.android.launcher3.Launcher"
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
android:theme="@style/Theme"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="nosensor"
android:resumeWhilePausing="true"
android:taskAffinity=""
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
</intent-filter>
</activity>
9.开机关闭USB调试
workspace\a64\android\packages\apps\Provision\src\com\android\provision\DefaultActivity.java
/*
* Copyright (C) 2008 The Android Open Source Project
*
* 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.provision;
import android.app.Activity;
import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.provider.Settings;
/**
* Application that sets the provisioned bit, like SetupWizard does.
*/
public class DefaultActivity extends Activity {
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Add a persistent setting to allow other apps to know the device has been provisioned.
Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);
Settings.Secure.putInt(getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 1);
// remove this activity from the package manager.
PackageManager pm = getPackageManager();
ComponentName name = new ComponentName(this, DefaultActivity.class);
pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
// terminate the activity.
finish();
}
}
加入:
if (!android.os.SystemProperties.getBoolean("ro.inet.adb_enabled",true)) {
Settings.Secure.putInt(getContentResolver(), Settings.Secure.ADB_ENABLED, 0);
}
10.WIFI感叹号自动连接
自从Android5.0开始就有了WIFI未联网时会有感叹号,但是因为项目的原因,设备会处于没有互联网的状态,所以感叹号我们得去掉。
目录位于:workspace/a64/android/frameworks/opt/net/wifi/service/java/com/android/server/wifi
WifiAutoJoinController.java
// NOTE: If this condition is updated, update NETWORK_STATUS_UNWANTED_DISABLE_AUTOJOIN.
if (config.numNoInternetAccessReports > 0
&& !isLastSelected
&& !config.validatedInternetAccess) {
// Avoid autoJoining this network because last time we used it, it didn't
// have internet access, and we never manage to validate internet access on this
// network configuration
if (DBG) {
logDbg("attemptAutoJoin skip candidate due to no InternetAccess "
+ config.configKey(true)
+ " num reports " + config.numNoInternetAccessReports);
}
//continue;
workspace/a64/android/frameworks/base/services/core/java/com/android/server/connectivity
NetworkMonitor.java
public NetworkMonitor(Context context, Handler handler, NetworkAgentInfo networkAgentInfo,
NetworkRequest defaultRequest) {
// Add suffix indicating which NetworkMonitor we're talking about.
super(TAG + networkAgentInfo.name());
mContext = context;
mConnectivityServiceHandler = handler;
mNetworkAgentInfo = networkAgentInfo;
mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
mDefaultRequest = defaultRequest;
addState(mDefaultState);
addState(mValidatedState, mDefaultState);
addState(mMaybeNotifyState, mDefaultState);
addState(mEvaluatingState, mMaybeNotifyState);
addState(mCaptivePortalState, mMaybeNotifyState);
addState(mLingeringState, mDefaultState);
setInitialState(mDefaultState);
mServer = Settings.Global.getString(mContext.getContentResolver(),
Settings.Global.CAPTIVE_PORTAL_SERVER);
if (mServer == null) mServer = DEFAULT_SERVER;
mLingerDelayMs = SystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS);
//mIsCaptivePortalCheckEnabled = Settings.Global.getInt(mContext.getContentResolver(),
// Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED, 1) == 1;
mIsCaptivePortalCheckEnabled = false;
start();
}
11.隐藏状态栏
状态栏也需要隐藏掉。
workspace/a64/android/frameworks/base/core/res/res/values
dimens.xml
<integer name="max_action_buttons">2</integer>
<dimen name="toast_y_offset">64dip</dimen>
<!-- Height of the status bar -->
<dimen name="status_bar_height">24dp</dimen>
<!-- Height of the bottom navigation / system bar. -->
<dimen name="navigation_bar_height">48dp</dimen>
修改status_bar_height的值即可。
12.关闭低电量时提醒
workspace/a64/android/frameworks/base/packages/SystemUI/src/com/android/systemui/power
if (!plugged
&& (bucket < oldBucket || oldPlugged)
&& mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
&& bucket < 0) {
// only play SFX when the dialog comes up or the bucket changes
final boolean playSound = bucket != oldBucket || oldPlugged;
mWarnings.showLowBatteryWarning(playSound);
} else if (plugged || (bucket > oldBucket && bucket > 0)) {
mWarnings.dismissLowBatteryWarning();
} else {
mWarnings.updateLowBatteryWarning();
}
禁用掉 mWarnings.showLowBatteryWarning(playSound);
打包修改
下面是打包阶段需要做的修改,因为打包脚本可能因为定制的厂商位置不一样,所以就不写文件路径了,以实际使用为准。
1.去除菜单栏、状态栏
使用qemu.hw.mainkeys来隐藏虚拟按键,这样就可以引导用户使用我们设计的独立按键来完成界面交互。
qemu.hw.mainkeys=1
ro.inet.adb_enabled=false
persist.sys.usb.config=charging
2.修改按钮映射
我的设备是有按键映射到系统的,所以修改一下映射按键的定义。
workspace/a64/android/device/softwinner/设备名/configs
key 115 VOLUME_UP
key 114 VOLUME_DOWN
修改为:
key 115 BACK
3.停用USB
不希望使用USB的话,还需要在配置文件中禁用USB。把usbcX_used改为0即可。
;--------------------------------
;[usbc0]: usbc0 configuration.
;usb_used: usb controller enable. 0-disable, 1-enable.
;usb_port_type: usb mode. 0-device, 1-host, 2-otg.
;usb_detect_type: usb hotplug detect mode. 0-none, 1-vbus/id detect, 2-id/dpdm detect.
;usb_detect_mode: usb otg switch has two config. 0-thread scan, 1-id gpio interrupt.
;usb_id_gpio: usb id detect IO.
;usb_det_vbus_gpio: USB DET_VBUS has two config. (1)gpio pin; (2)"axp_ctrl", use axp intf.
;usb_drv_vbus_gpio: USB DRY_VBUS has two config. (1)gpio pin; (2)"axp_ctrl", use axp intf.
;--------------------------------
;--------------------------------
;--- USB0 CONFIG
;--------------------------------
[usbc0]
usbc0_used = 0
usb_port_type = 2
usb_detect_type = 1
usb_detect_mode = 1
usb_id_gpio = port:PH09<0><1><default><default>
;usb_det_vbus_gpio = "axp_ctrl"
usb_det_vbus_gpio = "gpio"
usb_drv_vbus_gpio = port:power3<1><0><default><0>
usb_host_init_state = 0
usb_regulator_io = "nocare"
usb_wakeup_suspend = 0
;--- USB Device
usb_luns = 3
usb_serial_unique = 1
usb_serial_number = "20080411"
rndis_wceis = 1
;--------------------------------
;--- USB1 CONFIG
;--------------------------------
[usbc1]
usbc1_used = 0
usb_drv_vbus_gpio = port:PB06<1><0><default><0>
usb_host_init_state = 1
usb_regulator_io = "nocare"
usb_wakeup_suspend = 0
;--- HSIC config
usb_hsic_used = 0
usb_hsic_regulator_io = "vcc-hsic-12"
;--- Marvell 4G HSIC
usb_hsic_ctrl = 0
usb_hsic_rdy_gpio =
;--- SMSC usb3503 HSIC HUB
usb_hsic_usb3503_flag = 0
usb_hsic_hub_connect_gpio =
usb_hsic_int_n_gpio =
usb_hsic_reset_n_gpio =
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。