package com.example.demo;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Toast;
import java.lang.ref.WeakReference;
import java.util.List;
public class SplashActivity extends AppCompatActivity {
private static final String SPLASH_ACTIVITY_DEFAULT = "com.example.demo.SplashDefaultActivity";
private static final String SPLASH_ACTIVITY_UPDATE = "com.example.demo.SplashUpdateIconActivity";
private static final String TAG = SplashActivity.class.getSimpleName();
private ComponentName mDefaultComponentName;
private ComponentName mUpdateComponentName;
private PackageManager mPackageManager;
private static final String SHARD_PREFS_NAME = "resource";
private static final String UPDATE_ICON = "updateIcon";
private SharedPreferences mSharedPrefs;
private int time = 5;
private Handler mHandler = new WeakHandler(this);
private static class WeakHandler extends Handler {
WeakHandler(Activity activity) {
new WeakReference<>(activity);
}
}
private Runnable mCountDownRunnable = new Runnable() {
@Override
public void run() {
if (time <= 0) {
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
startActivity(intent);
finish();
return;
}
time--;
mHandler.postDelayed(mCountDownRunnable, 1000);
}
};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
mHandler.post(mCountDownRunnable);
initActivityAlias();
updateDesktopIcon();
}
private void initActivityAlias() {
mPackageManager = getPackageManager();
mDefaultComponentName = new ComponentName(getBaseContext(), SPLASH_ACTIVITY_DEFAULT);
mUpdateComponentName = new ComponentName(getBaseContext(), SPLASH_ACTIVITY_UPDATE);
}
private void updateDesktopIcon() {
if (isShouldUpdateIcon()) {
Toast.makeText(this, "update icon", Toast.LENGTH_SHORT).show();
shouldUpdateDesktopIcon(false);
enableComponentName(mUpdateComponentName);
disableComponentName(mDefaultComponentName);
} else {
Toast.makeText(this, "default icon", Toast.LENGTH_SHORT).show();
shouldUpdateDesktopIcon(true);
enableComponentName(mDefaultComponentName);
disableComponentName(mUpdateComponentName);
}
}
private void restartApp() {
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.addCategory(Intent.CATEGORY_DEFAULT);
List<ResolveInfo> resolveInfoList = mPackageManager.queryIntentActivities(intent, 0);
for (ResolveInfo resolveInfo : resolveInfoList) {
if (resolveInfo.activityInfo != null) {
Log.v(TAG, "package name = " + resolveInfo.activityInfo.packageName);
activityManager.killBackgroundProcesses(resolveInfo.activityInfo.packageName);
}
}
}
private void enableComponentName(ComponentName componentName) {
mPackageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
private void disableComponentName(ComponentName componentName) {
mPackageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
private void shouldUpdateDesktopIcon(boolean isShouldUpdateIcon) {
mSharedPrefs = getSharedPreferences(SHARD_PREFS_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = mSharedPrefs.edit();
editor.putBoolean(UPDATE_ICON, isShouldUpdateIcon);
editor.apply();
}
private boolean isShouldUpdateIcon() {
mSharedPrefs = getSharedPreferences(SHARD_PREFS_NAME, MODE_PRIVATE);
return mSharedPrefs.getBoolean(UPDATE_ICON, false);
}
@Override
protected void onDestroy() {
mHandler.removeCallbacks(mCountDownRunnable);
super.onDestroy();
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.demo">
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!--
这里为了防止在替换完成时app会自动退出的问题,使用了两个activity-alias作为默认和更新的入口
但某些机型还是会出现替换完成后会自动退出,需要重新进入app的问题
因为使用一个activity-alias作为默认入口Activity,所以把targetActivity的LAUNCHER去除
注意事项:
1、activity-alias的name属性要和new ComponentName()相同,如com.example.SplashDefaultActivity,否则会有ActivityNotFoundException
2、在正式的app开发时,如果第一个版本发布了activity-alias,则在以后的新覆盖版本中,不能再修改activity-alias的name属性,否则会导致app更新版本后没有图标
3、尽量使用隐式意图跳转使用了activity-alias的Activity,显示意图会找不到Activity,因为ComponentName已经改变
-->
<activity
android:name=".SplashActivity"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<!--<category android:name="android.intent.category.LAUNCHER" />-->
</intent-filter>
</activity>
<!-- 默认入口 -->
<activity-alias
android:name=".SplashDefaultActivity"
android:targetActivity=".SplashActivity"
android:label="@string/app_name"
android:enabled="true"
android:icon="@mipmap/ic_launcher">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<!-- 更新入口 -->
<activity-alias
android:name=".SplashUpdateIconActivity"
android:targetActivity=".SplashActivity"
android:label="@string/app_name"
android:enabled="false"
android:icon="@mipmap/ic_launcher_round">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity android:name=".MainActivity"/>
</application>
</manifest>