廣告系統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