init
This commit is contained in:
9
app/src/main/java/com/uiui/os/AppInfo.java
Normal file
9
app/src/main/java/com/uiui/os/AppInfo.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package com.uiui.os;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class AppInfo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -5488458740561098181L;
|
||||
|
||||
}
|
||||
270
app/src/main/java/com/uiui/os/activity/MainActivity.java
Normal file
270
app/src/main/java/com/uiui/os/activity/MainActivity.java
Normal file
@@ -0,0 +1,270 @@
|
||||
package com.uiui.os.activity;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Color;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.alarmclock.uiui.IAlarmAidlInterface;
|
||||
import com.amap.api.location.AMapLocation;
|
||||
import com.amap.api.location.AMapLocationClient;
|
||||
import com.amap.api.location.AMapLocationListener;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.qweather.sdk.bean.base.Code;
|
||||
import com.qweather.sdk.bean.base.Lang;
|
||||
import com.qweather.sdk.bean.base.Unit;
|
||||
import com.qweather.sdk.bean.weather.WeatherNowBean;
|
||||
import com.qweather.sdk.view.QWeather;
|
||||
import com.uiui.os.R;
|
||||
import com.uiui.os.base.BaseActivity;
|
||||
import com.uiui.os.bean.AlarmItem;
|
||||
import com.uiui.os.fragment.AppListFragment;
|
||||
import com.uiui.os.fragment.BaseFragmentPagerAdapter;
|
||||
import com.uiui.os.fragment.CustomFragment;
|
||||
import com.uiui.os.utils.AmapManager;
|
||||
import com.uiui.os.utils.ApkUtils;
|
||||
import com.uiui.os.view.ScaleCircleNavigator;
|
||||
|
||||
import net.lucode.hackware.magicindicator.MagicIndicator;
|
||||
import net.lucode.hackware.magicindicator.ViewPagerHelper;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public class MainActivity extends BaseActivity {
|
||||
private String TAG = MainActivity.class.getSimpleName();
|
||||
|
||||
@BindView(R.id.viewPager)
|
||||
ViewPager viewPager;
|
||||
@BindView(R.id.magicIndicator)
|
||||
MagicIndicator magicIndicator;
|
||||
|
||||
private FragmentManager fragmentManager;
|
||||
private FragmentTransaction fragmentTransaction;
|
||||
private BaseFragmentPagerAdapter adapter;
|
||||
private List<Fragment> fragments;
|
||||
private CustomFragment customFragment;
|
||||
|
||||
@Override
|
||||
public int getLayoutId() {
|
||||
return R.layout.activity_main;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initView() {
|
||||
ButterKnife.bind(this);
|
||||
fragmentManager = getSupportFragmentManager();
|
||||
fragmentTransaction = fragmentManager.beginTransaction();
|
||||
fragments = new ArrayList<>();
|
||||
adapter = new BaseFragmentPagerAdapter(fragmentManager, fragments);
|
||||
// fragmentTransaction.add(R.id.viewPager, appListFragment);
|
||||
// fragmentTransaction.commit();
|
||||
customFragment = new CustomFragment();
|
||||
mAlarmServiceConnection = new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
Log.e(TAG, "onServiceConnected: ");
|
||||
mIAlarmAidlInterface = IAlarmAidlInterface.Stub.asInterface(service);
|
||||
getAlarmData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
Log.e(TAG, "onServiceDisconnected: ");
|
||||
mIAlarmAidlInterface = null;
|
||||
}
|
||||
};
|
||||
bindAlarmService();
|
||||
}
|
||||
|
||||
private void getAlarmData() {
|
||||
if (mIAlarmAidlInterface == null) {
|
||||
bindAlarmService();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String json = mIAlarmAidlInterface.getAlarm();
|
||||
Log.e(TAG, "onServiceConnected: " + json);
|
||||
if (json.equalsIgnoreCase("暂无闹钟")) {
|
||||
customFragment.setAlarmItem(null);
|
||||
return;
|
||||
}
|
||||
Type type = new TypeToken<AlarmItem>() {
|
||||
}.getType();
|
||||
AlarmItem alarmItem = new Gson().fromJson(json, type);
|
||||
customFragment.setAlarmItem(alarmItem);
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private ServiceConnection mAlarmServiceConnection;
|
||||
private IAlarmAidlInterface mIAlarmAidlInterface;
|
||||
|
||||
private void bindAlarmService() {
|
||||
if (mIAlarmAidlInterface == null) {
|
||||
//这是连接aidl服务的代码
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.alarmclock.uiui.IAlarmAidlInterface");
|
||||
intent.setPackage("com.alarmclock.uiui");
|
||||
intent.setComponent(new ComponentName("com.alarmclock.uiui", "com.alarmclock.uiui.AIDLAlarmService"));
|
||||
bindService(intent, mAlarmServiceConnection, Context.BIND_AUTO_CREATE);
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private final static int APP_LIST_SIZE = 12;
|
||||
|
||||
@Override
|
||||
public void initData() {
|
||||
registmNewAppReceiver();
|
||||
fragments.add(customFragment);
|
||||
ArrayList<ApplicationInfo> applicationInfoList = ApkUtils.queryFilterAppInfo(this);
|
||||
int x = 0;
|
||||
for (int i = 0; i <= applicationInfoList.size(); i++) {
|
||||
if (i != 0 && i % APP_LIST_SIZE == 0) {
|
||||
AppListFragment appListFragment = new AppListFragment();
|
||||
appListFragment.setAppList(new ArrayList<>(applicationInfoList.subList(x, i)));
|
||||
fragments.add(appListFragment);
|
||||
x = i;
|
||||
} else if (i == applicationInfoList.size()) {
|
||||
AppListFragment appListFragment = new AppListFragment();
|
||||
fragments.add(appListFragment);
|
||||
appListFragment.setAppList(new ArrayList<>(applicationInfoList.subList(x, i)));
|
||||
}
|
||||
}
|
||||
viewPager.setAdapter(adapter);
|
||||
ScaleCircleNavigator scaleCircleNavigator = new ScaleCircleNavigator(this);
|
||||
scaleCircleNavigator.setCircleCount(fragments.size());
|
||||
scaleCircleNavigator.setNormalCircleColor(Color.DKGRAY);
|
||||
scaleCircleNavigator.setSelectedCircleColor(Color.LTGRAY);
|
||||
scaleCircleNavigator.setCircleClickListener(new ScaleCircleNavigator.OnCircleClickListener() {
|
||||
@Override
|
||||
public void onClick(int index) {
|
||||
|
||||
}
|
||||
});
|
||||
magicIndicator.setNavigator(scaleCircleNavigator);
|
||||
ViewPagerHelper.bind(magicIndicator, viewPager);
|
||||
if (fragments.size() > 1) {
|
||||
viewPager.setCurrentItem(1);
|
||||
}
|
||||
}
|
||||
|
||||
private void addData() {
|
||||
List<Fragment> fragmentList = new ArrayList<>();
|
||||
ArrayList<ApplicationInfo> applicationInfoList = ApkUtils.queryFilterAppInfo(this);
|
||||
int x = 0;
|
||||
for (int i = 0; i <= applicationInfoList.size(); i++) {
|
||||
if (i != 0 && i % APP_LIST_SIZE == 0) {
|
||||
AppListFragment appListFragment = new AppListFragment();
|
||||
appListFragment.setAppList(new ArrayList<>(applicationInfoList.subList(x, i)));
|
||||
fragmentList.add(appListFragment);
|
||||
x = i;
|
||||
} else if (i == applicationInfoList.size()) {
|
||||
AppListFragment appListFragment = new AppListFragment();
|
||||
fragmentList.add(appListFragment);
|
||||
appListFragment.setAppList(new ArrayList<>(applicationInfoList.subList(x, i)));
|
||||
}
|
||||
}
|
||||
for (int i = 1; i <= fragmentList.size(); i++) {
|
||||
if (fragments.get(i) != null) {
|
||||
adapter.replaceFragment(i, fragmentList.get(i - 1));
|
||||
fragments.remove(i);
|
||||
fragments.add(i, fragmentList.get(i - 1));
|
||||
} else {
|
||||
adapter.addFragment(fragmentList.get(i - 1));
|
||||
fragments.add(fragmentList.get(i - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
return false;
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
Log.e(TAG, "onNewIntent: " + intent.getAction());
|
||||
String action = intent.getAction();
|
||||
if (TextUtils.isEmpty(action)) {
|
||||
return;
|
||||
}
|
||||
switch (action) {
|
||||
default:
|
||||
break;
|
||||
case Intent.ACTION_MAIN:
|
||||
viewPager.setCurrentItem(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(@NonNull Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mNewAppReceiver != null) {
|
||||
unregisterReceiver(mNewAppReceiver);
|
||||
}
|
||||
}
|
||||
|
||||
private NewAppReceiver mNewAppReceiver;
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
getAlarmData();
|
||||
}
|
||||
|
||||
private void registmNewAppReceiver() {
|
||||
mNewAppReceiver = new NewAppReceiver();
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
|
||||
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
|
||||
filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
|
||||
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
|
||||
filter.addDataScheme("package");
|
||||
registerReceiver(mNewAppReceiver, filter);
|
||||
}
|
||||
|
||||
class NewAppReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
Log.e(TAG, "onReceive: " + action);
|
||||
addData();
|
||||
}
|
||||
}
|
||||
}
|
||||
55
app/src/main/java/com/uiui/os/base/BaseActivity.java
Normal file
55
app/src/main/java/com/uiui/os/base/BaseActivity.java
Normal file
@@ -0,0 +1,55 @@
|
||||
package com.uiui.os.base;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.uiui.os.R;
|
||||
import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX;
|
||||
|
||||
public abstract class BaseActivity extends AppCompatActivity {
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setBar();
|
||||
//状态栏改变放在setContentView前后有所不同
|
||||
setContentView(this.getLayoutId());
|
||||
initView();
|
||||
initData();
|
||||
}
|
||||
|
||||
private void setBar() {
|
||||
UltimateBarX.statusBar(this)
|
||||
.transparent()
|
||||
.colorRes(R.color.colorPrimaryDark)
|
||||
// .light(true)
|
||||
.apply();
|
||||
UltimateBarX.navigationBar(this)
|
||||
.transparent()
|
||||
.colorRes(R.color.colorPrimaryDark)
|
||||
// .light(true)
|
||||
.apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置布局
|
||||
*/
|
||||
public abstract int getLayoutId();
|
||||
|
||||
/**
|
||||
* 初始化视图
|
||||
*/
|
||||
public abstract void initView();
|
||||
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
public abstract void initData();
|
||||
}
|
||||
70
app/src/main/java/com/uiui/os/base/BaseApplication.java
Normal file
70
app/src/main/java/com/uiui/os/base/BaseApplication.java
Normal file
@@ -0,0 +1,70 @@
|
||||
package com.uiui.os.base;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import com.qweather.sdk.view.HeConfig;
|
||||
import com.uiui.os.utils.AmapManager;
|
||||
|
||||
|
||||
public class BaseApplication extends Application {
|
||||
private static final String TAG = BaseApplication.class.getSimpleName();
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
public static Context context;
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private static BaseApplication instance;
|
||||
|
||||
public static Context getAppContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
// 单例模式中获取唯一的ExitApplication实例
|
||||
public static BaseApplication getInstance() {
|
||||
if (null == instance) {
|
||||
instance = new BaseApplication();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
context = this;
|
||||
HeConfig.init("HE2111041506381545", "32b5ec69545e44119583a5e0ed4e87df");
|
||||
AmapManager.init(this);
|
||||
}
|
||||
|
||||
|
||||
private void catchException() {
|
||||
Thread.setDefaultUncaughtExceptionHandler(
|
||||
new Thread.UncaughtExceptionHandler() {
|
||||
@Override
|
||||
public void uncaughtException(Thread t, Throwable e) {
|
||||
Log.e("捕获异常子线程:", Thread.currentThread().getName() +
|
||||
"在:" + e.getStackTrace()[0].getClassName());
|
||||
}
|
||||
}
|
||||
);
|
||||
//下面是新增方法!
|
||||
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
Looper.loop(); //会先执行这个方法,然后在执行下面的异常捕获方法!
|
||||
} catch (Exception e) {
|
||||
Log.e("捕获异常主线程:", Thread.currentThread().getName() + "在:" + e.getStackTrace()[0].getClassName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
21
app/src/main/java/com/uiui/os/bean/AlarmItem.java
Normal file
21
app/src/main/java/com/uiui/os/bean/AlarmItem.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.uiui.os.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class AlarmItem implements Serializable {
|
||||
private static final long serialVersionUID = -2760428066543837757L;
|
||||
public String mTitle;
|
||||
public String mTime;
|
||||
public String mRepeatType;
|
||||
public String mRepeatCode;
|
||||
public boolean mActive;
|
||||
|
||||
public AlarmItem(String time, String repeatNormal, String repeatDefine, boolean active) {
|
||||
// this.mTitle = title;
|
||||
this.mTime = time;
|
||||
this.mRepeatType = repeatNormal;
|
||||
this.mRepeatCode = repeatDefine;
|
||||
this.mActive = active;
|
||||
|
||||
}
|
||||
}
|
||||
166
app/src/main/java/com/uiui/os/fragment/AppListFragment.java
Normal file
166
app/src/main/java/com/uiui/os/fragment/AppListFragment.java
Normal file
@@ -0,0 +1,166 @@
|
||||
package com.uiui.os.fragment;
|
||||
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.NavUtils;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.uiui.os.R;
|
||||
import com.uiui.os.utils.ApkUtils;
|
||||
import com.uiui.os.utils.BitmapUtils;
|
||||
import com.uiui.os.utils.IconUtils;
|
||||
import com.uiui.os.view.MyGridLayout;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A simple {@link Fragment} subclass.
|
||||
* Use the {@link AppListFragment#newInstance} factory method to
|
||||
* create an instance of this fragment.
|
||||
*/
|
||||
public class AppListFragment extends Fragment {
|
||||
// TODO: Rename parameter arguments, choose names that match
|
||||
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
||||
private static final String ARG_PARAM1 = "param1";
|
||||
private static final String ARG_PARAM2 = "param2";
|
||||
|
||||
// TODO: Rename and change types of parameters
|
||||
private String mParam1;
|
||||
private String mParam2;
|
||||
|
||||
private ArrayList<ApplicationInfo> applicationInfos;
|
||||
private MyGridLayout gridLayout;
|
||||
private String TAG = AppListFragment.class.getSimpleName();
|
||||
|
||||
public AppListFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this factory method to create a new instance of
|
||||
* this fragment using the provided parameters.
|
||||
*
|
||||
* @param param1 Parameter 1.
|
||||
* @param param2 Parameter 2.
|
||||
* @return A new instance of fragment AppListFragment.
|
||||
*/
|
||||
// TODO: Rename and change types and number of parameters
|
||||
public static AppListFragment newInstance(String param1, String param2) {
|
||||
AppListFragment fragment = new AppListFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putString(ARG_PARAM1, param1);
|
||||
args.putString(ARG_PARAM2, param2);
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (savedInstanceState != null) {
|
||||
applicationInfos = savedInstanceState.getParcelableArrayList("applicationInfos");
|
||||
}
|
||||
if (getArguments() != null) {
|
||||
mParam1 = getArguments().getString(ARG_PARAM1);
|
||||
mParam2 = getArguments().getString(ARG_PARAM2);
|
||||
}
|
||||
}
|
||||
|
||||
private View rootView;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
rootView = inflater.inflate(R.layout.fragment_applist, container, false);
|
||||
initView();
|
||||
return rootView;
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
if (applicationInfos.size() != 12) {
|
||||
applicationInfos.addAll(new ArrayList<>(Arrays.asList(new ApplicationInfo[12 - applicationInfos.size()])));
|
||||
}
|
||||
gridLayout = rootView.findViewById(R.id.list);
|
||||
if (getActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
gridLayout.set(4, 3);
|
||||
} else {
|
||||
gridLayout.set(3, 4);
|
||||
}
|
||||
|
||||
gridLayout.setGridAdapter(new MyGridLayout.GridAdatper() {
|
||||
@Override
|
||||
public View getView(int index) {
|
||||
PackageManager pm = rootView.getContext().getPackageManager();
|
||||
View view = getLayoutInflater().inflate(R.layout.actions_item,
|
||||
null);
|
||||
ImageView iv = view.findViewById(R.id.iv);
|
||||
TextView tv = view.findViewById(R.id.tv);
|
||||
LinearLayout linearLayout = view.findViewById(R.id.btn_booktag);
|
||||
ApplicationInfo applicationInfo = applicationInfos.get(index);
|
||||
|
||||
if (applicationInfo != null) {
|
||||
Log.e(TAG, "getView: " + applicationInfo.packageName);
|
||||
int i = IconUtils.appClassNameList.indexOf(applicationInfo.packageName);
|
||||
if (i != -1) {
|
||||
String val = IconUtils.appIconList.get(i);
|
||||
int resID = getActivity().getResources().getIdentifier(val, "drawable", "com.uiui.os");
|
||||
if (resID == 0) {
|
||||
iv.setImageDrawable(applicationInfo.loadIcon(pm));
|
||||
} else {
|
||||
iv.setImageDrawable(getActivity().getResources().getDrawable(resID));
|
||||
}
|
||||
} else {
|
||||
iv.setImageBitmap(BitmapUtils.getIconBitmap(rootView.getContext(), applicationInfo.loadIcon(pm)));
|
||||
}
|
||||
tv.setText(applicationInfo.loadLabel(pm));
|
||||
// linearLayout.setEnabled(true);
|
||||
} else {
|
||||
// linearLayout.setEnabled(false);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
// return applicationInfos == null ? 0 : applicationInfos.size();
|
||||
return applicationInfos.size();
|
||||
}
|
||||
});
|
||||
gridLayout.setApplicationInfos(applicationInfos);
|
||||
gridLayout.setOnItemClickListener(new MyGridLayout.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(View v, int index) {
|
||||
ApplicationInfo applicationInfo = applicationInfos.get(index);
|
||||
if (applicationInfo != null) {
|
||||
ApkUtils.openPackage(v.getContext(), applicationInfo.packageName);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setAppList(ArrayList<ApplicationInfo> appList) {
|
||||
this.applicationInfos = appList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
outState.putParcelableArrayList("applicationInfos", applicationInfos);
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
package com.uiui.os.fragment;
|
||||
|
||||
import android.util.SparseArray;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentPagerAdapter;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 加载显示Fragment的ViewPagerAdapter基类
|
||||
* 提供可以刷新的方法
|
||||
*
|
||||
* @author Fly
|
||||
* @e-mail 1285760616@qq.com
|
||||
* @time 2018/3/22
|
||||
*/
|
||||
public class BaseFragmentPagerAdapter extends FragmentPagerAdapter {
|
||||
private List<Fragment> mFragmentList;
|
||||
private FragmentManager mFragmentManager;
|
||||
/**下面两个值用来保存Fragment的位置信息,用以判断该位置是否需要更新*/
|
||||
private SparseArray<String> mFragmentPositionMap;
|
||||
private SparseArray<String> mFragmentPositionMapAfterUpdate;
|
||||
|
||||
public BaseFragmentPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
|
||||
super(fm);
|
||||
mFragmentList = fragments;
|
||||
mFragmentManager = fm;
|
||||
mFragmentList = fragments;
|
||||
mFragmentPositionMap = new SparseArray<>();
|
||||
mFragmentPositionMapAfterUpdate = new SparseArray<>();
|
||||
setFragmentPositionMap();
|
||||
setFragmentPositionMapForUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存更新之前的位置信息,用<hashCode, position>的键值对结构来保存
|
||||
*/
|
||||
private void setFragmentPositionMap() {
|
||||
mFragmentPositionMap.clear();
|
||||
for (int i = 0; i < mFragmentList.size(); i++) {
|
||||
mFragmentPositionMap.put(Long.valueOf(getItemId(i)).intValue(), String.valueOf(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存更新之后的位置信息,用<hashCode, position>的键值对结构来保存
|
||||
*/
|
||||
private void setFragmentPositionMapForUpdate() {
|
||||
mFragmentPositionMapAfterUpdate.clear();
|
||||
for (int i = 0; i < mFragmentList.size(); i++) {
|
||||
mFragmentPositionMapAfterUpdate.put(Long.valueOf(getItemId(i)).intValue(), String.valueOf(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 在此方法中找到需要更新的位置返回POSITION_NONE,否则返回POSITION_UNCHANGED即可
|
||||
*/
|
||||
@Override
|
||||
public int getItemPosition(Object object) {
|
||||
int hashCode = object.hashCode();
|
||||
//查找object在更新后的列表中的位置
|
||||
String position = mFragmentPositionMapAfterUpdate.get(hashCode);
|
||||
//更新后的列表中不存在该object的位置了
|
||||
if (position == null) {
|
||||
return POSITION_NONE;
|
||||
} else {
|
||||
//如果更新后的列表中存在该object的位置, 查找该object之前的位置并判断位置是否发生了变化
|
||||
int size = mFragmentPositionMap.size();
|
||||
for (int i = 0; i < size ; i++) {
|
||||
int key = mFragmentPositionMap.keyAt(i);
|
||||
if (key == hashCode) {
|
||||
String index = mFragmentPositionMap.get(key);
|
||||
if (position.equals(index)) {
|
||||
//位置没变依然返回POSITION_UNCHANGED
|
||||
return POSITION_UNCHANGED;
|
||||
} else {
|
||||
//位置变了
|
||||
return POSITION_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return POSITION_UNCHANGED;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指定的Fragment替换/更新为新的Fragment
|
||||
* @param oldFragment 旧Fragment
|
||||
* @param newFragment 新Fragment
|
||||
*/
|
||||
public void replaceFragment(Fragment oldFragment, Fragment newFragment) {
|
||||
int position = mFragmentList.indexOf(oldFragment);
|
||||
if (position == -1) {
|
||||
return;
|
||||
}
|
||||
//从Transaction移除旧的Fragment
|
||||
removeFragmentInternal(oldFragment);
|
||||
//替换List中对应的Fragment
|
||||
mFragmentList.set(position, newFragment);
|
||||
//刷新Adapter
|
||||
notifyItemChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指定位置的Fragment替换/更新为新的Fragment,同{@link #replaceFragment(Fragment oldFragment, Fragment newFragment)}
|
||||
* @param position 旧Fragment的位置
|
||||
* @param newFragment 新Fragment
|
||||
*/
|
||||
public void replaceFragment(int position, Fragment newFragment) {
|
||||
Fragment oldFragment = mFragmentList.get(position);
|
||||
removeFragmentInternal(oldFragment);
|
||||
mFragmentList.set(position, newFragment);
|
||||
notifyItemChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除指定的Fragment
|
||||
* @param fragment 目标Fragment
|
||||
*/
|
||||
public void removeFragment(Fragment fragment) {
|
||||
//先从List中移除
|
||||
mFragmentList.remove(fragment);
|
||||
//然后从Transaction移除
|
||||
removeFragmentInternal(fragment);
|
||||
//最后刷新Adapter
|
||||
notifyItemChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除指定位置的Fragment,同 {@link #removeFragment(Fragment fragment)}
|
||||
* @param position
|
||||
*/
|
||||
public void removeFragment(int position) {
|
||||
Fragment fragment = mFragmentList.get(position);
|
||||
//然后从List中移除
|
||||
mFragmentList.remove(fragment);
|
||||
//先从Transaction移除
|
||||
removeFragmentInternal(fragment);
|
||||
//最后刷新Adapter
|
||||
notifyItemChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加Fragment
|
||||
* @param fragment 目标Fragment
|
||||
*/
|
||||
public void addFragment(Fragment fragment) {
|
||||
mFragmentList.add(fragment);
|
||||
notifyItemChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 在指定位置插入一个Fragment
|
||||
* @param position 插入位置
|
||||
* @param fragment 目标Fragment
|
||||
*/
|
||||
public void insertFragment(int position, Fragment fragment) {
|
||||
mFragmentList.add(position, fragment);
|
||||
notifyItemChanged();
|
||||
}
|
||||
|
||||
private void notifyItemChanged() {
|
||||
//刷新之前重新收集位置信息
|
||||
setFragmentPositionMapForUpdate();
|
||||
notifyDataSetChanged();
|
||||
setFragmentPositionMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从Transaction移除Fragment
|
||||
* @param fragment 目标Fragment
|
||||
*/
|
||||
private void removeFragmentInternal(Fragment fragment) {
|
||||
FragmentTransaction transaction = mFragmentManager.beginTransaction();
|
||||
transaction.remove(fragment);
|
||||
transaction.commitNow();
|
||||
}
|
||||
|
||||
/**
|
||||
* 此方法不用position做返回值即可破解fragment tag异常的错误
|
||||
*/
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
// 获取当前数据的hashCode,其实这里不用hashCode用自定义的可以关联当前Item对象的唯一值也可以,只要不是直接返回position
|
||||
return mFragmentList.get(position).hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
return mFragmentList.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mFragmentList.size();
|
||||
}
|
||||
|
||||
public List<Fragment> getFragments() {
|
||||
return mFragmentList;
|
||||
}
|
||||
}
|
||||
343
app/src/main/java/com/uiui/os/fragment/CustomFragment.java
Normal file
343
app/src/main/java/com/uiui/os/fragment/CustomFragment.java
Normal file
@@ -0,0 +1,343 @@
|
||||
package com.uiui.os.fragment;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.amap.api.location.AMapLocation;
|
||||
import com.amap.api.location.AMapLocationClient;
|
||||
import com.amap.api.location.AMapLocationListener;
|
||||
import com.google.gson.Gson;
|
||||
import com.king.view.circleprogressview.CircleProgressView;
|
||||
import com.qweather.sdk.bean.base.Code;
|
||||
import com.qweather.sdk.bean.base.Lang;
|
||||
import com.qweather.sdk.bean.base.Unit;
|
||||
import com.qweather.sdk.bean.weather.WeatherNowBean;
|
||||
import com.qweather.sdk.view.QWeather;
|
||||
import com.uiui.os.BuildConfig;
|
||||
import com.uiui.os.R;
|
||||
import com.uiui.os.bean.AlarmItem;
|
||||
import com.uiui.os.utils.AmapManager;
|
||||
import com.uiui.os.utils.ApkUtils;
|
||||
import com.uiui.os.utils.AppUtil;
|
||||
import com.uiui.os.utils.Utils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
/**
|
||||
* A simple {@link Fragment} subclass.
|
||||
* Use the {@link CustomFragment#newInstance} factory method to
|
||||
* create an instance of this fragment.
|
||||
*/
|
||||
public class CustomFragment extends Fragment {
|
||||
private String TAG = CustomFragment.class.getSimpleName();
|
||||
|
||||
private TextView tv_time,tv_add, tv_type, tv_status;
|
||||
private ImageView iv_pic;
|
||||
private TextView tv_temp;
|
||||
private TextView tv_battery;
|
||||
private TextView tv_location;
|
||||
private CircleProgressView cpv;
|
||||
private ConstraintLayout cl_alarm;
|
||||
private ImageView iv_charging;
|
||||
private int[] mShaderColors = new int[]{0xFFfa3db5, 0xFFF8867E, 0xFFF79F6B, 0xFFF79F6B, 0xFFF79F6B, 0xFFF8867E, 0xFFfa3db5};
|
||||
|
||||
|
||||
// TODO: Rename parameter arguments, choose names that match
|
||||
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
||||
private static final String ARG_PARAM1 = "param1";
|
||||
private static final String ARG_PARAM2 = "param2";
|
||||
|
||||
// TODO: Rename and change types of parameters
|
||||
private String mParam1;
|
||||
private String mParam2;
|
||||
|
||||
private View rootView;
|
||||
private AlarmItem alarmItem;
|
||||
|
||||
public CustomFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this factory method to create a new instance of
|
||||
* this fragment using the provided parameters.
|
||||
*
|
||||
* @param param1 Parameter 1.
|
||||
* @param param2 Parameter 2.
|
||||
* @return A new instance of fragment CustomFragment.
|
||||
*/
|
||||
// TODO: Rename and change types and number of parameters
|
||||
public static CustomFragment newInstance(String param1, String param2) {
|
||||
CustomFragment fragment = new CustomFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putString(ARG_PARAM1, param1);
|
||||
args.putString(ARG_PARAM2, param2);
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public void setAlarmItem(AlarmItem item) {
|
||||
this.alarmItem = item;
|
||||
setAlarm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (getArguments() != null) {
|
||||
mParam1 = getArguments().getString(ARG_PARAM1);
|
||||
mParam2 = getArguments().getString(ARG_PARAM2);
|
||||
}
|
||||
registerBatteryReceiver();
|
||||
getActivity().registerReceiver(mbatteryReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
||||
}
|
||||
|
||||
private void registerBatteryReceiver() {
|
||||
if (null == batteryReceiver) {
|
||||
batteryReceiver = new BatteryReceiver();
|
||||
}
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
|
||||
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
|
||||
filter.addAction(Intent.ACTION_BATTERY_LOW);
|
||||
filter.addAction(Intent.ACTION_BATTERY_OKAY);
|
||||
filter.addAction(Intent.ACTION_POWER_CONNECTED);
|
||||
filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
|
||||
getActivity().registerReceiver(batteryReceiver, filter);
|
||||
}
|
||||
|
||||
BatteryReceiver batteryReceiver;
|
||||
|
||||
private class BatteryReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
|
||||
// 当前电量
|
||||
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
|
||||
// 最大电量
|
||||
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0);
|
||||
int elec = (level * 100) / scale;
|
||||
Log.e(TAG, "electricity:=" + elec + "%");
|
||||
tv_battery.setText(elec + "%");
|
||||
} else if (Intent.ACTION_POWER_CONNECTED.equals(action)
|
||||
|| Intent.ACTION_POWER_DISCONNECTED.equals(action)
|
||||
|| Intent.ACTION_BATTERY_LOW.equals(action)
|
||||
|| Intent.ACTION_BATTERY_OKAY.equals(action)
|
||||
) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BroadcastReceiver mbatteryReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
Log.e(TAG, "onReceive: " + action);
|
||||
if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
|
||||
int status = intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN);
|
||||
if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
|
||||
if (rootView != null) {
|
||||
iv_charging.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}else {
|
||||
if (rootView != null) {
|
||||
iv_charging.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
rootView = inflater.inflate(R.layout.fragment_custom, container, false);
|
||||
initView();
|
||||
initData();
|
||||
return rootView;
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
tv_time = rootView.findViewById(R.id.tv_time);
|
||||
tv_add = rootView.findViewById(R.id.tv_add);
|
||||
tv_type = rootView.findViewById(R.id.tv_type);
|
||||
tv_status = rootView.findViewById(R.id.tv_status);
|
||||
|
||||
iv_pic = rootView.findViewById(R.id.iv_pic);
|
||||
tv_temp = rootView.findViewById(R.id.tv_temp);
|
||||
tv_location = rootView.findViewById(R.id.tv_location);
|
||||
tv_battery = rootView.findViewById(R.id.tv_battery);
|
||||
Log.e(TAG, "initView: " + Utils.getBatteryLevel(getActivity()));
|
||||
tv_battery.setText(Utils.getBatteryLevel(getActivity()) + "%");
|
||||
cpv = rootView.findViewById(R.id.cpv);
|
||||
cpv.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
killBackgroundApp();
|
||||
}
|
||||
});
|
||||
cl_alarm = rootView.findViewById(R.id.cl_alarm);
|
||||
cl_alarm.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
ApkUtils.openPackage(getActivity(), "com.alarmclock.uiui");
|
||||
}
|
||||
});
|
||||
iv_charging = rootView.findViewById(R.id.iv_charging);
|
||||
setAlarm();
|
||||
refreshMemory();
|
||||
}
|
||||
|
||||
private void setAlarm() {
|
||||
if (rootView == null) return;
|
||||
if (alarmItem == null) {
|
||||
tv_time.setText("暂无闹钟");
|
||||
tv_time.setVisibility(View.GONE);
|
||||
tv_add.setVisibility(View.VISIBLE);
|
||||
tv_type.setVisibility(View.GONE);
|
||||
tv_status.setVisibility(View.GONE);
|
||||
} else {
|
||||
tv_time.setText(alarmItem.mTime);
|
||||
tv_time.setVisibility(View.VISIBLE);
|
||||
tv_add.setVisibility(View.GONE);
|
||||
tv_type.setText(alarmItem.mRepeatType);
|
||||
tv_type.setVisibility(View.VISIBLE);
|
||||
tv_status.setVisibility(View.VISIBLE);
|
||||
if (alarmItem.mActive) {
|
||||
tv_status.setText("打开");
|
||||
} else {
|
||||
tv_status.setText("关闭");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initData() {
|
||||
initAmap();
|
||||
}
|
||||
|
||||
private void initAmap() {
|
||||
AMapLocationClient aMapLocationClient = AmapManager.getInstance().getLocationClient();
|
||||
aMapLocationClient.stopLocation();
|
||||
aMapLocationClient.startLocation();
|
||||
aMapLocationClient.setLocationListener(new AMapLocationListener() {
|
||||
@Override
|
||||
public void onLocationChanged(AMapLocation aMapLocation) {
|
||||
Log.e(TAG, "onLocationChanged: " + aMapLocation);
|
||||
if (aMapLocation.getErrorCode() == 0) {
|
||||
String city = aMapLocation.getCity();
|
||||
getweather(aMapLocation.getLongitude(), aMapLocation.getLatitude());
|
||||
tv_location.setText(city);
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void getweather(double longitude, double latitude) {
|
||||
/**
|
||||
* 实况天气数据
|
||||
* @param location 所查询的地区,可通过该地区名称、ID、IP和经纬度进行查询经纬度格式:经度,纬度
|
||||
* (英文,分隔,十进制格式,北纬东经为正,南纬西经为负)
|
||||
* @param lang (选填)多语言,可以不使用该参数,默认为简体中文
|
||||
* @param unit (选填)单位选择,公制(m)或英制(i),默认为公制单位
|
||||
* @param listener 网络访问结果回调
|
||||
*/
|
||||
|
||||
QWeather.getWeatherNow(getActivity(), "" + longitude + "," + latitude, Lang.ZH_HANS, Unit.METRIC, new QWeather.OnResultWeatherNowListener() {
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
Log.e(TAG, "getWeather onError: " + e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(WeatherNowBean weatherBean) {
|
||||
Log.e(TAG, "getWeather onSuccess: " + new Gson().toJson(weatherBean));
|
||||
//先判断返回的status是否正确,当status正确时获取数据,若status不正确,可查看status对应的Code值找到原因
|
||||
if (Code.OK == weatherBean.getCode()) {
|
||||
WeatherNowBean.NowBaseBean now = weatherBean.getNow();
|
||||
String imageName = "he" + now.getIcon();
|
||||
// int resId = getResources().getIdentifier(imageName, "drawable", getActivity().getPackageName());
|
||||
// iv_pic.setImageDrawable(getActivity().getDrawable(resId));
|
||||
tv_temp.setText(now.getTemp() + "℃");
|
||||
} else {
|
||||
//在此查看返回数据失败的原因
|
||||
Code code = weatherBean.getCode();
|
||||
Log.e(TAG, "failed code: " + code);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void killBackgroundApp() {
|
||||
List<String> pkgList = ApkUtils.queryFilterAppList(getActivity());
|
||||
for (String pkg : pkgList) {
|
||||
if (pkg.equalsIgnoreCase(BuildConfig.APPLICATION_ID)) continue;
|
||||
killBackgroundProcesses(pkg);
|
||||
}
|
||||
}
|
||||
|
||||
private void killBackgroundProcesses(String packageName) {
|
||||
ActivityManager activityManager;
|
||||
try {
|
||||
activityManager = (ActivityManager)
|
||||
getActivity().getSystemService(Context.ACTIVITY_SERVICE);
|
||||
activityManager.killBackgroundProcesses(packageName);
|
||||
Method forceStopPackage = activityManager.getClass()
|
||||
.getDeclaredMethod("forceStopPackage", String.class);
|
||||
// Log.e(TAG, "killBackgroundProcesses: " + packageName);
|
||||
forceStopPackage.setAccessible(true);
|
||||
forceStopPackage.invoke(activityManager, packageName);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "killBackgroundProcesses: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
refreshMemory();
|
||||
}
|
||||
|
||||
private void refreshMemory() {
|
||||
long avail = AppUtil.getAvailMemory(getActivity());
|
||||
long total = AppUtil.getTotalMemory(getActivity());
|
||||
int x = (int) (((total - avail) / (double) total) * 100);
|
||||
cpv.setProgressColor(mShaderColors);
|
||||
cpv.showAnimation(0, x, 1000);
|
||||
float x2 = (((total - avail) / (float) total));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (batteryReceiver != null) {
|
||||
getActivity().unregisterReceiver(batteryReceiver);
|
||||
}
|
||||
if (mbatteryReceiver != null) {
|
||||
getActivity().unregisterReceiver(mbatteryReceiver);
|
||||
}
|
||||
}
|
||||
}
|
||||
78
app/src/main/java/com/uiui/os/utils/AmapManager.java
Normal file
78
app/src/main/java/com/uiui/os/utils/AmapManager.java
Normal file
@@ -0,0 +1,78 @@
|
||||
package com.uiui.os.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import com.amap.api.location.AMapLocation;
|
||||
import com.amap.api.location.AMapLocationClient;
|
||||
import com.amap.api.location.AMapLocationClientOption;
|
||||
import com.amap.api.location.AMapLocationListener;
|
||||
|
||||
public class AmapManager {
|
||||
private static AmapManager sInstance;
|
||||
private Context mContext;
|
||||
public static AMapLocationClient locationClient = null;
|
||||
private String TAG = AmapManager.class.getSimpleName();
|
||||
|
||||
private AmapManager(Context context) {
|
||||
this.mContext = context;
|
||||
}
|
||||
|
||||
public static void init(Context context) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new AmapManager(context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static AmapManager getInstance() {
|
||||
if (sInstance == null) {
|
||||
throw new IllegalStateException("You must be init AmapManager first");
|
||||
}
|
||||
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
public AMapLocationClient getLocationClient() {
|
||||
if (null == locationClient) {
|
||||
initAmap();
|
||||
}
|
||||
return locationClient;
|
||||
}
|
||||
|
||||
public void initAmap() {
|
||||
locationClient = new AMapLocationClient(mContext);
|
||||
AMapLocationClientOption option = new AMapLocationClientOption();
|
||||
option.setLocationPurpose(AMapLocationClientOption.AMapLocationPurpose.SignIn);
|
||||
option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
|
||||
option.setNeedAddress(true);
|
||||
//获取一次定位结果:
|
||||
//该方法默认为false。
|
||||
option.setOnceLocation(true);
|
||||
//获取最近3s内精度最高的一次定位结果:
|
||||
//设置setOnceLocationLatest(boolean b)接口为true,启动定位时SDK会返回最近3s内精度最高的一次定位结果。
|
||||
// 如果设置其为true,setOnceLocation(boolean b)接口也会被设置为true,反之不会,默认为false。
|
||||
option.setOnceLocationLatest(true);
|
||||
locationClient.setLocationOption(option);
|
||||
//设置定位模式为AMapLocationMode.Hight_Accuracy,高精度模式。
|
||||
//设置定位监听
|
||||
locationClient.setLocationListener(new AMapLocationListener() {
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(AMapLocation aMapLocation) {
|
||||
//errCode等于0代表定位成功,其他的为定位失败,具体的可以参照官网定位错误码说明
|
||||
if (aMapLocation.getErrorCode() == 0) {
|
||||
Log.e(TAG, "onLocationChanged: " + "定位成功");
|
||||
Log.e(TAG, "onLocationChanged: " + aMapLocation.getAddress());
|
||||
} else {
|
||||
//定位失败
|
||||
Log.e(TAG, "onLocationChanged: " + "定位失败");
|
||||
}
|
||||
}
|
||||
});
|
||||
//设置场景模式后最好调用一次stop,再调用start以保证场景模式生效
|
||||
locationClient.stopLocation();
|
||||
locationClient.startLocation();
|
||||
Log.e(TAG, "initAmap: " + "startLocation");
|
||||
}
|
||||
}
|
||||
141
app/src/main/java/com/uiui/os/utils/ApkUtils.java
Normal file
141
app/src/main/java/com/uiui/os/utils/ApkUtils.java
Normal file
@@ -0,0 +1,141 @@
|
||||
package com.uiui.os.utils;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.uiui.os.BuildConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ApkUtils {
|
||||
private static String[] excludePackageName = {BuildConfig.APPLICATION_ID};
|
||||
|
||||
|
||||
public static ArrayList<ApplicationInfo> queryFilterAppInfo(Context context) {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
// 查询所有已经安装的应用程序
|
||||
List<ApplicationInfo> appInfos = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);// GET_UNINSTALLED_PACKAGES代表已删除,但还有安装目录的
|
||||
ArrayList<ApplicationInfo> applicationInfos = new ArrayList<>();
|
||||
|
||||
// 创建一个类别为CATEGORY_LAUNCHER的该包名的Intent
|
||||
Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
|
||||
resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
|
||||
// 通过getPackageManager()的queryIntentActivities方法遍历,得到所有能打开的app的packageName
|
||||
List<ResolveInfo> resolveinfoList = pm.queryIntentActivities(resolveIntent, 0);
|
||||
Set<String> allowPackages = new HashSet();
|
||||
for (ResolveInfo resolveInfo : resolveinfoList) {
|
||||
allowPackages.add(resolveInfo.activityInfo.packageName);
|
||||
}
|
||||
|
||||
for (ApplicationInfo app : appInfos) {
|
||||
// if((app.flags & ApplicationInfo.FLAG_SYSTEM) <= 0)//通过flag排除系统应用,会将电话、短信也排除掉
|
||||
// {
|
||||
// applicationInfos.add(app);
|
||||
// }
|
||||
// if(app.uid > 10000){//通过uid排除系统应用,在一些手机上效果不好
|
||||
// applicationInfos.add(app);
|
||||
// }
|
||||
if (allowPackages.contains(app.packageName) && !Arrays.asList(excludePackageName).contains(app.packageName)) {
|
||||
// if (allowPackages.contains(app.packageName)) {
|
||||
applicationInfos.add(app);
|
||||
}
|
||||
}
|
||||
return applicationInfos;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取第三方应用
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static List<String> queryFilterAppList(Context context) {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
// 查询所有已经安装的应用程序
|
||||
List<ApplicationInfo> appInfos = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);// GET_UNINSTALLED_PACKAGES代表已删除,但还有安装目录的
|
||||
List<String> applicationInfos = new ArrayList<>();
|
||||
for (ApplicationInfo app : appInfos) {
|
||||
// Log.e("queryFilterAppInfo", String.valueOf(app.flags));
|
||||
// Log.e("queryFilterAppInfo", String.valueOf((app.flags & mask)));
|
||||
if ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 1) {
|
||||
//通过flag排除系统应用,会将电话、短信也排除掉
|
||||
} else {
|
||||
applicationInfos.add(app.packageName);
|
||||
Log.e("queryFilterAppInfo", app.packageName);
|
||||
}
|
||||
}
|
||||
return applicationInfos;
|
||||
}
|
||||
|
||||
public static void openApp(Context context, String packageName) {
|
||||
Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
|
||||
if (intent != null) {
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static Intent getAppOpenIntentByPackageName(Context context,String packageName){
|
||||
//Activity完整名
|
||||
String mainAct = null;
|
||||
//根据包名寻找
|
||||
PackageManager pkgMag = context.getPackageManager();
|
||||
Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||
intent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED|Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
List<ResolveInfo> list = pkgMag.queryIntentActivities(intent,
|
||||
PackageManager.GET_ACTIVITIES);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
ResolveInfo info = list.get(i);
|
||||
if (info.activityInfo.packageName.equals(packageName)) {
|
||||
mainAct = info.activityInfo.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (TextUtils.isEmpty(mainAct)) {
|
||||
return null;
|
||||
}
|
||||
intent.setComponent(new ComponentName(packageName, mainAct));
|
||||
return intent;
|
||||
}
|
||||
|
||||
public static Context getPackageContext(Context context, String packageName) {
|
||||
Context pkgContext = null;
|
||||
if (context.getPackageName().equals(packageName)) {
|
||||
pkgContext = context;
|
||||
} else {
|
||||
// 创建第三方应用的上下文环境
|
||||
try {
|
||||
pkgContext = context.createPackageContext(packageName,
|
||||
Context.CONTEXT_IGNORE_SECURITY
|
||||
| Context.CONTEXT_INCLUDE_CODE);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return pkgContext;
|
||||
}
|
||||
|
||||
public static boolean openPackage(Context context, String packageName) {
|
||||
Context pkgContext = getPackageContext(context, packageName);
|
||||
Intent intent = getAppOpenIntentByPackageName(context, packageName);
|
||||
if (pkgContext != null && intent != null) {
|
||||
pkgContext.startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
91
app/src/main/java/com/uiui/os/utils/AppUtil.java
Normal file
91
app/src/main/java/com/uiui/os/utils/AppUtil.java
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2012 www.amsoft.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.uiui.os.utils;
|
||||
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
|
||||
public class AppUtil {
|
||||
|
||||
private static String TAG = AppUtil.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* 描述:获取可用内存.
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static long getAvailMemory(Context context) {
|
||||
// 获取android当前可用内存大小
|
||||
ActivityManager activityManager = (ActivityManager) context
|
||||
.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
|
||||
activityManager.getMemoryInfo(memoryInfo);
|
||||
// 当前系统可用内存 ,将获得的内存大小规格化
|
||||
|
||||
return memoryInfo.availMem;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @return 可用的内存大小
|
||||
*/
|
||||
public static long getFreeMemory(Context context) {
|
||||
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
|
||||
activityManager.getMemoryInfo(memoryInfo);
|
||||
long freeMem = memoryInfo.totalMem - memoryInfo.availMem;
|
||||
// Log.e("getHardware", "getFreeMemory: " + freeMem);
|
||||
return freeMem;
|
||||
}
|
||||
|
||||
/**
|
||||
* 描述:总内存.
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static long getTotalMemory(Context context) {
|
||||
// 系统内存信息文件
|
||||
String file = "/proc/meminfo";
|
||||
String memInfo;
|
||||
String[] strs;
|
||||
long memory = 0;
|
||||
|
||||
try {
|
||||
FileReader fileReader = new FileReader(file);
|
||||
BufferedReader bufferedReader = new BufferedReader(fileReader, 8192);
|
||||
// 读取meminfo第一行,系统内存大小
|
||||
memInfo = bufferedReader.readLine();
|
||||
strs = memInfo.split("\\s+");
|
||||
for (String str : strs) {
|
||||
Log.e(TAG, "getTotalMemory: " + str + "\t");
|
||||
}
|
||||
// 获得系统总内存,单位KB
|
||||
memory = Integer.valueOf(strs[1]).intValue();
|
||||
bufferedReader.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Byte转位KB或MB
|
||||
return memory * 1024;
|
||||
}
|
||||
}
|
||||
72
app/src/main/java/com/uiui/os/utils/BitmapUtils.java
Normal file
72
app/src/main/java/com/uiui/os/utils/BitmapUtils.java
Normal file
@@ -0,0 +1,72 @@
|
||||
package com.uiui.os.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.drawable.AdaptiveIconDrawable;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
public class BitmapUtils {
|
||||
public static Bitmap Bytes2Bimap(byte[] b) {
|
||||
if (b.length != 0) {
|
||||
return BitmapFactory.decodeByteArray(b, 0, b.length);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] Bitmap2Bytes(Bitmap bitmap) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
|
||||
byte[] data = baos.toByteArray();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drawable转换成一个Bitmap
|
||||
*
|
||||
* @param drawable drawable对象
|
||||
* @return
|
||||
*/
|
||||
public static final Bitmap drawableToBitmap(Drawable drawable) {
|
||||
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
|
||||
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
|
||||
drawable.draw(canvas);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
|
||||
public static Bitmap drawableToBitamp(Drawable drawable) {
|
||||
Bitmap bitmap;
|
||||
BitmapDrawable bd = (BitmapDrawable) drawable;
|
||||
bitmap = bd.getBitmap();
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public static Bitmap getIconBitmap(Context context, Drawable drawable) {
|
||||
try {
|
||||
if (drawable == null) {
|
||||
return null;
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && drawable instanceof AdaptiveIconDrawable) {
|
||||
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
|
||||
drawable.draw(canvas);
|
||||
return bitmap;
|
||||
} else {
|
||||
return ((BitmapDrawable) drawable).getBitmap();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
61
app/src/main/java/com/uiui/os/utils/IconUtils.java
Normal file
61
app/src/main/java/com/uiui/os/utils/IconUtils.java
Normal file
@@ -0,0 +1,61 @@
|
||||
package com.uiui.os.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class IconUtils {
|
||||
public static List<String> appClassNameList = new ArrayList<String>() {
|
||||
{
|
||||
this.add("com.android.appstore");//应用市场
|
||||
this.add("com.android.browser");//浏览器
|
||||
this.add("com.android.calculator2");//计算器
|
||||
this.add("com.android.calendar");//日历
|
||||
this.add("com.android.camera");//相机
|
||||
this.add("com.android.camera2");//相机
|
||||
this.add("com.android.contacts");//通讯录
|
||||
this.add("com.android.deskclock");//时钟
|
||||
this.add("com.android.dialer");//电话
|
||||
this.add("com.android.dialer");//电话
|
||||
this.add("com.android.gallery3d");//图库
|
||||
this.add("com.android.mms.ui");//信息
|
||||
this.add("com.android.music");//音乐
|
||||
this.add("com.android.providers.downloads.ui");//下载
|
||||
this.add("com.android.quicksearchbox");//搜索
|
||||
this.add("com.android.settings");//设置
|
||||
this.add("com.android.soundrecorder");//录音机
|
||||
this.add("com.android.stk.StkMain");//sim卡
|
||||
this.add("com.android.vdieo");//视频
|
||||
this.add("com.mediatek.filemanager");//文件管理
|
||||
this.add("com.android.documentsui");//下载
|
||||
this.add("com.mediatek.fmradio");//收音机
|
||||
this.add("com.android.fmradio");//收音机
|
||||
this.add("com.android.email");//电子邮件
|
||||
}
|
||||
};
|
||||
public static List<String> appIconList = new ArrayList<String>() {{
|
||||
this.add("com_android_appstore");
|
||||
this.add("com_android_browser");
|
||||
this.add("com_android_calculator2");
|
||||
this.add("com_android_calendar");
|
||||
this.add("com_android_camera");
|
||||
this.add("com_android_camera");
|
||||
this.add("com_android_contacts");
|
||||
this.add("com_android_deskclock");
|
||||
this.add("com_android_dialer");
|
||||
this.add("com_android_dialer");
|
||||
this.add("com_android_gallery3d_app");
|
||||
this.add("com_android_mms_ui");
|
||||
this.add("com_android_music");
|
||||
this.add("com_android_providers_downloads_ui");
|
||||
this.add("com_android_quicksearchbox");
|
||||
this.add("com_android_settings");
|
||||
this.add("com_android_soundrecorder");
|
||||
this.add("com_android_stk_stkmain");
|
||||
this.add("com_android_vdieo");
|
||||
this.add("com_mediatek_filemanager");
|
||||
this.add("com_mediatek_filemanager");
|
||||
this.add("com_mediatek_fmradio");
|
||||
this.add("com_mediatek_fmradio");//收音机
|
||||
this.add("com_android_email");
|
||||
}};
|
||||
}
|
||||
26
app/src/main/java/com/uiui/os/utils/Utils.java
Normal file
26
app/src/main/java/com/uiui/os/utils/Utils.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package com.uiui.os.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Build;
|
||||
|
||||
public class Utils {
|
||||
/**
|
||||
* 获取电量
|
||||
*
|
||||
* @param mContext
|
||||
* @return
|
||||
*/
|
||||
synchronized public static int getBatteryLevel(Context mContext) {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
return ((BatteryManager) mContext.getSystemService(Context.BATTERY_SERVICE)).getIntProperty(4);
|
||||
} else {
|
||||
Intent intent = (new ContextWrapper(mContext)).registerReceiver(null, new IntentFilter("android.intent.action.BATTERY_CHANGED"));
|
||||
return intent.getIntExtra("level", -1) * 100 / intent.getIntExtra("scale", -1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
71
app/src/main/java/com/uiui/os/view/CustomContent.java
Normal file
71
app/src/main/java/com/uiui/os/view/CustomContent.java
Normal file
@@ -0,0 +1,71 @@
|
||||
package com.uiui.os.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.AttrRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
|
||||
public class CustomContent extends FrameLayout implements CustomContentCallbacks {
|
||||
|
||||
public CustomContent(@NonNull Context context) {
|
||||
super(context);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public CustomContent(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public CustomContent(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(context);
|
||||
}
|
||||
|
||||
private void init(Context context){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow(boolean fromResume) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollProgressChanged(float progress) {
|
||||
|
||||
}
|
||||
|
||||
// 滑到负一屏是否再允许滑动,true:允许滑动到主屏,false:不允许再滑动
|
||||
@Override
|
||||
public boolean isScrollingAllowed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewAdded(View child) {
|
||||
super.onViewAdded(child);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.uiui.os.view;
|
||||
|
||||
|
||||
// add by codemx.cn ---- 20190712 ---plus- start
|
||||
// modify by codemx.cn ---- 20190712 ---plus- start
|
||||
public interface CustomContentCallbacks {
|
||||
|
||||
// Custom content is completely shown. {@code fromResume} indicates whether this was caused
|
||||
// by a onResume or by scrolling otherwise.
|
||||
void onShow(boolean fromResume);
|
||||
|
||||
// Custom content is completely hidden
|
||||
void onHide();
|
||||
|
||||
// Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).
|
||||
void onScrollProgressChanged(float progress);
|
||||
|
||||
// Indicates whether the user is allowed to scroll away from the custom content.
|
||||
boolean isScrollingAllowed();
|
||||
|
||||
}
|
||||
176
app/src/main/java/com/uiui/os/view/MyGridLayout.java
Normal file
176
app/src/main/java/com/uiui/os/view/MyGridLayout.java
Normal file
@@ -0,0 +1,176 @@
|
||||
package com.uiui.os.view;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
|
||||
import com.uiui.os.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static android.view.View.MeasureSpec.EXACTLY;
|
||||
import static android.view.View.MeasureSpec.makeMeasureSpec;
|
||||
|
||||
/**
|
||||
* 自定义布局组件
|
||||
*
|
||||
* @author zihao
|
||||
*/
|
||||
public class MyGridLayout extends ViewGroup {
|
||||
int margin = 2;// 每个格子的水平和垂直间隔
|
||||
int colums = 4;//列数
|
||||
int rows = 3;//行数
|
||||
int count = 0;
|
||||
|
||||
private GridAdatper adapter;
|
||||
private String TAG = MyGridLayout.class.getSimpleName();
|
||||
|
||||
@SuppressLint("Recycle")
|
||||
public MyGridLayout(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
if (attrs != null) {
|
||||
TypedArray a = getContext().obtainStyledAttributes(attrs,
|
||||
R.styleable.MyGridLayout);
|
||||
margin = a.getInteger(R.styleable.MyGridLayout_itemMargin, 2);
|
||||
colums = a.getInteger(R.styleable.MyGridLayout_numColumns, 4);
|
||||
rows = a.getInteger(R.styleable.MyGridLayout_numRows, 3);
|
||||
}
|
||||
}
|
||||
|
||||
public MyGridLayout(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public MyGridLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public void setColums(int c) {
|
||||
this.colums = c;
|
||||
}
|
||||
|
||||
public void setRows(int r) {
|
||||
this.rows = r;
|
||||
}
|
||||
|
||||
public void set(int c, int r) {
|
||||
this.colums = c;
|
||||
this.rows = r;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
count = getChildCount();
|
||||
if (count == 0) {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = getChildAt(i);
|
||||
if (child.getVisibility() == GONE) {
|
||||
continue;
|
||||
}
|
||||
child.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
|
||||
}
|
||||
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
int height = b - t;// 布局区域高度
|
||||
int width = r - l;// 布局区域宽度
|
||||
// int rows = count % colums == 0 ? count / colums : count / colums + 1;// 行数
|
||||
if (count == 0)
|
||||
return;
|
||||
int gridW = (width - margin * (colums + 1)) / colums;// 格子宽度
|
||||
int gridH = (height - margin * (rows + 1)) / rows;// 格子高度
|
||||
|
||||
int left;
|
||||
int top = margin + margin / 2;
|
||||
|
||||
for (int i = 0; i < rows; i++) {// 遍历行
|
||||
for (int j = 0; j < colums; j++) {// 遍历每一行的元素
|
||||
View child = this.getChildAt(i * colums + j);
|
||||
if (child == null)
|
||||
return;
|
||||
// if (j == 0) {
|
||||
left = j * gridW + (j + 1) * margin + margin / 2;
|
||||
// } else {
|
||||
// left = j * gridW + (j + 1) * margin;
|
||||
// }
|
||||
// 如果当前布局宽度和测量宽度不一样,就直接用当前布局的宽度重新测量
|
||||
if (gridW != child.getMeasuredWidth()
|
||||
|| gridH != child.getMeasuredHeight()) {
|
||||
child.measure(makeMeasureSpec(gridW, EXACTLY),
|
||||
makeMeasureSpec(gridH, EXACTLY));
|
||||
}
|
||||
child.layout(left, top, left + gridW, top + gridH);
|
||||
// Log.e(TAG, "onLayout: left = " + left);
|
||||
// Log.e(TAG, "onLayout: top = " + top);
|
||||
// Log.e(TAG, "onLayout: right = " + left + gridW);
|
||||
// Log.e(TAG, "onLayout: bottom = " + top + gridH);
|
||||
}
|
||||
top += gridH + margin;
|
||||
}
|
||||
}
|
||||
|
||||
public interface GridAdatper {
|
||||
View getView(int index);
|
||||
|
||||
int getCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置适配器
|
||||
*/
|
||||
public void setGridAdapter(GridAdatper adapter) {
|
||||
this.adapter = adapter;
|
||||
// 动态添加视图
|
||||
int size = adapter.getCount();
|
||||
for (int i = 0; i < size; i++) {
|
||||
addView(adapter.getView(i));
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onItemClick(View v, int index);
|
||||
}
|
||||
|
||||
private ArrayList<ApplicationInfo> applicationInfos;
|
||||
|
||||
public void setApplicationInfos(ArrayList<ApplicationInfo> infoArrayList) {
|
||||
this.applicationInfos = infoArrayList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置item点击事件
|
||||
*
|
||||
* @param click
|
||||
*/
|
||||
public void setOnItemClickListener(final OnItemClickListener click) {
|
||||
if (this.adapter == null)
|
||||
return;
|
||||
for (int i = 0; i < adapter.getCount(); i++) {
|
||||
final int index = i;
|
||||
View view = getChildAt(i);
|
||||
view.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
click.onItemClick(v, index);
|
||||
}
|
||||
});
|
||||
if (applicationInfos.get(index) == null) {
|
||||
view.setClickable(false);
|
||||
} else view.setClickable(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
323
app/src/main/java/com/uiui/os/view/ScaleCircleNavigator.java
Normal file
323
app/src/main/java/com/uiui/os/view/ScaleCircleNavigator.java
Normal file
@@ -0,0 +1,323 @@
|
||||
package com.uiui.os.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PointF;
|
||||
import android.util.SparseArray;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
|
||||
import net.lucode.hackware.magicindicator.NavigatorHelper;
|
||||
import net.lucode.hackware.magicindicator.abs.IPagerNavigator;
|
||||
import net.lucode.hackware.magicindicator.buildins.ArgbEvaluatorHolder;
|
||||
import net.lucode.hackware.magicindicator.buildins.UIUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
// _oo0oo_
|
||||
// o8888888o
|
||||
// 88" . "88
|
||||
// (| -_- |)
|
||||
// 0\ = /0
|
||||
// ___/`---'\___
|
||||
// .' \\| |// '.
|
||||
// / \\||| : |||// \
|
||||
// / _||||| -:- |||||- \
|
||||
// | | \\\ - /// | |
|
||||
// | \_| ''\---/'' |_/ |
|
||||
// \ .-\__ '-' ___/-. /
|
||||
// ___'. .' /--.--\ `. .'___
|
||||
// ."" '< `.___\_<|>_/___.' >' "".
|
||||
// | | : `- \`.;`\ _ /`;.`/ - ` : | |
|
||||
// \ \ `_. \_ __\ /__ _/ .-` / /
|
||||
// =====`-.____`.___ \_____/___.-`___.-'=====
|
||||
// `=---='
|
||||
//
|
||||
//
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// 佛祖保佑 永无BUG
|
||||
|
||||
/**
|
||||
* 类似CircleIndicator的效果
|
||||
* Created by hackware on 2016/9/3.
|
||||
*/
|
||||
|
||||
public class ScaleCircleNavigator extends View implements IPagerNavigator, NavigatorHelper.OnNavigatorScrollListener {
|
||||
private int mMinRadius;
|
||||
private int mMaxRadius;
|
||||
private int mNormalCircleColor = Color.LTGRAY;
|
||||
private int mSelectedCircleColor = Color.GRAY;
|
||||
private int mCircleSpacing;
|
||||
private int mCircleCount;
|
||||
|
||||
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private List<PointF> mCirclePoints = new ArrayList<PointF>();
|
||||
private SparseArray<Float> mCircleRadiusArray = new SparseArray<Float>();
|
||||
|
||||
// 事件回调
|
||||
private boolean mTouchable;
|
||||
private ScaleCircleNavigator.OnCircleClickListener mCircleClickListener;
|
||||
private float mDownX;
|
||||
private float mDownY;
|
||||
private int mTouchSlop;
|
||||
|
||||
private boolean mFollowTouch = true; // 是否跟随手指滑动
|
||||
private NavigatorHelper mNavigatorHelper = new NavigatorHelper();
|
||||
private Interpolator mStartInterpolator = new LinearInterpolator();
|
||||
|
||||
public ScaleCircleNavigator(Context context) {
|
||||
super(context);
|
||||
init(context);
|
||||
}
|
||||
|
||||
private void init(Context context) {
|
||||
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
|
||||
mMinRadius = UIUtil.dip2px(context, 3);
|
||||
mMaxRadius = UIUtil.dip2px(context, 4);
|
||||
mCircleSpacing = UIUtil.dip2px(context, 8);
|
||||
mNavigatorHelper.setNavigatorScrollListener(this);
|
||||
mNavigatorHelper.setSkimOver(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
|
||||
}
|
||||
|
||||
private int measureWidth(int widthMeasureSpec) {
|
||||
int mode = MeasureSpec.getMode(widthMeasureSpec);
|
||||
int width = MeasureSpec.getSize(widthMeasureSpec);
|
||||
int result = 0;
|
||||
switch (mode) {
|
||||
case MeasureSpec.EXACTLY:
|
||||
result = width;
|
||||
break;
|
||||
case MeasureSpec.AT_MOST:
|
||||
case MeasureSpec.UNSPECIFIED:
|
||||
if (mCircleCount <= 0) {
|
||||
result = getPaddingLeft() + getPaddingRight();
|
||||
} else {
|
||||
result = (mCircleCount - 1) * mMinRadius * 2 + mMaxRadius * 2 + (mCircleCount - 1) * mCircleSpacing + getPaddingLeft() + getPaddingRight();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int measureHeight(int heightMeasureSpec) {
|
||||
int mode = MeasureSpec.getMode(heightMeasureSpec);
|
||||
int height = MeasureSpec.getSize(heightMeasureSpec);
|
||||
int result = 0;
|
||||
switch (mode) {
|
||||
case MeasureSpec.EXACTLY:
|
||||
result = height;
|
||||
break;
|
||||
case MeasureSpec.AT_MOST:
|
||||
case MeasureSpec.UNSPECIFIED:
|
||||
result = mMaxRadius * 2 + getPaddingTop() + getPaddingBottom();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
for (int i = 0, j = mCirclePoints.size(); i < j; i++) {
|
||||
PointF point = mCirclePoints.get(i);
|
||||
float radius = mCircleRadiusArray.get(i, (float) mMinRadius);
|
||||
mPaint.setColor(ArgbEvaluatorHolder.eval((radius - mMinRadius) / (mMaxRadius - mMinRadius), mNormalCircleColor, mSelectedCircleColor));
|
||||
canvas.drawCircle(point.x, getHeight() / 2.0f, radius, mPaint);
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareCirclePoints() {
|
||||
mCirclePoints.clear();
|
||||
if (mCircleCount > 0) {
|
||||
int y = Math.round(getHeight() / 2.0f);
|
||||
int centerSpacing = mMinRadius * 2 + mCircleSpacing;
|
||||
int startX = mMaxRadius + getPaddingLeft();
|
||||
for (int i = 0; i < mCircleCount; i++) {
|
||||
PointF pointF = new PointF(startX, y);
|
||||
mCirclePoints.add(pointF);
|
||||
startX += centerSpacing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
float x = event.getX();
|
||||
float y = event.getY();
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
if (mTouchable) {
|
||||
mDownX = x;
|
||||
mDownY = y;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (mCircleClickListener != null) {
|
||||
if (Math.abs(x - mDownX) <= mTouchSlop && Math.abs(y - mDownY) <= mTouchSlop) {
|
||||
float max = Float.MAX_VALUE;
|
||||
int index = 0;
|
||||
for (int i = 0; i < mCirclePoints.size(); i++) {
|
||||
PointF pointF = mCirclePoints.get(i);
|
||||
float offset = Math.abs(pointF.x - x);
|
||||
if (offset < max) {
|
||||
max = offset;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
mCircleClickListener.onClick(index);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
mNavigatorHelper.onPageScrolled(position, positionOffset, positionOffsetPixels);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
mNavigatorHelper.onPageSelected(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
mNavigatorHelper.onPageScrollStateChanged(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
prepareCirclePoints();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyDataSetChanged() {
|
||||
prepareCirclePoints();
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachToMagicIndicator() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachFromMagicIndicator() {
|
||||
}
|
||||
|
||||
public void setMinRadius(int minRadius) {
|
||||
mMinRadius = minRadius;
|
||||
prepareCirclePoints();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setMaxRadius(int maxRadius) {
|
||||
mMaxRadius = maxRadius;
|
||||
prepareCirclePoints();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setNormalCircleColor(int normalCircleColor) {
|
||||
mNormalCircleColor = normalCircleColor;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setSelectedCircleColor(int selectedCircleColor) {
|
||||
mSelectedCircleColor = selectedCircleColor;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setCircleSpacing(int circleSpacing) {
|
||||
mCircleSpacing = circleSpacing;
|
||||
prepareCirclePoints();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setStartInterpolator(Interpolator startInterpolator) {
|
||||
mStartInterpolator = startInterpolator;
|
||||
if (mStartInterpolator == null) {
|
||||
mStartInterpolator = new LinearInterpolator();
|
||||
}
|
||||
}
|
||||
|
||||
public void setCircleCount(int count) {
|
||||
mCircleCount = count; // 此处不调用invalidate,让外部调用notifyDataSetChanged
|
||||
mNavigatorHelper.setTotalCount(mCircleCount);
|
||||
}
|
||||
|
||||
public void setTouchable(boolean touchable) {
|
||||
mTouchable = touchable;
|
||||
}
|
||||
|
||||
public void setFollowTouch(boolean followTouch) {
|
||||
mFollowTouch = followTouch;
|
||||
}
|
||||
|
||||
public void setSkimOver(boolean skimOver) {
|
||||
mNavigatorHelper.setSkimOver(skimOver);
|
||||
}
|
||||
|
||||
public void setCircleClickListener(OnCircleClickListener circleClickListener) {
|
||||
if (!mTouchable) {
|
||||
mTouchable = true;
|
||||
}
|
||||
mCircleClickListener = circleClickListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnter(int index, int totalCount, float enterPercent, boolean leftToRight) {
|
||||
if (mFollowTouch) {
|
||||
float radius = mMinRadius + (mMaxRadius - mMinRadius) * mStartInterpolator.getInterpolation(enterPercent);
|
||||
mCircleRadiusArray.put(index, radius);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLeave(int index, int totalCount, float leavePercent, boolean leftToRight) {
|
||||
if (mFollowTouch) {
|
||||
float radius = mMaxRadius + (mMinRadius - mMaxRadius) * mStartInterpolator.getInterpolation(leavePercent);
|
||||
mCircleRadiusArray.put(index, radius);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSelected(int index, int totalCount) {
|
||||
if (!mFollowTouch) {
|
||||
mCircleRadiusArray.put(index, (float) mMaxRadius);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeselected(int index, int totalCount) {
|
||||
if (!mFollowTouch) {
|
||||
mCircleRadiusArray.put(index, (float) mMinRadius);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnCircleClickListener {
|
||||
void onClick(int index);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user