opt
This commit is contained in:
@@ -34,6 +34,8 @@ public class AppsFragment extends MvpFragment< AppsView, AppsPresenter > impleme
|
||||
private View mExit;
|
||||
private IMogoFragmentManager mMogoFragmentManager;
|
||||
|
||||
private View mLoadingView;
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
return R.layout.module_apps_fragment_apps;
|
||||
@@ -62,6 +64,8 @@ public class AppsFragment extends MvpFragment< AppsView, AppsPresenter > impleme
|
||||
// }
|
||||
// } );
|
||||
// mBottomSheetBehavior.setState( BottomSheetBehavior.STATE_COLLAPSED );
|
||||
mLoadingView = findViewById( R.id.module_apps_id_loading );
|
||||
mLoadingView.setVisibility( View.VISIBLE );
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -78,6 +82,7 @@ public class AppsFragment extends MvpFragment< AppsView, AppsPresenter > impleme
|
||||
|
||||
@Override
|
||||
public void renderApps( Map< Integer, List< AppInfo > > appInfos ) {
|
||||
mLoadingView.setVisibility( View.GONE );
|
||||
if ( mAppsPagerAdapter == null ) {
|
||||
mAppsPagerAdapter = new AppsPagerAdapter( appInfos );
|
||||
mAppsPager.setAdapter( mAppsPagerAdapter );
|
||||
@@ -88,5 +93,6 @@ public class AppsFragment extends MvpFragment< AppsView, AppsPresenter > impleme
|
||||
} else {
|
||||
mAppsPagerAdapter.setPagedApps( appInfos );
|
||||
}
|
||||
mLoadingView.setVisibility( View.GONE );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,16 @@
|
||||
package com.mogo.module.apps;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.Observer;
|
||||
|
||||
import com.mogo.commons.mvp.Presenter;
|
||||
import com.mogo.module.apps.model.AppInfo;
|
||||
import com.mogo.module.apps.model.AppsModel;
|
||||
import com.mogo.utils.ThreadPoolService;
|
||||
import com.mogo.utils.TipToast;
|
||||
import com.mogo.utils.UiThreadHandler;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
@@ -32,13 +22,8 @@ public class AppsPresenter extends Presenter< AppsView > {
|
||||
|
||||
private static final String TAG = "AppsPresenter";
|
||||
|
||||
private AppFilter mAppFilter;
|
||||
|
||||
public AppsPresenter( AppsView view ) {
|
||||
super( view );
|
||||
RefreshAppsListLiveData.getInstance().observeForever( s -> {
|
||||
renderAppsList();
|
||||
} );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,45 +34,17 @@ public class AppsPresenter extends Presenter< AppsView > {
|
||||
|
||||
private void renderAppsList() {
|
||||
ThreadPoolService.execute( () -> {
|
||||
final Map< Integer, List< AppInfo > > appInfoList = loadAppsList();
|
||||
UiThreadHandler.post( () -> {
|
||||
if ( mView != null ) {
|
||||
mView.renderApps( appInfoList );
|
||||
}
|
||||
AppsModel.getInstance( getContext() ).load( appInfoList -> {
|
||||
UiThreadHandler.post( () -> {
|
||||
if ( mView != null ) {
|
||||
mView.renderApps( appInfoList );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
} );
|
||||
}
|
||||
|
||||
private Map< Integer, List< AppInfo > > loadAppsList() {
|
||||
Logger.i( TAG, "load apps list." );
|
||||
if ( mAppFilter == null ) {
|
||||
mAppFilter = new AppFilterImpl( getContext() );
|
||||
}
|
||||
|
||||
final Map< Integer, List< AppInfo > > pagedApps = new HashMap<>();
|
||||
final PackageManager packageManager = getContext().getPackageManager();
|
||||
List< PackageInfo > packages = packageManager.getInstalledPackages( 0 );
|
||||
int counter = 0;
|
||||
for ( int i = 0; i < packages.size(); ++i ) {
|
||||
PackageInfo packageInfo = packages.get( i );
|
||||
if ( mAppFilter.filter( packageInfo ) ) {
|
||||
continue;
|
||||
}
|
||||
int page = counter++ / AppsConst.TOTAL_SIZE_EACH_PAGE;
|
||||
if ( !pagedApps.containsKey( page ) ) {
|
||||
pagedApps.put( page, new ArrayList<>() );
|
||||
}
|
||||
String appName = packageInfo.applicationInfo.loadLabel( packageManager ).toString();
|
||||
String packageName = packageInfo.packageName;
|
||||
String versionName = packageInfo.versionName;
|
||||
int versionCode = packageInfo.versionCode;
|
||||
Drawable appIcon = packageInfo.applicationInfo.loadIcon( packageManager );
|
||||
AppInfo appInfo = new AppInfo( appName, packageName, versionName, versionCode, appIcon );
|
||||
pagedApps.get( page ).add( appInfo );
|
||||
}
|
||||
return pagedApps;
|
||||
}
|
||||
|
||||
public void launch( AppInfo appInfo ) {
|
||||
if ( appInfo == null ) {
|
||||
return;
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.mogo.module.apps;
|
||||
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-12-30
|
||||
* <p>
|
||||
* 刷新app列表
|
||||
*/
|
||||
public class RefreshAppsListLiveData extends MutableLiveData< String > {
|
||||
|
||||
private static volatile RefreshAppsListLiveData sInstance;
|
||||
|
||||
private RefreshAppsListLiveData() {
|
||||
}
|
||||
|
||||
public static RefreshAppsListLiveData getInstance() {
|
||||
if ( sInstance == null ) {
|
||||
synchronized ( RefreshAppsListLiveData.class ) {
|
||||
if ( sInstance == null ) {
|
||||
sInstance = new RefreshAppsListLiveData();
|
||||
}
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
public synchronized void release() {
|
||||
sInstance = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.mogo.module.apps.model;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2020-01-09
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public interface AppLoadCallback {
|
||||
|
||||
void onLoaded( Map< Integer, List< AppInfo > > appInfos );
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
package com.mogo.module.apps.model;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.mogo.module.apps.AppFilter;
|
||||
import com.mogo.module.apps.AppFilterImpl;
|
||||
import com.mogo.module.apps.AppsConst;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2020-01-09
|
||||
* <p>
|
||||
* 加载并保存 app 列表
|
||||
*/
|
||||
public class AppsModel {
|
||||
|
||||
private static volatile AppsModel sInstance;
|
||||
private final Context mContext;
|
||||
|
||||
private AppFilter mAppFilter;
|
||||
|
||||
private Map< Integer, List< AppInfo > > mPagedApps = new HashMap<>();
|
||||
|
||||
private AppsModel( Context context ) {
|
||||
mContext = context;
|
||||
mAppFilter = new AppFilterImpl( context );
|
||||
}
|
||||
|
||||
public static AppsModel getInstance( Context context ) {
|
||||
if ( sInstance == null ) {
|
||||
synchronized ( AppsModel.class ) {
|
||||
if ( sInstance == null ) {
|
||||
sInstance = new AppsModel( context );
|
||||
}
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
|
||||
private AtomicBoolean mIsLoaded = new AtomicBoolean( false );
|
||||
|
||||
public synchronized void release() {
|
||||
sInstance = null;
|
||||
}
|
||||
|
||||
public void load( AppLoadCallback callback ) {
|
||||
if ( !mPagedApps.isEmpty() ) {
|
||||
if ( callback != null ) {
|
||||
callback.onLoaded( mPagedApps );
|
||||
}
|
||||
return;
|
||||
}
|
||||
final PackageManager packageManager = mContext.getPackageManager();
|
||||
List< PackageInfo > packages = packageManager.getInstalledPackages( 0 );
|
||||
int counter = 0;
|
||||
for ( int i = 0; i < packages.size(); ++i ) {
|
||||
PackageInfo packageInfo = packages.get( i );
|
||||
if ( mAppFilter.filter( packageInfo ) ) {
|
||||
continue;
|
||||
}
|
||||
int page = counter++ / AppsConst.TOTAL_SIZE_EACH_PAGE;
|
||||
if ( !mPagedApps.containsKey( page ) ) {
|
||||
mPagedApps.put( page, new ArrayList<>() );
|
||||
}
|
||||
String appName = packageInfo.applicationInfo.loadLabel( packageManager ).toString();
|
||||
String packageName = packageInfo.packageName;
|
||||
String versionName = packageInfo.versionName;
|
||||
int versionCode = packageInfo.versionCode;
|
||||
Drawable appIcon = packageInfo.applicationInfo.loadIcon( packageManager );
|
||||
AppInfo appInfo = new AppInfo( appName, packageName, versionName, versionCode, appIcon );
|
||||
mPagedApps.get( page ).add( appInfo );
|
||||
}
|
||||
if ( callback != null ) {
|
||||
callback.onLoaded( mPagedApps );
|
||||
}
|
||||
mIsLoaded.set( true );
|
||||
}
|
||||
|
||||
public void appAdded( String packageName ) {
|
||||
if ( !mIsLoaded.get() ) {
|
||||
return;
|
||||
}
|
||||
if ( TextUtils.isEmpty( packageName ) ) {
|
||||
return;
|
||||
}
|
||||
if ( mPagedApps.isEmpty() ) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final PackageManager packageManager = mContext.getPackageManager();
|
||||
PackageInfo packageInfo = packageManager.getPackageInfo( packageName, 0 );
|
||||
if ( !mAppFilter.filter( packageInfo ) ) {
|
||||
String appName = packageInfo.applicationInfo.loadLabel( packageManager ).toString();
|
||||
String versionName = packageInfo.versionName;
|
||||
int versionCode = packageInfo.versionCode;
|
||||
Drawable appIcon = packageInfo.applicationInfo.loadIcon( packageManager );
|
||||
AppInfo appInfo = new AppInfo( appName, packageName, versionName, versionCode, appIcon );
|
||||
int pageIndex = getPageIndex( packageName, true );
|
||||
if ( !mPagedApps.containsKey( pageIndex ) ) {
|
||||
mPagedApps.put( pageIndex, new ArrayList<>() );
|
||||
}
|
||||
mPagedApps.get( pageIndex ).add( appInfo );
|
||||
}
|
||||
} catch ( PackageManager.NameNotFoundException e ) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private int getPageIndex( String packageName, boolean add ) {
|
||||
int totalPages = mPagedApps.size();
|
||||
if ( add ) {
|
||||
if ( totalPages == 0 ) {
|
||||
return 0;
|
||||
} else {
|
||||
if ( mPagedApps.get( totalPages - 1 ).size() == AppsConst.TOTAL_SIZE_EACH_PAGE ) {
|
||||
return totalPages + 1;
|
||||
} else {
|
||||
return totalPages;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( totalPages == 0 ) {
|
||||
return -1;
|
||||
}
|
||||
int pageIndex = -1;
|
||||
for ( int i = 0; i < totalPages; i++ ) {
|
||||
for ( AppInfo appInfo : mPagedApps.get( i ) ) {
|
||||
if ( TextUtils.equals( appInfo.getPackageName(), packageName ) ) {
|
||||
pageIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pageIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public void appRemoved( String packageName ) {
|
||||
if ( !mIsLoaded.get() ) {
|
||||
return;
|
||||
}
|
||||
if ( TextUtils.isEmpty( packageName ) ) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final PackageManager packageManager = mContext.getPackageManager();
|
||||
PackageInfo packageInfo = packageManager.getPackageInfo( packageName, 0 );
|
||||
if ( !mAppFilter.filter( packageInfo ) ) {
|
||||
int pageIndex = getPageIndex( packageName, false );
|
||||
if ( pageIndex == -1 ) {
|
||||
return;
|
||||
}
|
||||
int totalPages = mPagedApps.size();
|
||||
List< AppInfo > dynamicAppsList = new ArrayList<>();
|
||||
for ( int i = pageIndex; i < totalPages; i++ ) {
|
||||
dynamicAppsList.addAll( mPagedApps.remove( i ) );
|
||||
}
|
||||
int counter = 0;
|
||||
for ( int i = 0; i < dynamicAppsList.size(); i++ ) {
|
||||
AppInfo appInfo = dynamicAppsList.get( i );
|
||||
if ( TextUtils.equals( appInfo.getPackageName(), packageName ) ) {
|
||||
continue;
|
||||
}
|
||||
int page = counter++ / AppsConst.TOTAL_SIZE_EACH_PAGE + pageIndex;
|
||||
if ( !mPagedApps.containsKey( page ) ) {
|
||||
mPagedApps.put( page, new ArrayList<>() );
|
||||
}
|
||||
mPagedApps.get( page ).add( appInfo );
|
||||
}
|
||||
}
|
||||
} catch ( PackageManager.NameNotFoundException e ) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,8 @@ package com.mogo.module.apps.receiver;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
import com.mogo.module.apps.RefreshAppsListLiveData;
|
||||
import com.mogo.module.apps.model.AppsModel;
|
||||
|
||||
public class AppInstallReceiver extends BroadcastReceiver {
|
||||
|
||||
@@ -14,31 +13,23 @@ public class AppInstallReceiver extends BroadcastReceiver {
|
||||
public void onReceive( Context context, Intent intent ) {
|
||||
if ( intent.getAction().equals( Intent.ACTION_PACKAGE_ADDED ) ) {
|
||||
String packageName = intent.getData().getSchemeSpecificPart();
|
||||
notifyRefreshAppsList( packageName );
|
||||
AppsModel.getInstance( context ).appAdded( packageName );
|
||||
}
|
||||
if ( intent.getAction().equals( Intent.ACTION_PACKAGE_REMOVED ) ) {
|
||||
String packageName = intent.getData().getSchemeSpecificPart();
|
||||
notifyRefreshAppsList( packageName );
|
||||
AppsModel.getInstance( context ).appRemoved( packageName );
|
||||
}
|
||||
if ( intent.getAction().equals( Intent.ACTION_PACKAGE_REPLACED ) ) {
|
||||
String packageName = intent.getData().getSchemeSpecificPart();
|
||||
notifyRefreshAppsList( packageName );
|
||||
}
|
||||
if ( intent.getAction().equals( Intent.ACTION_PACKAGE_CHANGED ) ) {
|
||||
String packageName = intent.getData().getSchemeSpecificPart();
|
||||
notifyRefreshAppsList( packageName );
|
||||
}
|
||||
if ( intent.getAction().equals( Intent.ACTION_PACKAGE_RESTARTED ) ) {
|
||||
String packageName = intent.getData().getSchemeSpecificPart();
|
||||
notifyRefreshAppsList( packageName );
|
||||
}
|
||||
if ( intent.getAction().equals( Intent.ACTION_PACKAGE_DATA_CLEARED ) ) {
|
||||
String packageName = intent.getData().getSchemeSpecificPart();
|
||||
notifyRefreshAppsList( packageName );
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyRefreshAppsList( String packageName ) {
|
||||
RefreshAppsListLiveData.getInstance().postValue( packageName );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user