廣告系統(tǒng)4.0也就是SystemAdvert.apk,主要包括待機(jī)廣告、待機(jī)喚醒廣告(播放的是開(kāi)機(jī)廣告)、無(wú)信號(hào)屏保廣告、無(wú)操作屏保廣告。待機(jī)喚醒廣告功能的實(shí)現(xiàn)不需要系統(tǒng)移植相關(guān)代碼,所以這里只介紹待機(jī)廣告、無(wú)信號(hào)屏保、無(wú)操作屏保的移植。
待機(jī)廣告移植說(shuō)明
目前的平臺(tái)中按照是否有STR可以分為兩種,保留STR的平臺(tái)(例如638、V500平臺(tái)),去掉STR的平臺(tái)(例如648)。保留STR的平臺(tái)中又可以分為638和V500兩種移植形式,所以目前主要存在三種形式的待機(jī)廣告移植形式,只是大同小異罷了。
主要區(qū)別:
待機(jī)廣告Activity的啟動(dòng)參數(shù)不一樣
保留STR
以V500、638為代表,但是V500與638又有一些區(qū)別。
V500由于不支持待機(jī)喚醒直接播放視頻廣告,所以待機(jī)廣告和待機(jī)喚醒廣告的實(shí)現(xiàn)在兩個(gè)Activity中。而638平臺(tái)的待機(jī)廣告和待機(jī)喚醒廣告是在一個(gè)Activity中實(shí)現(xiàn)的,所以兩個(gè)平臺(tái)的移植有一些不同。
V500移植說(shuō)明
- 修改文件
PhoneWindowManager.java - 修改內(nèi)容
修改倒計(jì)時(shí)
static final int STANDBY_LOGO_WAIT_TIME_OUT = 7* 1000;
啟動(dòng)待機(jī)廣告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
//新增方法,判斷當(dāng)前是否為待機(jī)廣告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
//新增方法,判斷當(dāng)前是否為待機(jī)喚醒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
//新增方法,判斷應(yīng)用是否安裝
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移植說(shuō)明
- 修改文件
PhoneWindowManager.java - 修改內(nèi)容
修改倒計(jì)時(shí)
static final int STANDBY_LOGO_WAIT_TIME_OUT = 10 * 1000;
啟動(dòng)待機(jī)廣告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{
//待機(jī)廣告是否結(jié)束標(biāo)記位置位
SystemProperties.set("sys.standbyAdFinished.advert", "false");
//是否是待機(jī)喚醒廣告的標(biāo)記位置位
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);
//是否啟動(dòng)待機(jī)喚醒廣告activity來(lái)播放待機(jī)開(kāi)機(jī)廣告
intentSetup.putExtra("startSTRBootActivity",false);
//是否由廣告系統(tǒng)來(lái)播放開(kāi)機(jī)圖片廣告
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
//判斷當(dāng)前是否是待機(jī)廣告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
//判斷應(yīng)用是否安裝
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
//判斷當(dāng)前是否是播放待機(jī)喚醒廣告
public boolean getPlaySTRBootSystemProperty(){
return SystemProperties.getBoolean("sys.playSTRBoot.advert",false);
}
//add for SystemAdvert end
去掉STR
以648為代表
648平臺(tái)去掉了STR,待機(jī)喚醒走的是開(kāi)機(jī)流程。
648移植說(shuō)明
648移植參照638的移植說(shuō)明,注意只有一處不同,就是在啟動(dòng)待機(jī)廣告Activity處多添加一個(gè)啟動(dòng)參數(shù)。這個(gè)參數(shù)的作用是待機(jī)廣告啟動(dòng)為透明背景,并且不切STORAGE信源。啟動(dòng)的完整代碼如下,注意與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{
//待機(jī)廣告是否結(jié)束標(biāo)記位置位
SystemProperties.set("sys.standbyAdFinished.advert", "false");
//是否是待機(jī)喚醒廣告的標(biāo)記位置位
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);
//是否啟動(dòng)待機(jī)喚醒廣告activity來(lái)播放待機(jī)開(kāi)機(jī)廣告
intentSetup.putExtra("startSTRBootActivity",false);
//是否由廣告系統(tǒng)來(lái)播放開(kāi)機(jī)圖片廣告
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
}
無(wú)信號(hào)屏保移植說(shuō)明
由于無(wú)信號(hào)的廣播是由TvSetting發(fā)送的,所以需要根據(jù)平臺(tái)選擇植入最新的Tvsetting4.apk或者Tvsetting2.apk。
無(wú)操作屏保移植說(shuō)明
- 修改文件
Settings.java - 修改內(nèi)容
/**
* 廣告系統(tǒng)4.0無(wú)操作待機(jī)時(shí)間
* @hide
*/
public static final String NO_OPERATION_TIMEOUT = "no_operation_timeout";
- 修改文件
PowerManagerService.java - 修改內(nèi)容
private static final int MSG_NO_OPERATION_TIMEOUT = 5;
private long mNoOperationTimeout;//廣告系統(tǒng)4.0添加,系統(tǒng)無(wú)操作超時(shí)時(shí)間
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
//新增方法
/**
* 發(fā)送無(wú)操作廣播,用于調(diào)起廣告系統(tǒng)的無(wú)操作屏保
*/
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