目录
一、Launcher应用的作用和重要性
二、Launcher应用的类型和分类
三、Launcher应用的架构和组件
四、Launcher应用的定制和扩展
下表为Launcher应用的作用和重要性:
作用 | 重要性 |
---|---|
1. 提供用户界面 | Launcher应用是用户与设备交互的主要界面,提供了桌面、应用程序列表和小部件等界面元素。 |
2. 启动应用程序 | 用户可以通过Launcher应用快速访问和启动已安装的应用程序,提供了快捷方式和应用程序图标。 |
3. 管理应用程序 | Launcher应用可以帮助用户管理已安装的应用程序,包括卸载、移动、隐藏应用程序等操作。 |
4. 提供个性化选项 | 用户可以通过Launcher应用进行个性化设置,如更换壁纸、调整图标样式、添加小部件等。 |
5. 提升用户体验 | 作为用户与设备的主要交互界面,Launcher应用的设计和性能直接影响用户的整体体验。 |
作为Android设备的主屏幕界面,Launcher应用提供了用户与设备交互的入口和管理功能,同时也负责启动和管理应用程序,为用户提供个性化设置选项,以提升用户体验。它是Android系统中不可或缺的一部分,对于设备的易用性和用户满意度具有重要影响。
下表为Launcher应用的类型和分类:
类型 | 描述 |
---|---|
1. 原生Launcher应用 | 由设备制造商或操作系统开发者提供的默认Launcher应用,通常包含设备特定的定制功能和界面样式。 |
2. 第三方Launcher应用 | 由第三方开发者创建的Launcher应用,可以替代原生Launcher应用,提供不同的界面风格和额外的功能。 |
3. 桌面Launcher应用 | 专注于提供桌面布局和图标管理的Launcher应用,可以让用户自定义桌面布局、添加小部件和快捷方式等。 |
4. 3D效果Launcher应用 | 具备3D动画效果和特殊视觉效果的Launcher应用,提供更炫酷的界面和交互体验。 |
5. 轻量级Launcher应用 | 精简而简洁的Launcher应用,注重性能和资源消耗的优化,适用于低端设备或对性能要求较高的用户。 |
原生Launcher应用是设备制造商或操作系统提供的默认选项,而第三方Launcher应用则由第三方开发者创建,为用户提供更多的个性化选择。桌面Launcher应用专注于桌面布局和图标管理,而3D效果Launcher应用则注重视觉效果。此外,还有轻量级Launcher应用,针对性能和资源消耗进行了优化。用户可以根据自己的需求和喜好选择适合的Launcher应用。
下表为Launcher应用的架构和组件:
架构和组件 | 描述 |
---|---|
1. Launcher框架 | 提供了整个Launcher应用的基础架构,包括界面布局、事件处理和数据管理等。 |
2. Launcher界面 | 包括主屏幕、应用抽屉、小部件等,用户通过这些界面与应用程序进行交互。 |
3. 主屏幕布局 | 用于显示应用图标、小部件和快捷方式等,用户可以在主屏幕上布置和管理自己的应用。 |
4. 应用抽屉 | 用于存放所有已安装应用的列表,用户可以通过应用抽屉访问和启动应用程序。 |
5. 小部件 | 允许用户在主屏幕上放置可交互的应用扩展,如天气、时钟、日历等。 |
6. 快捷方式 | 用户可以在主屏幕上创建快捷方式,直接打开特定的应用、联系人或操作。 |
7. 桌面壁纸 | 用户可以选择自定义的桌面壁纸,为Launcher应用增添个性化的外观。 |
8. 主题和图标包 | 允许用户更改Launcher应用的外观和图标样式,实现个性化定制。 |
9. 通知徽章 | 在应用图标上显示未读消息数量或其他通知徽章,提供快速查看和操作的功能。 |
Launcher框架提供了整个应用的基础架构,而Launcher界面包括主屏幕、应用抽屉和小部件等。用户可以通过主屏幕布局管理应用图标和快捷方式,通过应用抽屉访问所有已安装应用。小部件提供了可交互的应用扩展功能。用户还可以自定义桌面壁纸、主题和图标包来个性化Launcher应用的外观。另外,通知徽章功能可以在应用图标上显示未读消息数量或其他通知标记,方便用户快速查看和操作。
1.在launcher3的QuickstepLauncher.java中添加如下代码:
mDTMFToneEnabled = Settings.System.getInt(getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
private static final int TONE_LENGTH_INFINITE = -1;
private static final int TONE_RELATIVE_VOLUME = 80;
private static final int DIAL_TONE_STREAM_TYPE = AudioManager.STREAM_DTMF;
private static final int LONGPRESS_STAR = 0;
private boolean mDTMFToneEnabled;
private ToneGenerator mToneGenerator;
private final Object mToneGeneratorLock = new Object();
private AudioManager mAudioManager;
private long clickTime = 0;
private void playTone(int tone, int durationMs) {
// if local tone playback is disabled, just return.
if (!mDTMFToneEnabled) {
return;
}
// Also do nothing if the phone is in silent mode.
// We need to re-check the ringer mode for *every* playTone()
// call, rather than keeping a local flag that's updated in
// onResume(), since it's possible to toggle silent mode without
// leaving the current activity (via the ENDCALL-longpress menu.)
AudioManager audioManager =
(AudioManager) getSystemService(Context.AUDIO_SERVICE);
int ringerMode = audioManager.getRingerMode();
if ((ringerMode == AudioManager.RINGER_MODE_SILENT)
|| (ringerMode == AudioManager.RINGER_MODE_VIBRATE)) {
return;
}
synchronized (mToneGeneratorLock) {
if (mToneGenerator == null) {
return;
}
// Start the new tone (will stop any playing tone)
mToneGenerator.startTone(tone, durationMs);
}
}
/** Stop the tone if it is played. */
private void stopTone() {
// if local tone playback is disabled, just return.
if (!mDTMFToneEnabled) {
return;
}
synchronized (mToneGeneratorLock) {
if (mToneGenerator == null) {
return;
}
mToneGenerator.stopTone();
}
}
private void keyPressed(int keyCode) {
switch (keyCode) {
case KeyEvent.KEYCODE_1:
playTone(ToneGenerator.TONE_DTMF_1, TONE_LENGTH_INFINITE);
break;
case KeyEvent.KEYCODE_2:
playTone(ToneGenerator.TONE_DTMF_2, TONE_LENGTH_INFINITE);
break;
case KeyEvent.KEYCODE_3:
playTone(ToneGenerator.TONE_DTMF_3, TONE_LENGTH_INFINITE);
break;
case KeyEvent.KEYCODE_4:
playTone(ToneGenerator.TONE_DTMF_4, TONE_LENGTH_INFINITE);
break;
case KeyEvent.KEYCODE_5:
playTone(ToneGenerator.TONE_DTMF_5, TONE_LENGTH_INFINITE);
break;
case KeyEvent.KEYCODE_6:
playTone(ToneGenerator.TONE_DTMF_6, TONE_LENGTH_INFINITE);
break;
case KeyEvent.KEYCODE_7:
playTone(ToneGenerator.TONE_DTMF_7, TONE_LENGTH_INFINITE);
break;
case KeyEvent.KEYCODE_8:
playTone(ToneGenerator.TONE_DTMF_8, TONE_LENGTH_INFINITE);
break;
case KeyEvent.KEYCODE_9:
playTone(ToneGenerator.TONE_DTMF_9, TONE_LENGTH_INFINITE);
break;
case KeyEvent.KEYCODE_0:
playTone(ToneGenerator.TONE_DTMF_0, TONE_LENGTH_INFINITE);
break;
case KeyEvent.KEYCODE_POUND:
playTone(ToneGenerator.TONE_DTMF_P, TONE_LENGTH_INFINITE);
break;
case KeyEvent.KEYCODE_STAR:
playTone(ToneGenerator.TONE_DTMF_S, TONE_LENGTH_INFINITE);
break;
default:
break;
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
clickTime = event.getDownTime();
String number = "";
final KeyEvent.DispatcherState dispatcher = getWorkspace().getKeyDispatcherState();
switch (keyCode) {
case KeyEvent.KEYCODE_0:
case KeyEvent.KEYCODE_1:
case KeyEvent.KEYCODE_2:
case KeyEvent.KEYCODE_3:
case KeyEvent.KEYCODE_4:
case KeyEvent.KEYCODE_5:
case KeyEvent.KEYCODE_6:
case KeyEvent.KEYCODE_7:
case KeyEvent.KEYCODE_8:
case KeyEvent.KEYCODE_9:
number = String.valueOf(keyCode - 7);
break;
case KeyEvent.KEYCODE_STAR:
// number = getString(R.string.dialpad_star_number);
//Log.e(TAG, "onKeyDown event.getRepeatCount()->"+event.getRepeatCount());
if(event.getRepeatCount() == 0){
keyPressed(keyCode);
clickTime = event.getDownTime();
mHandler.sendEmptyMessageDelayed(LONGPRESS_STAR, 500);
return true;
}
break;
case KeyEvent.KEYCODE_POUND:
number = "#";
break;
default:
break;
}
if (!TextUtils.isEmpty(number)) {
keyPressed(keyCode);
/*Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + number));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);*/
if(event.getRepeatCount() == 0){
dispatcher.startTracking(event, this);
}
else if(event.isLongPress() && dispatcher.isTracking(event)){
dispatcher.performedLongPress(event);
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + number));
intent.putExtra("is_speed_dial",true);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
Log.e(TAG, "onKeyDown 2 keyCode->"+keyCode);
return true;
}
// Log.e(TAG, "onKeyDown-keyCode->" + keyCode);
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
String number = "";
if(keyCode == KeyEvent.KEYCODE_STAR){
stopTone();
clickTime = event.getEventTime() - clickTime;
//Log.e(TAG, "onKeyUp clickTime->"+clickTime);
if (clickTime < 400) {
mHandler.removeMessages(LONGPRESS_STAR);
Intent intent = new Intent(Intent.ACTION_DIAL,Uri.parse("tel:*"));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
return true;
}
else if(keyCode == KeyEvent.KEYCODE_0 ||
keyCode == KeyEvent.KEYCODE_1 ||
keyCode == KeyEvent.KEYCODE_2 ||
keyCode == KeyEvent.KEYCODE_3 ||
keyCode == KeyEvent.KEYCODE_4 ||
keyCode == KeyEvent.KEYCODE_5 ||
keyCode == KeyEvent.KEYCODE_6 ||
keyCode == KeyEvent.KEYCODE_7 ||
keyCode == KeyEvent.KEYCODE_8 ||
keyCode == KeyEvent.KEYCODE_9 ){
number = String.valueOf(keyCode - 7);
//stopTone();
}
else if(keyCode == KeyEvent.KEYCODE_POUND){
//stopTone();
number = "#";
}
if (event.isTracking() && !event.isCanceled() && !TextUtils.isEmpty(number)) {
stopTone();
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + number));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Log.e(TAG, "onKeyDown 2 keyCode->"+keyCode);
return true;
}
return super.onKeyUp(keyCode, event);
}
private Handler mHandler = new Handler(){
public void handleMessage(Message msg) {
int ringerMode = mAudioManager.getRingerMode();
if (ringerMode == AudioManager.RINGER_MODE_NORMAL) {
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
} else {
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
}
clickTime = 0;
};
};
2.在launcher3的QuickstepLauncher.java中将expandStatusBar()方法注释掉:
/*private IStatusBarService mStatusBarService;
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
{
expandStatusBar();
}
return;
}
private void expandStatusBar() {
Log.e(TAG, "expendStatusBar-->");
if (mStatusBarService == null) {
mStatusBarService = IStatusBarService.Stub.asInterface(ServiceManager.getService("statusbar"));
}
if (mStatusBarService != null) {
try {
mStatusBarService.expandNotificationsPanel();
} catch (RemoteException e) {
// do nothing.
}
}
}*/
3.在Launcher3中的devices_profile.xml修改成4x4的排列布局:
4.1 在MainActivity.java中添加接受广播的方法用于监听dialer,如下代码:
private IntentFilter intentFilter;
private CallSmsChangeReceiver mCallSmsChangeReceiver;
public class CallSmsChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ComponentName CallSmsComponentName = intent.getParcelableExtra("component_name");
int changeCount = intent.getIntExtra("unread_number", 0);
Log.d(TAG, "onReceive: " + CallSmsComponentName.getClassName());
Log.d(TAG, "onReceive: " + changeCount);
if (CallSmsComponentName.getPackageName().contains("dialer")) {
// CallSmsComponentName.getPackageName() = com.android.dialer.app.DialtactsActivity
setMmsOrPhoneNum(CALL_PAKNAME, changeCount);
} else if (CallSmsComponentName.getPackageName().equals(MMS_PAKNAME)) {
setMmsOrPhoneNum(MMS_PAKNAME, changeCount);
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
isFirstStart = true;
Log.e(TAG, "SimpleLauncher onCreate--isFirstStart-->" + isFirstStart);
/*call sms*/
intentFilter = new IntentFilter();
intentFilter.addAction("xx.xxxxxx.launcher.action.UNREAD_CHANGED");
mCallSmsChangeReceiver = new CallSmsChangeReceiver();
registerReceiver(mCallSmsChangeReceiver, intentFilter);
mLauncherApps = (LauncherApps) getSystemService(Context.LAUNCHER_APPS_SERVICE);
mainLayout = findViewById(R.id.main_layout);
mPagedView = (PagedView) findViewById(R.id.pageView);
parentView = findViewById(R.id.launcher);
mPagedView.initParentViews(parentView);
defaultView = mPagedView.getChildAt(0);
defaultView.setOnKeyListener(mOnkeyListener);
mFocusHelper = new ViewGroupFocusHelper(parentView);
allAppBtn = (Button) findViewById(R.id.all_app_btn);
// allContactsBtn = (Button) findViewById(R.id.all_contacts_btn);
allAppBtn.setOnKeyListener(mOnkeyListener);
allAppBtn.setOnClickListener(moreBtnListener);
/*allContactsBtn.setOnKeyListener(mOnkeyListener);
allContactsBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setComponent(
new ComponentName("com.android.contacts", "com.android.contacts.activities.PeopleActivity"));
startActivity(intent);
}
});*/
allApp_layout = findViewById(R.id.allapp_layout);
allApp = (ListView) findViewById(R.id.all_app);
mDTMFToneEnabled =
Settings.System.getInt(getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
mAppItemAdapter = new AppItemAdapter(MainActivity.this, new ArrayList());
new AppItemTask(this).execute();
mLauncherApps.registerCallback(new Callback() {
@Override
public void onPackagesUnavailable(String[] packageNames, UserHandle user, boolean replacing) {
// TODO Auto-generated method stub
}
@Override
public void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing) {
// TODO Auto-generated method stub
}
@Override
public void onPackageRemoved(String packageName, UserHandle user) {
// TODO Auto-generated method stub
Log.e(TAG, "onPackageRemoved");
new AppItemTask(MainActivity.this).execute();
}
@Override
public void onPackageChanged(String packageName, UserHandle user) {
// TODO Auto-generated method stub
Log.e(TAG, "onPackageChanged");
new AppItemTask(MainActivity.this).execute();
}
@Override
public void onPackageAdded(String packageName, UserHandle user) {
// TODO Auto-generated method stub
Log.e(TAG, "onPackageAdded");
new AppItemTask(MainActivity.this).execute();
}
});
initDefaultPage();
initAppMap();
initAppItems();
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
}
// call sms
final private int REQUEST_CODE_ASK_PERMISSIONS = 123;
private static final String[] SMS_PROJECTION = new String[]{
BaseColumns._ID,
Telephony.Sms.THREAD_ID,
};
private static final String[] MMS_PROJECTION = new String[]{
BaseColumns._ID,
Telephony.Mms.THREAD_ID,
};
private int getMissMmsCount() {
int missSmsCount = 0;
int missMmsCount = 0;
int missMsgCount = 0;
Cursor cursorSMS = null;
Cursor cursorMMS = null;
try {
cursorSMS = getContentResolver().query(
Uri.parse("content://sms/"), SMS_PROJECTION, "(read=0)",
null, null);
cursorMMS = getContentResolver().query(
Uri.parse("content://mms/"), MMS_PROJECTION, "(read=0)", null,
null);
} catch (SQLiteException e) {
return missSmsCount;
}
if (cursorSMS != null) {
missSmsCount = cursorSMS.getCount();
cursorSMS.close();
}
if (cursorMMS != null) {
missMmsCount = cursorMMS.getCount();
cursorMMS.close();
}
missMsgCount = missSmsCount + missMmsCount;
Log.i(TAG, "getMissMmsCount " + missMsgCount);
return missMsgCount;
}
private int getMissCallCount() {
int missCallCount = 0;
Uri missingCallUri = CallLog.Calls.CONTENT_URI;
// modify begin
//String where = Calls.TYPE + " = '" + Calls.MISSED_TYPE + "'"
// + " AND new=1";
String where = CallLog.Calls.IS_READ + "=0"
+ " AND new=1";
// modify end
Cursor cursorCall = null;
try {
cursorCall = getContentResolver().query(missingCallUri,
null, where, null, null);
} catch (SQLiteException e) {
return missCallCount;
}
if (cursorCall != null) {
missCallCount = cursorCall.getCount();
cursorCall.close();
}
Log.i(TAG, "getMissCallCount: " + missCallCount);
return missCallCount;
}
private static final String CALL_PAKNAME="org.codeaurora.dialer";
private static final String MMS_PAKNAME="com.android.mms";
private void setMmsOrPhoneNum(final String pkgName, final int missCount) {
// Drawable drawable1= ContextCompat.getDrawable(getBaseContext(), R.drawable.dialer_bg);
for(int i=0; i<6; i++){
if(mItems[i].getPkgName().equals(pkgName)){
AppItem appItem = mItems[i];
Log.d(TAG, "setMmsOrPhoneNum: "+appItem.getPkgName());
if(pkgName.equals(CALL_PAKNAME)){
StateListDrawable drawable1 = new StateListDrawable();
Bitmap defaultIconBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.dial);
Bitmap defaultIconBitmapFocused = BitmapFactory.decodeResource(getResources(),R.drawable.dial_selected);
Bitmap bitmap = Utils.createIconBitmap(defaultIconBitmap, missCount);
Bitmap bitmapFocused = Utils.createIconBitmap(defaultIconBitmapFocused, missCount);
Drawable drawable=new BitmapDrawable(getResources(),bitmap);
Drawable drawableFocused=new BitmapDrawable(getResources(),bitmapFocused);
drawable1.addState(new int[]{android.R.attr.state_focused}, drawableFocused);
drawable1.addState(new int[]{-android.R.attr.state_focused}, drawable);
appItem.setBackground(drawable1);
break;
}else if(pkgName.equals(MMS_PAKNAME)){
StateListDrawable drawable2 = new StateListDrawable();
Bitmap defaultIconBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.sms);
Bitmap defaultIconBitmapFocused = BitmapFactory.decodeResource(getResources(),R.drawable.sms_selected);
Bitmap bitmap = Utils.createIconBitmap(defaultIconBitmap, missCount);
Bitmap bitmapFocused = Utils.createIconBitmap(defaultIconBitmapFocused, missCount);
Drawable drawable=new BitmapDrawable(getResources(),bitmap);
Drawable drawableFocused=new BitmapDrawable(getResources(),bitmapFocused);
drawable2.addState(new int[]{android.R.attr.state_focused}, drawableFocused);
drawable2.addState(new int[]{-android.R.attr.state_focused}, drawable);
appItem.setBackground(drawable2);
break;
}
}
}
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
mPagedView.pageEndMoving();
Log.e(TAG, "onResume isFirstStart->"+isFirstStart);
if(isFirstStart){
mPagedView.setCurrentPage(DEFAULT_PAGE);
defaultView.setSelected(true);
defaultView.requestFocus();
isFirstStart = false;
}
if(mainLayout.getVisibility() != View.VISIBLE) {
//Log.e(TAG,"getSelectedPosition->"+mAppItemAdapter.getSelectedPosition()+",getFirstVisiblePosition->"+allApp.getFirstVisiblePosition());
View selectedItemView = allApp.getChildAt(mAppItemAdapter.getSelectedPosition()-allApp.getFirstVisiblePosition());
selectedItemView.postDelayed(new Runnable() {
@Override
public void run() {
selectedItemView.requestFocus();
}
}, 300);
}
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unregisterReceiver(receiver);
/*sms call*/
unregisterReceiver(mCallSmsChangeReceiver);
}
private View.OnClickListener contactItemListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
ContactItem contactItem = (ContactItem) v;
if (contactItem.isSetContact()) {
startActivity(contactItem.getIntent());
} else {
startActivityForResult(getDialShortcut(), Integer.parseInt(contactItem.getKey()));
}
}
};
private OnLongClickListener contactItemLongClickListener = new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
ContactItem item = (ContactItem) v;
String key = item.getKey();
if (mHashMap.get(key) != null) {
currentContactKey = key;
confirm_what = SHOW_DELETE_CONTACT_DIALOG;
ShowConfirmDialog2(SHOW_DELETE_CONTACT_DIALOG);
}
return true;
}
};
private void initAppItems() {
mItem0 = (AppItem) findViewById(R.id.app0);
mItem1 = (AppItem) findViewById(R.id.app1);
mItem2 = (AppItem) findViewById(R.id.app2);
mItem3 = (AppItem) findViewById(R.id.app3);
mItem4 = (AppItem) findViewById(R.id.app4);
mItem5 = (AppItem) findViewById(R.id.app5);
mItems[0] = mItem0;
mItems[1] = mItem1;
mItems[2] = mItem2;
mItems[3] = mItem3;
mItems[4] = mItem4;
mItems[5] = mItem5;
SharedPreferences sp = getSharedPreferences(Utils.PREFRENCE_NAME, MODE_PRIVATE);
String item0_info = sp.getString(Utils.ITEM0, Utils.ITEM0_INF0);
String item1_info = sp.getString(Utils.ITEM1, Utils.ITEM0_INF1);
String item2_info = sp.getString(Utils.ITEM2, Utils.ITEM0_INF2);
String item3_info = sp.getString(Utils.ITEM3, Utils.ITEM0_INF3);
String item4_info = sp.getString(Utils.ITEM4, Utils.ITEM0_INF4);
String item5_info = sp.getString(Utils.ITEM5, Utils.ITEM0_INF5);
PackageManager pm = getPackageManager();
for (int i = 0; i < 6; i++) {
String item_info = sp.getString(Utils.ITEM + i, Utils.ITEM_INFOS[i]);
String[] shortCutInfos = item_info.split("\\|");
String pkgName = shortCutInfos[0];
String clsName = shortCutInfos[1];
String lable = "";
try {
ActivityInfo activityInfo = pm.getActivityInfo(new ComponentName(pkgName, clsName), 0);
lable = activityInfo.loadLabel(pm).toString();
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
AppItem item = mItems[i];
item.setText(lable);
item.setIndex(i);
item.setPkgName(shortCutInfos[0]);
item.setClsName(shortCutInfos[1]);
/*call sms*/
if(pkgName.equals(MMS_PAKNAME)){
setMmsOrPhoneNum(MMS_PAKNAME, getMissMmsCount());
}else if(pkgName.equals(CALL_PAKNAME)){
setMmsOrPhoneNum(CALL_PAKNAME, getMissCallCount());
}else if(clsName.equals(SHORTCUT_CLASSNAME)){
item.setBackgroundResource(R.drawable.shortcut_bg);
}else if(clsName.equals(MODESETTING_CLASSNAME)){
item.setBackgroundResource(R.drawable.mode_set_bg);
} else {
item.setBackgroundResource(appMap.get(shortCutInfos[0]));
}
item.setOnClickListener(appClickListener);
item.setOnLongClickListener(appLongClickListener);
}
mItem0.setOnKeyListener(mOnkeyListener);
mItem1.setOnKeyListener(mOnkeyListener);
mItem2.setOnKeyListener(mOnkeyListener);
mItem3.setOnKeyListener(mOnkeyListener);
mItem4.setOnKeyListener(mOnkeyListener);
mItem5.setOnKeyListener(mOnkeyListener);
}
private void updateAppItem(String pkgName, String clsName) {
if (whichItem == -1)
{
return;
}
// Add begin
if(!appMap.containsKey(pkgName) && !pkgName.equals("com.xxx.shortcut")) {
Toast.makeText(MainActivity.this, R.string.can_not_setapp, Toast.LENGTH_LONG).show();
return;
}
AppItem appItem = mItems[whichItem];
appItem.setPkgName(pkgName);
appItem.setClsName(clsName);
SharedPreferences sp = getSharedPreferences(Utils.PREFRENCE_NAME, MODE_PRIVATE);
String key = Utils.ITEM0;
switch (whichItem) {
case 0:
key = Utils.ITEM0;
break;
case 1:
key = Utils.ITEM1;
break;
case 2:
key = Utils.ITEM2;
break;
case 3:
key = Utils.ITEM3;
break;
case 4:
key = Utils.ITEM4;
break;
case 5:
key = Utils.ITEM5;
break;
}
PackageManager pm = getPackageManager();
try {
ActivityInfo activityInfo = pm.getActivityInfo(new ComponentName(pkgName, clsName), 0);
appItem.setText(activityInfo.loadLabel(pm).toString());
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/* call sms*/
if(pkgName.equals(MMS_PAKNAME)){
setMmsOrPhoneNum(MMS_PAKNAME, getMissMmsCount());
}else if(pkgName.equals(CALL_PAKNAME)){
setMmsOrPhoneNum(CALL_PAKNAME, getMissCallCount());
Log.d(TAG, "updateAppItem: "+appItem.getPkgName());
Log.d(TAG, "updateAppItem: "+getMissCallCount());
}else if(clsName.equals(SHORTCUT_CLASSNAME)){
appItem.setBackgroundResource(R.drawable.shortcut_bg);
}else if(clsName.equals(MODESETTING_CLASSNAME)){
appItem.setBackgroundResource(R.drawable.mode_set_bg);
}else {
// lzx
appItem.setBackgroundResource(appMap.get(pkgName));
}
sp.edit().putString(key, pkgName + "|" + clsName).commit();
}
// add begin
private View.OnClickListener appClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
AppItem item = (AppItem) v;
try {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setComponent(new ComponentName(item.getPkgName(), item.getClsName()));
startActivity(intent);
}catch (ActivityNotFoundException e){
e.printStackTrace();
}
}
};
//add end
4.2 在Utils.java中添加绘图的方法用于显示未读数的图标,如下代码:
/*call sms*/
public static Bitmap createIconBitmap(Bitmap b, int count) {
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888,true);
if (count == 0) return b;
int textureWidth = bitmap.getWidth();
final Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);
canvas.setBitmap(bitmap);
paint.setColor(Color.RED);
Paint countPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);
countPaint.setColor(Color.WHITE);
countPaint.setTextSize(35f);
countPaint.setTypeface(Typeface.DEFAULT_BOLD);
float x = textureWidth - 24-25;
if (count > 0 && count<10) {
canvas.drawCircle(textureWidth - 17-10, 16+10, 16+10, paint);
String text = String.valueOf(count);
canvas.drawText(text, x+12, 25+14, countPaint);
}else if (count > 99) {
RectF oval2 = new RectF(textureWidth-2*(15+25),0,textureWidth,2*(16+10));
canvas.drawRoundRect(oval2,15+5,15+5, paint);
String text = String.valueOf(99) + "+";
canvas.drawText(text, x-20, 25+14, countPaint);
} else {
RectF oval2 = new RectF(textureWidth-2*(15+15),0,textureWidth,2*(16+10));
canvas.drawRoundRect(oval2,15+5,15+5, paint);
String text = String.valueOf(count);
canvas.drawText(text, x-1, 25+14, countPaint);
}
return bitmap;
}
5. 在MainActivity.java中继承WallpaperColorInfo.OnChangeListener,并实现监听方法
private TextView mWeekTextView;
private int mDefaultTextColor;
private void initDefaultPage() {
mDiagitalClock = (TextClock) findViewById(R.id.digital_clock);
mDiagitalClock.setVisibility(View.VISIBLE);
// mDiagitalClock.setTimeZone(cityTimeZoneId);
mDiagitalClock.setFormat12Hour(Utils.get12ModeFormat(0.228f /* amPmRatio */, false));
mDiagitalClock.setFormat24Hour(Utils.get24ModeFormat());
date = (TextView) findViewById(R.id.date);
mWeekTextView = (TextView) findViewById(R.id.week);
WallpaperColorInfo.INSTANCE.get(this).addOnChangeListener(this);
updateDefaultPageTextColor();
setDateView();
findViewById(R.id.default_page).setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
try {
Intent i = new Intent();
i.setClassName("com.android.wallpaperpicker", "com.android.wallpaperpicker.WallpaperPickerActivity");
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}catch (Exception e){
e.printStackTrace();
}
return true;
}
});
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_DATE_CHANGED);
intentFilter.addAction(Intent.ACTION_TIME_CHANGED);
intentFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
registerReceiver(receiver, intentFilter);
}
private void setDateView(){
final Locale l = Locale.getDefault();
final String datePattern = DateFormat.getBestDateTimePattern(l, getString(R.string.date_formater));
final String weekPattern = DateFormat.getBestDateTimePattern(l, getString(R.string.week_formater));
final String descriptionPattern = DateFormat.getBestDateTimePattern(l,
getString(R.string.full_wday_month_day_no_year));
final Date now = new Date();
date.setText(new SimpleDateFormat(datePattern, l).format(now));
date.setContentDescription(new SimpleDateFormat(descriptionPattern, l).format(now));
mWeekTextView = (TextView) findViewById(R.id.week);
mWeekTextView.setText(new SimpleDateFormat(weekPattern, l).format(now));
}
@Override
public void onExtractedColorsChanged(WallpaperColorInfo wallpaperColorInfo) {
updateDefaultPageTextColor();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
updateDefaultPageTextColor();
}
private void updateDefaultPageTextColor() {
int textColor = WallpaperColorInfo.getTextColor(this);
if (mDefaultTextColor != WallpaperColorInfo.getTextColor(this)) {
mDefaultTextColor = textColor;
if(mDiagitalClock != null){
mDiagitalClock.setTextColor(mDefaultTextColor);
}
if(date != null){
date.setTextColor(mDefaultTextColor);
}
if(mWeekTextView != null){
mWeekTextView.setTextColor(mDefaultTextColor);
}
}
}
本文仅代表个人观点和经验,难免存在不足之处。如果有任何错误或改进的建议,欢迎指正和交流,共同进步。