中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

青島做外貿(mào)網(wǎng)站建設(shè)網(wǎng)絡(luò)營(yíng)銷服務(wù)的特點(diǎn)

青島做外貿(mào)網(wǎng)站建設(shè),網(wǎng)絡(luò)營(yíng)銷服務(wù)的特點(diǎn),凱里市網(wǎng)站建設(shè),注冊(cè)網(wǎng)站會(huì)員經(jīng)常聽到大家討論類似的需求,懷疑大廠是不是用了此方案,據(jù)我個(gè)人了解,多數(shù)頭部 app 其實(shí)都是發(fā)版來更新節(jié)假日的 icon。當(dāng)然本方案也是一種可選的方案,以前我也調(diào)研過,存在問題和作者所述差不多,此外原文鏈…

經(jīng)常聽到大家討論類似的需求,懷疑大廠是不是用了此方案,據(jù)我個(gè)人了解,多數(shù)頭部 app 其實(shí)都是發(fā)版來更新節(jié)假日的 icon。當(dāng)然本方案也是一種可選的方案,以前我也調(diào)研過,存在問題和作者所述差不多,此外原文鏈接作者也回復(fù)了很多疑問,可以同時(shí)了解。

效果圖

產(chǎn)品需求

市面上很多App能根據(jù)特定活動(dòng),動(dòng)態(tài)切換應(yīng)用圖標(biāo)達(dá)到宣傳目的,例如淘寶雙十一,國(guó)慶節(jié)等等。那么我們?cè)鯓硬拍茉诓话l(fā)新版本的情況下,動(dòng)態(tài)切換應(yīng)用圖標(biāo)呢?

具體方案

1.圖標(biāo)更換:在AndroidManifest設(shè)置應(yīng)用入口Activity的別名,然后通過setComponentEnabledSetting動(dòng)態(tài)啟用或禁用別名進(jìn)行圖標(biāo)切換。

2.控制圖標(biāo)顯示:冷啟動(dòng)App時(shí),調(diào)用接口判斷是否需要切換icon。

3.觸發(fā)時(shí)機(jī):監(jiān)聽App前后臺(tái)切換,當(dāng)App處于后臺(tái)時(shí)切換圖標(biāo),使得用戶無感知。

代碼實(shí)現(xiàn)

在AndroidManifest.xml中給入口Activity設(shè)置activity-alias

<applicationandroid:name=".MyApplication"android:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:supportsRtl="true"android:theme="@style/Theme.SwitchIcon"><!-- 原MainActivity --><activity android:name=".MainActivity" /><!-- 固定設(shè)置一個(gè)默認(rèn)的別名,用來替代原MainActivity --><activity-aliasandroid:name=".DefaultAliasActivity"android:enabled="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:targetActivity=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity-alias><!-- 別名1,特定活動(dòng)需要的圖標(biāo)如:雙11,國(guó)慶節(jié)等 --><activity-aliasandroid:name=".Alias1Activity"android:enabled="false"android:icon="@mipmap/ic_launcher_show"android:label="@string/app_name"android:targetActivity=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity-alias></application>

activity-alias標(biāo)簽中的屬性如下:

標(biāo)簽

作用

android:name

別名,命名規(guī)則同Actively

android:enabled

是否啟用別名,這里的主要作用的控制顯示應(yīng)用圖標(biāo)

android:icon

應(yīng)用圖標(biāo)

android:label

應(yīng)用名

android:targetActivity

必須指向原入口Activity

在MainActivity中,通過啟用或禁用別名進(jìn)行圖標(biāo)切換

/*** 設(shè)置默認(rèn)的別名為啟動(dòng)入口*/
public void setDefaultAlias() {PackageManager packageManager = getPackageManager();ComponentName name1 = new ComponentName(this, "com.fengfeibiao.switchicon.DefaultAliasActivity");packageManager.setComponentEnabledSetting(name1, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);ComponentName name2 = new ComponentName(this, "com.fengfeibiao.switchicon.Alias1Activity");packageManager.setComponentEnabledSetting(name2, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);}/*** 設(shè)置別名1為啟動(dòng)入口*/
public void setAlias1() {PackageManager packageManager = getPackageManager();ComponentName name1 = new ComponentName(this, "com.fengfeibiao.switchicon.DefaultAliasActivity");packageManager.setComponentEnabledSetting(name1, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);ComponentName name2 = new ComponentName(this, "com.fengfeibiao.switchicon.Alias1Activity");packageManager.setComponentEnabledSetting(name2, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
}

ForegroundCallbacks監(jiān)聽App前后臺(tái)切換

/*** 監(jiān)聽App前后臺(tái)切換*/
public class ForegroundCallbacks implements Application.ActivityLifecycleCallbacks {public static final long CHECK_DELAY = 500;public static final String TAG = ForegroundCallbacks.class.getName();public interface Listener {void onForeground();void onBackground();}private static ForegroundCallbacks instance;private boolean foreground = false, paused = true;private Handler handler = new Handler();private List<Listener> listeners = new CopyOnWriteArrayList<Listener>();private Runnable check;public static ForegroundCallbacks init(Application application) {if (instance == null) {instance = new ForegroundCallbacks();application.registerActivityLifecycleCallbacks(instance);}return instance;}public static ForegroundCallbacks get(Application application) {if (instance == null) {init(application);}return instance;}public static ForegroundCallbacks get(Context ctx) {if (instance == null) {Context appCtx = ctx.getApplicationContext();if (appCtx instanceof Application) {init((Application) appCtx);}throw new IllegalStateException("Foreground is not initialised and " +"cannot obtain the Application object");}return instance;}public static ForegroundCallbacks get() {if (instance == null) {throw new IllegalStateException("Foreground is not initialised - invoke " +"at least once with parameterised init/get");}return instance;}public boolean isForeground() {return foreground;}public boolean isBackground() {return !foreground;}public void addListener(Listener listener) {listeners.add(listener);}public void removeListener(Listener listener) {listeners.remove(listener);}@Overridepublic void onActivityResumed(Activity activity) {paused = false;boolean wasBackground = !foreground;foreground = true;if (check != null)handler.removeCallbacks(check);if (wasBackground) {Log.d(TAG, "went foreground");for (Listener l : listeners) {try {l.onForeground();} catch (Exception exc) {Log.d(TAG, "Listener threw exception!:" + exc.toString());}}} else {Log.d(TAG, "still foreground");}}@Overridepublic void onActivityPaused(Activity activity) {paused = true;if (check != null)handler.removeCallbacks(check);handler.postDelayed(check = new Runnable() {@Overridepublic void run() {if (foreground && paused) {foreground = false;Log.d(TAG, "went background");for (Listener l : listeners) {try {l.onBackground();} catch (Exception exc) {Log.d(TAG, "Listener threw exception!:" + exc.toString());}}} else {Log.d(TAG, "still foreground");}}}, CHECK_DELAY);}@Overridepublic void onActivityCreated(Activity activity, Bundle savedInstanceState) {}@Overridepublic void onActivityStarted(Activity activity) {}@Overridepublic void onActivityStopped(Activity activity) {}@Overridepublic void onActivitySaveInstanceState(Activity activity, Bundle outState) {}@Overridepublic void onActivityDestroyed(Activity activity) {}
}

需要在Application中調(diào)用ForegroundCallbacks.init(this)進(jìn)行初始化。

在MainActivity中實(shí)現(xiàn)ForegroundCallbacks.Listener對(duì)App進(jìn)行監(jiān)聽,當(dāng)處于后臺(tái)判斷是否切換應(yīng)用圖標(biāo)

完整的MainActivity代碼:

public class MainActivity extends AppCompatActivity implements ForegroundCallbacks.Listener {private int position = 0;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//添加app前后臺(tái)監(jiān)聽ForegroundCallbacks.get(this).addListener(this);findViewById(R.id.tv_default).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {position = 0;}});findViewById(R.id.tv_alias1).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {position = 1;}});}@Overrideprotected void onDestroy() {// 移除app前后臺(tái)監(jiān)聽ForegroundCallbacks.get(this).removeListener(this);super.onDestroy();}@Overridepublic void onForeground() {}@Overridepublic void onBackground() {//根據(jù)具體業(yè)務(wù)需求設(shè)置切換條件,我公司采用接口控制icon切換if (position == 0) {setDefaultAlias();} else {setAlias1();}}/*** 設(shè)置默認(rèn)的別名為啟動(dòng)入口*/public void setDefaultAlias() {PackageManager packageManager = getPackageManager();ComponentName name1 = new ComponentName(this, "com.fengfeibiao.switchicon.DefaultAliasActivity");packageManager.setComponentEnabledSetting(name1, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);ComponentName name2 = new ComponentName(this, "com.fengfeibiao.switchicon.Alias1Activity");packageManager.setComponentEnabledSetting(name2, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);}/*** 設(shè)置別名1為啟動(dòng)入口*/public void setAlias1() {PackageManager packageManager = getPackageManager();ComponentName name1 = new ComponentName(this, "com.fengfeibiao.switchicon.DefaultAliasActivity");packageManager.setComponentEnabledSetting(name1, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);ComponentName name2 = new ComponentName(this, "com.fengfeibiao.switchicon.Alias1Activity");packageManager.setComponentEnabledSetting(name2, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);}
}

具體缺陷

具體缺陷如下:

1. 切換icon會(huì)關(guān)閉應(yīng)用進(jìn)程,不是崩潰所以不會(huì)上報(bào)bugly。

2. 切換icon需要時(shí)間,部分華為機(jī)型要10s左右,之后能正常打開。

3. 切換icon過程中,部分機(jī)型點(diǎn)擊圖標(biāo)無法打開應(yīng)用,提示應(yīng)用未安裝。

Demo的github地址

https://github.com/FengFeiBiao/SwitchIcon
http://www.risenshineclean.com/news/34946.html

相關(guān)文章:

  • 微信網(wǎng)站模板免費(fèi)下載seo免費(fèi)入門教程
  • wordpress foxseo 關(guān)鍵詞優(yōu)化
  • 快速免費(fèi)建網(wǎng)站常用的營(yíng)銷策略
  • 邢臺(tái)做網(wǎng)站優(yōu)化百度排名優(yōu)化軟件
  • 淮北做網(wǎng)站的公司百度seo優(yōu)化服務(wù)項(xiàng)目
  • 滎陽網(wǎng)站建設(shè)公司網(wǎng)絡(luò)關(guān)鍵詞優(yōu)化軟件
  • 便宜做網(wǎng)站seo算法優(yōu)化
  • 佛山正規(guī)網(wǎng)站建設(shè)報(bào)價(jià)優(yōu)化大師app下載安裝
  • 口碑好網(wǎng)站建設(shè)公司seo關(guān)鍵詞優(yōu)化平臺(tái)
  • 不同網(wǎng)站對(duì)商家做o2o的政策阿里seo排名優(yōu)化軟件
  • 湖南教育平臺(tái)網(wǎng)站建設(shè)流量寶
  • 梧州專業(yè)網(wǎng)站推廣官方百度平臺(tái)
  • 做外貿(mào)的網(wǎng)站主要有哪些內(nèi)容網(wǎng)站分析培訓(xùn)班
  • 智慧團(tuán)建登錄入口官網(wǎng)排名輕松seo 網(wǎng)站推廣
  • 家政公司網(wǎng)站建設(shè)方案軟文營(yíng)銷ppt
  • 做網(wǎng)站可以用什么軟件目前病毒的最新情況
  • 中國(guó)做美國(guó)網(wǎng)站的翻譯兼職百度推廣投訴電話客服24小時(shí)
  • 幫非法集資公司做網(wǎng)站違法嗎南京網(wǎng)絡(luò)優(yōu)化公司有哪些
  • 國(guó)外網(wǎng)站推廣公司棗莊網(wǎng)絡(luò)推廣seo
  • 新手學(xué)wordpress武漢網(wǎng)站seo德升
  • 注冊(cè)一個(gè)做網(wǎng)站的公司好自媒體怎么入門
  • 網(wǎng)易工作做網(wǎng)站工資獎(jiǎng)金高嗎上海關(guān)鍵詞排名優(yōu)化公司
  • 做阿里巴巴網(wǎng)站口碑seo技術(shù)培訓(xùn)教程
  • 有沒有做羞羞的網(wǎng)站seo排名軟件哪個(gè)好用
  • 動(dòng)易網(wǎng)站模板2022最新時(shí)事新聞及點(diǎn)評(píng)
  • 怎樣進(jìn)入建設(shè)通網(wǎng)站外鏈推廣是什么意思
  • 網(wǎng)站運(yùn)營(yíng)怎樣做網(wǎng)站建設(shè)方案模板
  • 公司制做網(wǎng)站蘭州seo推廣
  • 我要建立自己的網(wǎng)站百度關(guān)鍵詞排名優(yōu)化工具
  • 在百度上怎么建網(wǎng)站模板網(wǎng)站