广告系统4.0也就是SystemAdvert.apk,主要包括待机广告、待机唤醒广告(播放的是开机广告)、无信号屏保广告、无操作屏保广告。待机唤醒广告功能的实现不需要系统移植相关代码,所以这里只介绍待机广告、无信号屏保、无操作屏保的移植。
待机广告移植说明
目前的平台中按照是否有STR可以分为两种,保留STR的平台(例如638、V500平台),去掉STR的平台(例如648)。保留STR的平台中又可以分为638和V500两种移植形式,所以目前主要存在三种形式的待机广告移植形式,只是大同小异罢了。
主要区别:
待机广告Activity的启动参数不一样
保留STR
以V500、638为代表,但是V500与638又有一些区别。
V500由于不支持待机唤醒直接播放视频广告,所以待机广告和待机唤醒广告的实现在两个Activity中。而638平台的待机广告和待机唤醒广告是在一个Activity中实现的,所以两个平台的移植有一些不同。
V500移植说明
- 修改文件
PhoneWindowManager.java - 修改内容
修改倒计时
static final int STANDBY_LOGO_WAIT_TIME_OUT = 7* 1000;
启动待机广告Activity
final Runnable rStandbyDialogConfirmCallback = new Runnable() {
@Override public void run() {
Log.d(TAG, "standbyDialog, in confirm callback -- modify by liupeng");
/*if (null == standbyHintDialog) {
standbyHintDialog = StandbyHintDialog.create(mContext, mHandler);
}*/
//add for SystemAdvert begin
Log.d(TAG, "standby logo shown = " + System.currentTimeMillis());
Log.d(TAG,"Start SystemStandbyActivity");
if(checkApkExist(mContext,"com.konka.systemadvert")){
Log.d(TAG,"com.konka.systemadvert is exist");
try{
Intent intentSetup = new Intent();
intentSetup.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK,Intent.FLAG_ACTIVITY_CLEAR_TASK);
intentSetup.setClassName("com.konka.systemadvert", "com.konka.systemadvert.SystemStandbyActivity");
intentSetup.putExtra("standby",0);
Log.d(TAG,"Start com.konka.systemadvert.SystemStandbyActivity");
mContext.startActivity(intentSetup);
}catch(ActivityNotFoundException e){
Log.d(TAG, "com.konka.systemadvert.SystemStandbyActivity can't find");
}
}
else{
Log.d(TAG,"com.konka.systemadvert is not exist");
}
//end for SystemAdvert end
//屏蔽掉不用的代码
}
屏蔽按键
public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
...
//add for SystemAdvert begin
if(bDiscardAllKeyInSystemAdvert()){
Log.d(TAG, "SystemAdvert don't need this key, discard the key ---- by Hfeng");
return -1;
}
if(bDiscardSomeKeyInSystemAdvert()){
if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP
|| keyCode == KeyEvent.KEYCODE_VOLUME_MUTE){
Log.d(TAG, "SystemAdvert need this key, release the key ---- by Hfeng");
}
else {
Log.d(TAG, "SystemAdvert don't need this key, discard the key ---- by Hfeng");
return -1;
}
}
//add for SystemAdvert end
}
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) {
...
case KeyEvent.KEYCODE_POWER: {
//add by SystemAdvert begin
if(bDiscardSomeKeyInSystemAdvert()){
Log.d(TAG," Discard the key dispatching because SystemSTRBootActivity is running -- by Hfeng");
break;
//add by SystemAdvert end
}
}
//add for SystemAdvert begin
//新增方法,判断当前是否为待机广告Activity
public boolean bDiscardAllKeyInSystemAdvert(){
boolean bSystemAdvert = false;
ActivityManager am = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(2).get(0).topActivity;
String packageName = cn.getPackageName();
String className = cn.getClassName();
Log.d(TAG, "The package of top task is ========= " + packageName);
Log.d(TAG, "The package of classname is ========= " +className);
if(packageName.equals("com.konka.systemadvert") && className.equals("com.konka.systemadvert.SystemStandbyActivity")){
bSystemAdvert = true;
}
if(bSystemAdvert){
return true;
} else {
return false;
}
}
//add for SystemAdvert end
//add for SystemAdvert begin
//新增方法,判断当前是否为待机唤醒Activity
public boolean bDiscardSomeKeyInSystemAdvert(){
boolean bSystemAdvert = false;
ActivityManager am = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(2).get(0).topActivity;
String packageName = cn.getPackageName();
String className = cn.getClassName();
Log.d(TAG, "The package of top task is ========= " + packageName);
Log.d(TAG, "The package of classname is ========= " +className);
if(packageName.equals("com.konka.systemadvert") && className.equals("com.konka.systemadvert.SystemSTRBootActivity")){
bSystemAdvert = true;
}
if(bSystemAdvert){
return true;
} else {
return false;
}
}
//add for SystemAdvert end
//add for SystemAdvert begin
//新增方法,判断应用是否安装
public boolean checkApkExist(Context context, String packageName){
if(packageName == null || "".equals(packageName)){
Log.d(TAG,packageName+" is null");
return false;
}
try{
context.getPackageManager().getPackageInfo(packageName,
PackageManager.GET_UNINSTALLED_PACKAGES);
return true;
} catch(NameNotFoundException e){
Log.d(TAG,packageName+" not find");
return false;
}
}
//add for SystemAdvert end
638移植说明
- 修改文件
PhoneWindowManager.java - 修改内容
修改倒计时
static final int STANDBY_LOGO_WAIT_TIME_OUT = 10 * 1000;
启动待机广告Activity
final Runnable rStandbyDialogConfirmCallback = new Runnable() {
@Override public void run() {
Log.d(TAG, "standbyDialog, in confirm callback -- modify by liupeng");
/*if (null == standbyHintDialog) {
standbyHintDialog = StandbyHintDialog.create(mContext, mHandler);
}*/
Log.d(TAG, "standby logo shown = " + System.currentTimeMillis());
//add for SystemAdvert begin
Log.d(TAG,"Start SystemStandbyActivity");
if(checkApkExist(mContext,"com.konka.systemadvert")){
Log.d(TAG,"com.konka.systemadvert is exist");
try{
//待机广告是否结束标记位置位
SystemProperties.set("sys.standbyAdFinished.advert", "false");
//是否是待机唤醒广告的标记位置位
SystemProperties.set("sys.playSTRBoot.advert", "false");
Intent intentSetup = new Intent();
intentSetup.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intentSetup.setClassName("com.konka.systemadvert", "com.konka.systemadvert.SystemStandbyActivity");
intentSetup.putExtra("standby",0);
//是否启动待机唤醒广告activity来播放待机开机广告
intentSetup.putExtra("startSTRBootActivity",false);
//是否由广告系统来播放开机图片广告
intentSetup.putExtra("playAdBootAnimation",false);
Log.d(TAG,"Start com.konka.systemadvert.SystemStandbyActivity");
mContext.startActivity(intentSetup);
}catch(ActivityNotFoundException e){
Log.d(TAG, "com.konka.systemadvert.SystemStandbyActivity can't find");
}
}
else{
Log.d(TAG,"com.konka.systemadvert is not exist");
}
//屏蔽掉不用的代码
//add for SystemAdvert end
}
屏蔽按键
public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
...
//add for SystemAdvert begin
if(bDiscardSomeKeyInSystemAdvert()){
if(getPlaySTRBootSystemProperty()){
if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP
|| keyCode == KeyEvent.KEYCODE_VOLUME_MUTE){
Log.d(TAG, "SystemAdvert STRBoot need this key, release the key ---- by Hfeng");
}
else {
Log.d(TAG, "SystemAdvert STRBoot don't need this key, discard the key ---- by Hfeng");
return -1;
}
}
else {
Log.d(TAG, "SystemAdvert don't need this key, discard the key ---- by Hfeng");
return -1;
}
}
//add for SystemAdvert end
}
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn){
...
case KeyEvent.KEYCODE_POWER: {
//add for SystemAdvert begin
if(bDiscardSomeKeyInSystemAdvert() && getPlaySTRBootSystemProperty()){
Log.d(TAG," Discard the key dispatching because SystemStandbyBootActivity is running -- by Hfeng");
break;
}
//add for SystemAdvert end
if (down) {
...
}
else{
...
while (!isStandbyLogoFinish) {
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
//add for SystemAdvert begin
if (SystemProperties.getBoolean("sys.standbyAdFinished.advert",false)){
Log.d(TAG, "!!!!!!!!!! STADNBY Advert play finished !!!!!");
break;
}
//add for SystemAdvert end
...
}
}
}
}
//add for SystemAdvert begin
//判断当前是否是待机广告activity
public boolean bDiscardSomeKeyInSystemAdvert(){
boolean bSystemAdvert = false;
ActivityManager am = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(2).get(0).topActivity;
String packageName = cn.getPackageName();
String className = cn.getClassName();
Log.d(TAG, "The package of top task is ========= " + packageName);
Log.d(TAG, "The package of classname is ========= " +className);
if(packageName.equals("com.konka.systemadvert") && className.equals("com.konka.systemadvert.SystemStandbyActivity")){
bSystemAdvert = true;
}
if(bSystemAdvert){
return true;
} else {
return false;
}
}
//add for SystemAdvert end
//add for SystemAdvert begin
//判断应用是否安装
public boolean checkApkExist(Context context, String packageName){
if(packageName == null || "".equals(packageName)){
Log.d(TAG,packageName+" is null");
return false;
}
try{
context.getPackageManager().getPackageInfo(packageName,
PackageManager.GET_UNINSTALLED_PACKAGES);
return true;
} catch(NameNotFoundException e){
Log.d(TAG,packageName+" not find");
return false;
}
}
//add for SystemAdvert end
//add for SystemAdvert begin
//判断当前是否是播放待机唤醒广告
public boolean getPlaySTRBootSystemProperty(){
return SystemProperties.getBoolean("sys.playSTRBoot.advert",false);
}
//add for SystemAdvert end
去掉STR
以648为代表
648平台去掉了STR,待机唤醒走的是开机流程。
648移植说明
648移植参照638的移植说明,注意只有一处不同,就是在启动待机广告Activity处多添加一个启动参数。这个参数的作用是待机广告启动为透明背景,并且不切STORAGE信源。启动的完整代码如下,注意与638的不同处。
final Runnable rStandbyDialogConfirmCallback = new Runnable() {
@Override public void run() {
Log.d(TAG, "standbyDialog, in confirm callback -- modify by liupeng");
/*if (null == standbyHintDialog) {
standbyHintDialog = StandbyHintDialog.create(mContext, mHandler);
}*/
Log.d(TAG, "standby logo shown = " + System.currentTimeMillis());
//add for SystemAdvert begin
Log.d(TAG,"Start SystemStandbyActivity");
if(checkApkExist(mContext,"com.konka.systemadvert")){
Log.d(TAG,"com.konka.systemadvert is exist");
try{
//待机广告是否结束标记位置位
SystemProperties.set("sys.standbyAdFinished.advert", "false");
//是否是待机唤醒广告的标记位置位
SystemProperties.set("sys.playSTRBoot.advert", "false");
Intent intentSetup = new Intent();
intentSetup.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intentSetup.setClassName("com.konka.systemadvert", "com.konka.systemadvert.SystemStandbyActivity");
intentSetup.putExtra("standby",0);
//是否启动待机唤醒广告activity来播放待机开机广告
intentSetup.putExtra("startSTRBootActivity",false);
//是否由广告系统来播放开机图片广告
intentSetup.putExtra("playAdBootAnimation",false);
//add for 648 begin
intentSetup.putExtra("setBlackTheme",false);
//add for 648 end
Log.d(TAG,"Start com.konka.systemadvert.SystemStandbyActivity");
mContext.startActivity(intentSetup);
}catch(ActivityNotFoundException e){
Log.d(TAG, "com.konka.systemadvert.SystemStandbyActivity can't find");
}
}
else{
Log.d(TAG,"com.konka.systemadvert is not exist");
}
//屏蔽掉不用的代码
//add for SystemAdvert end
}
无信号屏保移植说明
由于无信号的广播是由TvSetting发送的,所以需要根据平台选择植入最新的Tvsetting4.apk或者Tvsetting2.apk。
无操作屏保移植说明
- 修改文件
Settings.java - 修改内容
/**
* 广告系统4.0无操作待机时间
* @hide
*/
public static final String NO_OPERATION_TIMEOUT = "no_operation_timeout";
- 修改文件
PowerManagerService.java - 修改内容
private static final int MSG_NO_OPERATION_TIMEOUT = 5;
private long mNoOperationTimeout;//广告系统4.0添加,系统无操作超时时间
public void init(Context context, LightsService ls,ActivityManagerService am, BatteryService bs, IBatteryStats bss,IAppOpsService appOps, DisplayManagerService dm) {
...
//add for SystemAdvert begin
mNoOperationTimeout=Settings.System.getInt(context.getContentResolver(),Settings.System.NO_OPERATION_TIMEOUT, 60000);
//add for SystemAdvert end
}
public void handleMessage(Message msg) {
switch (msg.what) {
//add for SystemAdvert begin
case MSG_NO_OPERATION_TIMEOUT:
handleNoOperationTimeout();
break;
//add for SystemAdvert end
...
}
}
private void updateUserActivitySummaryLocked(long now, int dirty) {
...
//add for SystemAdvert begin
if (SystemProperties.getInt("sys.boot_completed",0) == 1){
long nextNoOperationTimeout = 0;
nextNoOperationTimeout = mLastUserActivityTime + mNoOperationTimeout;
Message msg = mHandler.obtainMessage(MSG_NO_OPERATION_TIMEOUT);
msg.setAsynchronous(true);
mHandler.removeMessages(MSG_NO_OPERATION_TIMEOUT);
mHandler.sendMessageAtTime(msg, nextNoOperationTimeout);
}
//add for SystemAdvert end
}
//add for SystemAdvert begin
//新增方法
/**
* 发送无操作广播,用于调起广告系统的无操作屏保
*/
private void handleNoOperationTimeout() {
Intent noActionIntent = new Intent( "konka.action.NO_OPERATION_TIMEOUT");
noActionIntent.setFlags(Intent.
FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mContext.sendBroadcast(noActionIntent );
}
//add for SystemAdvert end