opt
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
package com.mogo.module.apps;
|
||||
|
||||
import android.content.pm.PackageInfo;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2020-01-08
|
||||
* <p>
|
||||
* app 过滤规则
|
||||
*/
|
||||
public interface AppFilter {
|
||||
|
||||
/**
|
||||
* 过滤包
|
||||
*
|
||||
* @param packageInfo
|
||||
* @return true - 过滤 false - 不过滤
|
||||
*/
|
||||
boolean filter( PackageInfo packageInfo );
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.mogo.module.apps;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2020-01-08
|
||||
* <p>
|
||||
* 过滤 app
|
||||
*/
|
||||
public class AppFilterImpl implements AppFilter {
|
||||
|
||||
private final Context mContext;
|
||||
private List< String > mFilterPackages;
|
||||
|
||||
public AppFilterImpl( Context context ) {
|
||||
mContext = context;
|
||||
final String[] values = context.getResources().getStringArray( R.array.module_apps_array_filter_packages );
|
||||
if ( values != null ) {
|
||||
mFilterPackages = Arrays.asList( values );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean filter( PackageInfo packageInfo ) {
|
||||
// if ( isSystemApp( packageInfo ) ) {
|
||||
// return true;
|
||||
// }
|
||||
if ( isFilterPackages( packageInfo ) ) {
|
||||
return true;
|
||||
}
|
||||
if ( noLaunchIntent( packageInfo ) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isSystemApp( PackageInfo packageInfo ) {
|
||||
return ( packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM ) != 0;
|
||||
}
|
||||
|
||||
private boolean isFilterPackages( PackageInfo packageInfo ) {
|
||||
return mFilterPackages.contains( packageInfo.packageName );
|
||||
}
|
||||
|
||||
private boolean noLaunchIntent( PackageInfo packageInfo ) {
|
||||
return mContext.getPackageManager().getLaunchIntentForPackage( packageInfo.packageName ) == null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,11 +3,11 @@ package com.mogo.module.apps;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.mogo.module.apps.model.AppInfo;
|
||||
|
||||
@@ -19,53 +19,59 @@ import java.util.List;
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public class AppsAdapter extends RecyclerView.Adapter< AppsAdapter.AppsViewHolder > {
|
||||
public class AppsAdapter extends BaseAdapter {
|
||||
|
||||
private List< AppInfo > mAppInfos;
|
||||
|
||||
public AppsAdapter( List< AppInfo > appInfos ) {
|
||||
this.mAppInfos = appInfos;
|
||||
}
|
||||
private View.OnClickListener onClickListener;
|
||||
|
||||
public void refreshAppInfos( List< AppInfo > mAppInfos ) {
|
||||
this.mAppInfos = mAppInfos;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public AppsViewHolder onCreateViewHolder( @NonNull ViewGroup parent, int viewType ) {
|
||||
return new AppsViewHolder( LayoutInflater.from( parent.getContext() ).inflate( R.layout.module_apps_item_app, null ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder( @NonNull AppsViewHolder holder, int position ) {
|
||||
final AppInfo appInfo = mAppInfos.get( position );
|
||||
holder.mIcon.setImageDrawable( appInfo.getIcon() );
|
||||
holder.mName.setText( appInfo.getName() );
|
||||
holder.itemView.setTag(appInfo);
|
||||
holder.itemView.setOnClickListener(onClickListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
public int getCount() {
|
||||
return mAppInfos == null ? 0 : mAppInfos.size();
|
||||
}
|
||||
|
||||
public static class AppsViewHolder extends RecyclerView.ViewHolder {
|
||||
@Override
|
||||
public AppInfo getItem( int position ) {
|
||||
return mAppInfos.get( position );
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId( int position ) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView( int position, View convertView, ViewGroup parent ) {
|
||||
AppViewHolder holder = null;
|
||||
if ( convertView == null ) {
|
||||
holder = new AppViewHolder( LayoutInflater.from( parent.getContext() ).inflate( R.layout.module_apps_item_app, null ) );
|
||||
} else {
|
||||
holder = ( ( AppViewHolder ) convertView.getTag() );
|
||||
}
|
||||
AppInfo appInfo = getItem( position );
|
||||
holder.mIcon.setImageDrawable( appInfo.getIcon() );
|
||||
holder.mName.setText( appInfo.getName() );
|
||||
return holder.mItemView;
|
||||
}
|
||||
|
||||
public static class AppViewHolder {
|
||||
|
||||
private View mItemView;
|
||||
public ImageView mIcon;
|
||||
public TextView mName;
|
||||
|
||||
public AppsViewHolder( @NonNull View itemView ) {
|
||||
super( itemView );
|
||||
public AppViewHolder( @NonNull View itemView ) {
|
||||
mItemView = itemView;
|
||||
mIcon = itemView.findViewById( R.id.module_apps_id_app_icon );
|
||||
mName = itemView.findViewById( R.id.module_apps_id_app_name );
|
||||
mItemView.setTag( this );
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnClickListener(View.OnClickListener onClickListener) {
|
||||
this.onClickListener = onClickListener;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.mogo.module.apps;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2020-01-08
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public class AppsConst {
|
||||
|
||||
public static final int TOTAL_SIZE_EACH_PAGE = 12;
|
||||
}
|
||||
@@ -1,16 +1,21 @@
|
||||
package com.mogo.module.apps;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.alibaba.android.arouter.launcher.ARouter;
|
||||
import com.mogo.commons.mvp.MvpFragment;
|
||||
import com.mogo.module.apps.model.AppInfo;
|
||||
import com.mogo.service.MogoServicePaths;
|
||||
import com.mogo.service.fragmentmanager.IMogoFragmentManager;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
@@ -23,8 +28,11 @@ public class AppsFragment extends MvpFragment< AppsView, AppsPresenter > impleme
|
||||
public static final String TAG = "AppsFragment";
|
||||
|
||||
// private BottomSheetBehavior mBottomSheetBehavior;
|
||||
private RecyclerView mAppsList;
|
||||
private AppsAdapter mAppsAdapter;
|
||||
private ViewPager mAppsPager;
|
||||
private AppsPagerAdapter mAppsPagerAdapter;
|
||||
|
||||
private View mExit;
|
||||
private IMogoFragmentManager mMogoFragmentManager;
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
@@ -33,8 +41,13 @@ public class AppsFragment extends MvpFragment< AppsView, AppsPresenter > impleme
|
||||
|
||||
@Override
|
||||
protected void initViews() {
|
||||
mAppsList = findViewById( R.id.module_apps_id_apps );
|
||||
mAppsList.setLayoutManager( new GridLayoutManager( getContext(), 8 ) );
|
||||
mAppsPager = findViewById( R.id.module_apps_id_apps_pager );
|
||||
mExit = findViewById( R.id.module_apps_id_apps_exit );
|
||||
mExit.setOnClickListener( view -> {
|
||||
mMogoFragmentManager.pop();
|
||||
} );
|
||||
// mAppsList = findViewById( R.id.module_apps_id_apps );
|
||||
// mAppsList.setLayoutManager( new GridLayoutManager( getContext(), 8 ) );
|
||||
// mBottomSheetBehavior = BottomSheetBehavior.from( mAppsList );
|
||||
// mBottomSheetBehavior.setSkipCollapsed( true );
|
||||
// mBottomSheetBehavior.setBottomSheetCallback( new BottomSheetBehavior.BottomSheetCallback() {
|
||||
@@ -60,23 +73,20 @@ public class AppsFragment extends MvpFragment< AppsView, AppsPresenter > impleme
|
||||
@Override
|
||||
public void onActivityCreated( @Nullable Bundle savedInstanceState ) {
|
||||
super.onActivityCreated( savedInstanceState );
|
||||
mMogoFragmentManager = ( IMogoFragmentManager ) ARouter.getInstance().build( MogoServicePaths.PATH_FRAGMENT_MANAGER ).navigation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderApps( List< AppInfo > appInfos ) {
|
||||
if ( mAppsAdapter == null ) {
|
||||
mAppsAdapter = new AppsAdapter( appInfos );
|
||||
mAppsList.setAdapter( mAppsAdapter );
|
||||
bindListener();
|
||||
public void renderApps( Map< Integer, List< AppInfo > > appInfos ) {
|
||||
if ( mAppsPagerAdapter == null ) {
|
||||
mAppsPagerAdapter = new AppsPagerAdapter( appInfos );
|
||||
mAppsPager.setAdapter( mAppsPagerAdapter );
|
||||
mAppsPagerAdapter.setOnAppClickedListener( ( appInfo, position ) -> {
|
||||
Logger.i( TAG, "position = %d clicked. name = %s", position, appInfo.getName() );
|
||||
mPresenter.launch( appInfo );
|
||||
} );
|
||||
} else {
|
||||
mAppsAdapter.refreshAppInfos( appInfos );
|
||||
mAppsPagerAdapter.setPagedApps( appInfos );
|
||||
}
|
||||
}
|
||||
|
||||
private void bindListener() {
|
||||
mAppsAdapter.setOnClickListener( view -> {
|
||||
AppInfo app = ( AppInfo ) view.getTag();
|
||||
mPresenter.launch( app );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.mogo.module.apps;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.GridView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.viewpager.widget.PagerAdapter;
|
||||
|
||||
import com.mogo.module.apps.model.AppInfo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2020-01-08
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public class AppsPagerAdapter extends PagerAdapter {
|
||||
|
||||
private Map< Integer, List< AppInfo > > mPagedApps;
|
||||
private OnAppClickedListener mOnAppClickedListener;
|
||||
|
||||
public AppsPagerAdapter( Map< Integer, List< AppInfo > > apps ) {
|
||||
this.mPagedApps = apps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mPagedApps == null ? 0 : mPagedApps.size();
|
||||
}
|
||||
|
||||
public void setOnAppClickedListener( OnAppClickedListener onAppClickedListener ) {
|
||||
this.mOnAppClickedListener = onAppClickedListener;
|
||||
}
|
||||
|
||||
public OnAppClickedListener getOnAppClickedListener() {
|
||||
return mOnAppClickedListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isViewFromObject( @NonNull View view, @NonNull Object object ) {
|
||||
return view == object;
|
||||
}
|
||||
|
||||
public void setPagedApps( Map< Integer, List< AppInfo > > pagedApps ) {
|
||||
this.mPagedApps = pagedApps;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Object instantiateItem( @NonNull ViewGroup container, int position ) {
|
||||
View pager = LayoutInflater.from( container.getContext() ).inflate( R.layout.module_apps_item_app_pager, null );
|
||||
GridView page = pager.findViewById( R.id.module_apps_id_apps_page );
|
||||
page.setAdapter( new AppsAdapter( mPagedApps.get( position ) ) );
|
||||
page.setOnItemClickListener( ( parent, view, appPosition, id ) -> {
|
||||
if ( getOnAppClickedListener() != null ) {
|
||||
getOnAppClickedListener().onClick( mPagedApps.get( position ).get( appPosition ), position * AppsConst.TOTAL_SIZE_EACH_PAGE + appPosition );
|
||||
}
|
||||
} );
|
||||
container.addView( page );
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyItem( @NonNull ViewGroup container, int position, @NonNull Object object ) {
|
||||
if ( object instanceof View ) {
|
||||
container.removeView( ( ( View ) object ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemPosition( @NonNull Object object ) {
|
||||
return POSITION_NONE;
|
||||
}
|
||||
|
||||
public interface OnAppClickedListener {
|
||||
void onClick( AppInfo appInfo, int position );
|
||||
}
|
||||
}
|
||||
@@ -13,11 +13,14 @@ import androidx.lifecycle.Observer;
|
||||
import com.mogo.commons.mvp.Presenter;
|
||||
import com.mogo.module.apps.model.AppInfo;
|
||||
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
|
||||
@@ -29,13 +32,12 @@ public class AppsPresenter extends Presenter< AppsView > {
|
||||
|
||||
private static final String TAG = "AppsPresenter";
|
||||
|
||||
private AppFilter mAppFilter;
|
||||
|
||||
public AppsPresenter( AppsView view ) {
|
||||
super( view );
|
||||
RefreshAppsListLiveData.getInstance().observeForever( new Observer< String >() {
|
||||
@Override
|
||||
public void onChanged( String s ) {
|
||||
renderAppsList();
|
||||
}
|
||||
RefreshAppsListLiveData.getInstance().observeForever( s -> {
|
||||
renderAppsList();
|
||||
} );
|
||||
}
|
||||
|
||||
@@ -46,55 +48,58 @@ public class AppsPresenter extends Presenter< AppsView > {
|
||||
}
|
||||
|
||||
private void renderAppsList() {
|
||||
ThreadPoolService.execute( new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final List< AppInfo > appInfoList = loadAppsList();
|
||||
UiThreadHandler.post( new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if ( mView != null ) {
|
||||
mView.renderApps( appInfoList );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
ThreadPoolService.execute( () -> {
|
||||
final Map< Integer, List< AppInfo > > appInfoList = loadAppsList();
|
||||
UiThreadHandler.post( () -> {
|
||||
if ( mView != null ) {
|
||||
mView.renderApps( appInfoList );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
private List< AppInfo > loadAppsList() {
|
||||
private Map< Integer, List< AppInfo > > loadAppsList() {
|
||||
Logger.i( TAG, "load apps list." );
|
||||
final List< AppInfo > appInfos = new ArrayList<>();
|
||||
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 ( ( packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM ) == 0 ) {
|
||||
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 );
|
||||
appInfos.add( appInfo );
|
||||
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 appInfos;
|
||||
return pagedApps;
|
||||
}
|
||||
|
||||
public void launch( AppInfo appInfo ) {
|
||||
if ( appInfo == null ) {
|
||||
return;
|
||||
}
|
||||
Intent intent = getContext().getPackageManager().getLaunchIntentForPackage( appInfo.getPackageName() );
|
||||
if ( intent == null ) {
|
||||
Logger.e( TAG, "can't launch app: %s", appInfo.toString() );
|
||||
return;
|
||||
|
||||
try {
|
||||
Intent intent = getContext().getPackageManager().getLaunchIntentForPackage( appInfo.getPackageName() );
|
||||
intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
|
||||
getContext().startActivity( intent );
|
||||
} catch ( Exception e ) {
|
||||
TipToast.shortTip( R.string.module_apps_str_no_app );
|
||||
}
|
||||
intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
|
||||
getContext().startActivity( intent );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.mogo.commons.mvp.IView;
|
||||
import com.mogo.module.apps.model.AppInfo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
@@ -18,5 +19,5 @@ public interface AppsView extends IView {
|
||||
*
|
||||
* @param appInfos
|
||||
*/
|
||||
void renderApps( List< AppInfo > appInfos );
|
||||
void renderApps( Map< Integer, List< AppInfo > > appInfos );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user