系统应用篇(二)--Launcher篇

目录

一、Launcher应用的作用和重要性

二、Launcher应用的类型和分类

三、Launcher应用的架构和组件

四、Launcher应用的定制和扩展


一、Launcher应用的作用和重要性

下表为Launcher应用的作用和重要性:

作用 重要性
1. 提供用户界面 Launcher应用是用户与设备交互的主要界面,提供了桌面、应用程序列表和小部件等界面元素。
2. 启动应用程序 用户可以通过Launcher应用快速访问和启动已安装的应用程序,提供了快捷方式和应用程序图标。
3. 管理应用程序 Launcher应用可以帮助用户管理已安装的应用程序,包括卸载、移动、隐藏应用程序等操作。
4. 提供个性化选项 用户可以通过Launcher应用进行个性化设置,如更换壁纸、调整图标样式、添加小部件等。
5. 提升用户体验 作为用户与设备的主要交互界面,Launcher应用的设计和性能直接影响用户的整体体验。

        作为Android设备的主屏幕界面,Launcher应用提供了用户与设备交互的入口和管理功能,同时也负责启动和管理应用程序,为用户提供个性化设置选项,以提升用户体验。它是Android系统中不可或缺的一部分,对于设备的易用性和用户满意度具有重要影响。


二、Launcher应用的类型和分类

下表为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应用的架构和组件

下表为Launcher应用的架构和组件:

架构和组件 描述
1. Launcher框架 提供了整个Launcher应用的基础架构,包括界面布局、事件处理和数据管理等。
2. Launcher界面 包括主屏幕、应用抽屉、小部件等,用户通过这些界面与应用程序进行交互。
3. 主屏幕布局 用于显示应用图标、小部件和快捷方式等,用户可以在主屏幕上布置和管理自己的应用。
4. 应用抽屉 用于存放所有已安装应用的列表,用户可以通过应用抽屉访问和启动应用程序。
5. 小部件 允许用户在主屏幕上放置可交互的应用扩展,如天气、时钟、日历等。
6. 快捷方式 用户可以在主屏幕上创建快捷方式,直接打开特定的应用、联系人或操作。
7. 桌面壁纸 用户可以选择自定义的桌面壁纸,为Launcher应用增添个性化的外观。
8. 主题和图标包 允许用户更改Launcher应用的外观和图标样式,实现个性化定制。
9. 通知徽章 在应用图标上显示未读消息数量或其他通知徽章,提供快速查看和操作的功能。

        Launcher框架提供了整个应用的基础架构,而Launcher界面包括主屏幕、应用抽屉和小部件等。用户可以通过主屏幕布局管理应用图标和快捷方式,通过应用抽屉访问所有已安装应用。小部件提供了可交互的应用扩展功能。用户还可以自定义桌面壁纸、主题和图标包来个性化Launcher应用的外观。另外,通知徽章功能可以在应用图标上显示未读消息数量或其他通知标记,方便用户快速查看和操作。


四、Launcher应用的定制和扩展

  1. 添加Launcher界面点击数字按键进拨号盘
  2. 去掉返回滑出下拉通知栏
  3. 修改桌面的APP排列为4X4,allapp界面3X3
  4. 在新开发的Launcher上添加电话和短信右上角显示未读数的功能
  5. 调整SimpleLauncher应用按钮字体颜色和状态栏颜色跟随主题变化

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);
			}
        }
    }
	

本文仅代表个人观点和经验,难免存在不足之处。如果有任何错误或改进的建议,欢迎指正和交流,共同进步。

你可能感兴趣的:(android基础,android,java)