本文将介绍获取应用程序的NotifyIcon矩形?的详细情况,特别是关于获取应用软件的方法的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于andro
本文将介绍获取应用程序的NotifyIcon矩形?的详细情况,特别是关于获取应用软件的方法的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于android-如何获取应用程序的程序包名称,然后使用Intent启动该应用程序?、Android5.0以下 源码分析Notification的notify、ApplicationInfo-Android动态获取包名-Android获取所有的应用程序信息-Android获取应用程序的占用空间大小-Android应用程序管理系列(三)、C# NotifyIcon 托盘控件的知识。
本文目录一览:- 获取应用程序的NotifyIcon矩形?(获取应用软件的方法)
- android-如何获取应用程序的程序包名称,然后使用Intent启动该应用程序?
- Android5.0以下 源码分析Notification的notify
- ApplicationInfo-Android动态获取包名-Android获取所有的应用程序信息-Android获取应用程序的占用空间大小-Android应用程序管理系列(三)
- C# NotifyIcon 托盘控件
获取应用程序的NotifyIcon矩形?(获取应用软件的方法)
我想知道我的NotifyIcon在系统托盘中的位置(在执行任何点击之前)。
在另外一个问题中, 汉斯·帕斯坦(Hans Passant)发表了一个评论:“ 不 ,这是不可能的,但是我认为几乎所有可以由操作系统内部完成的事情都可以由开发者复制,如果我不对, SO可以通过NotifyIcon来显示popup窗口吗?
在上面的同一个问题中,有一个C#示例说明了如何定位systemtray矩形,我想知道这是否是一个开始。
这个任务可以实现吗?
无法build立应用程序安装程序
VS2017 8.1SDK与独立安装程序不同吗?
将exe指向可执行文件目录之外的dll
如何在.NET中侦听Windows广播消息?
如何使用2个第三方.net库时,他们的非托pipe依赖冲突?
如果是,那么如何?
如果没有,为什么操作系统可以? 我们以什么方式限制不能再现相同的事物?
MSBuild不能build立一个MSI。 是否有Windows服务的替代品?
如何模块化PowerShell脚本
创buildWindows用户编程,不用硬编码密码
Directory.GetFilesfind不存在的文件
XP和Vista在桌面上显示什么分辨率的.ico文件?
你需要这些声明:
public const Int32 WM_MYMESSAGE = 0x8000; //WM_APP public const Int32 NOTIFYICON_VERSION_4 = 0x4; //messages public const Int32 WM_CONTEXTMENU = 0x7B; public const Int32 NIN_BALLOONHIDE = 0x403; public const Int32 NIN_BALLOONSHOW = 0x402; public const Int32 NIN_BALLOONTIMEOUT = 0x404; public const Int32 NIN_BALLOONUSERCLICK = 0x405; public const Int32 NIN_KEYSELECT = 0x403; public const Int32 NIN_SELECT = 0x400; public const Int32 NIN_POPUPOPEN = 0x406; public const Int32 NIN_POPUPCLOSE = 0x407; public const Int32 NIIF_USER = 0x4; public const Int32 NIIF_NONE = 0x0; public const Int32 NIIF_INFO = 0x1; public const Int32 NIIF_WARNING = 0x2; public const Int32 NIIF_ERROR = 0x3; public const Int32 NIIF_LARGE_ICON = 0x20; public enum NotifyFlags { NIF_MESSAGE = 0x01,NIF_ICON = 0x02,NIF_TIP = 0x04,NIF_INFO = 0x10,NIF_STATE = 0x08,NIF_GUID = 0x20,NIF_SHOWTIP = 0x80 } public enum NotifyCommand { NIM_ADD = 0x0,NIM_DELETE = 0x2,NIM_MODIFY = 0x1,NIM_SETVERSION = 0x4} [StructLayout(LayoutKind.Sequential)] public struct NOTIFYICONDATA { public Int32 cbSize; public IntPtr hWnd; public Int32 uID; public NotifyFlags uFlags; public Int32 uCallbackMessage; public IntPtr hIcon; [MarshalAs(UnmanagedType.ByValTStr,SizeConst = 128)] public String szTip; public Int32 dwState; public Int32 dwStateMask; [MarshalAs(UnmanagedType.ByValTStr,SizeConst = 256)] public String szInfo; public Int32 uVersion; [MarshalAs(UnmanagedType.ByValTStr,SizeConst = 64)] public String szInfoTitle; public Int32 dwInfoFlags; public Guid guidItem; //> IE 6 public IntPtr hBalloonIcon; } [DllImport("shell32.dll")] public static extern system.int32 Shell_NotifyIcon(NotifyCommand cmd,ref NOTIFYICONDATA data); [StructLayout(LayoutKind.Sequential)] public struct RECT { public Int32 left; public Int32 top; public Int32 right; public Int32 bottom; } [StructLayout(LayoutKind.Sequential)] public struct NOTIFYICONIDENTIFIER { public Int32 cbSize; public IntPtr hWnd; public Int32 uID; public Guid guidItem; } //Works with Shell32.dll (version 6.1 or later) [DllImport("shell32.dll",SetLastError = true)] public static extern int Shell_NotifyIconGetRect([In]ref NOTIFYICONIDENTIFIER identifier,[Out]out RECT iconLocation);
添加图标:
//you only need this guid to identify your icon private Guid guid; //call only once to set the icon and create the guid. private void AddIcon() { guid = Guid.NewGuid(); NOTIFYICONDATA data = new NOTIFYICONDATA(); data.cbSize = Marshal.SizeOf(data); data.hWnd = this.Handle; data.guidItem = guid; data.uCallbackMessage = WM_MYMESSAGE; //This is the message sent to our app data.hIcon = Properties.Resources.myIcon; data.szTip = "Your text"; data.uFlags = NotifyFlags.NIF_ICON | NotifyFlags.NIF_GUID | NotifyFlags.NIF_MESSAGE | NotifyFlags.NIF_TIP | NotifyFlags.NIF_SHOWTIP; Shell_NotifyIcon(NotifyCommand.NIM_ADD,ref data); data.uVersion = NOTIFYICON_VERSION_4; Shell_NotifyIcon(NotifyCommand.NIM_SETVERSION,ref data); }
获取图标在屏幕坐标中的位置:
private void GetRectIcon() { RECT rect = new RECT(); NOTIFYICONIDENTIFIER notifyIcon = new NOTIFYICONIDENTIFIER(); notifyIcon.cbSize = Marshal.SizeOf(notifyIcon); //only guid is needed notifyIcon.guidItem = guid; int hresult = Shell_NotifyIconGetRect(ref notifyIcon,out rect); //rect Now has the position and size of icon }
要删除通知图标:
private void DeleteIcon() { NOTIFYICONDATA data = new NOTIFYICONDATA(); data.cbSize = Marshal.SizeOf(data); data.uFlags = NotifyFlags.NIF_GUID; data.guidItem = guid; Shell_NotifyIcon(NotifyCommand.NIM_DELETE,ref data); }
要添加一个气球
private void AddBalloon() { NOTIFYICONDATA data; data = new NOTIFYICONDATA(); data.cbSize = Marshal.SizeOf(data); data.guidItem = guid; //Set custom icon for balloon or NIIF_NONE for no icon. You can use all the other //NIIF_... for system icons data.dwInfoFlags = NIIF_USER; data.hBalloonIcon = Properties.Resources.myNewIcon; //text in balloon data.szInfo = "My text in balloon"; //balloon title data.szInfoTitle = "Balloon title"; //set the flags to be modified data.uFlags = NotifyFlags.NIF_INFO | NotifyFlags.NIF_SHOWTIP | NotifyFlags.NIF_GUID; Shell_NotifyIcon(NotifyCommand.NIM_MODIFY,ref data); }
捕捉消息
protected override void WndProc(ref Message m) { if (m.Msg == WM_MYMESSAGE) { //(Int32)m.LParam & 0x0000FFFF get the low 2 bytes of LParam,we dont need the high ones. //(Int32)m.WParam & 0x0000FFFF is the X coordinate and //((Int32)m.WParam & 0xFFFF0000) >> 16 the Y switch ((Int32)m.LParam & 0x0000FFFF) { case NIN_BALLOONHIDE: break; case NIN_BALLOONSHOW: break; case NIN_BALLOONTIMEOUT: break; case NIN_BALLOONUSERCLICK: //user clicked on balloon break; case NIN_SELECT: //user left click on icon break; case WM_CONTEXTMENU: //user right click on icon break; //get what mouse messages you want //case WM_LBUTTONDOWN: //.... default: break; } } base.WndProc(ref m); }
非托管代码的威力
随着γηράσκωδ'αείπολλάδιδ的答案的帮助下,我能够找到一个解决方案,让您使用标准的NotifyIcon控件来确定图标的位置。 它需要使用反射,因为它必须访问私有字段,因此依赖于NotifyIcon类的当前实现。 我用.NET Framework 2.0和4.0测试了它。
using System; using System.Reflection; using System.Windows.Forms; using System.Runtime.InteropServices; sealed class NotifyIconHelper { public static Rectangle GetIconRect(NotifyIcon icon) { RECT rect = new RECT(); NOTIFYICONIDENTIFIER notifyIcon = new NOTIFYICONIDENTIFIER(); notifyIcon.cbSize = Marshal.SizeOf(notifyIcon); //use hWnd and id of NotifyIcon instead of guid is needed notifyIcon.hWnd = GetHandle(icon); notifyIcon.uID = GetId(icon); int hresult = Shell_NotifyIconGetRect(ref notifyIcon,out rect); //rect Now has the position and size of icon return new Rectangle(rect.left,rect.top,rect.right - rect.left,rect.bottom - rect.top); } [StructLayout(LayoutKind.Sequential)] private struct RECT { public Int32 left; public Int32 top; public Int32 right; public Int32 bottom; } [StructLayout(LayoutKind.Sequential)] private struct NOTIFYICONIDENTIFIER { public Int32 cbSize; public IntPtr hWnd; public Int32 uID; public Guid guidItem; } [DllImport("shell32.dll",SetLastError = true)] private static extern int Shell_NotifyIconGetRect([In]ref NOTIFYICONIDENTIFIER identifier,[Out]out RECT iconLocation); private static FieldInfo windowField = typeof(NotifyIcon).GetField("window",Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance); private static IntPtr GetHandle(NotifyIcon icon) { if (windowField == null) throw new InvalidOperationException("[Useful error message]"); NativeWindow window = windowField.GetValue(icon) as NativeWindow; if (window == null) throw new InvalidOperationException("[Useful error message]"); // should not happen? return window.Handle; } private static FieldInfo idField = typeof(NotifyIcon).GetField("id",Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance); private static int GetId(NotifyIcon icon) { if (idField == null) throw new InvalidOperationException("[Useful error message]"); return (int)idField.GetValue(icon); } }
android-如何获取应用程序的程序包名称,然后使用Intent启动该应用程序?
我正在开发一个Android应用程序.在该应用程序中,有一个按钮可以转到另一个活动,其中包含手机上已安装的应用程序的列表.当用户选择一个应用程序时,将保存其程序包名称,并返回上一个活动.但是,如何获得软件包名称?
public class LoaderCustomSupport extends SherlockFragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager fm = getSupportFragmentManager();
// Create the list fragment and add it as our sole content.
if (fm.findFragmentById(android.R.id.content) == null) {
AppListFragment list = new AppListFragment();
fm.beginTransaction().add(android.R.id.content, list).commit();
}
}
/**
* This class holds the per-item data in our Loader.
*/
public static class AppEntry {
public AppEntry(AppListLoader loader, ApplicationInfo info) {
mloader = loader;
mInfo = info;
mApkFile = new File(info.sourceDir);
}
public ApplicationInfo getApplicationInfo() {
return mInfo;
}
public String getLabel() {
return mLabel;
}
public Drawable getIcon() {
if (mIcon == null) {
if (mApkFile.exists()) {
mIcon = mInfo.loadIcon(mloader.mPm);
return mIcon;
} else {
mMounted = false;
}
} else if (!mMounted) {
// If the app wasn't mounted but is Now mounted, reload
// its icon.
if (mApkFile.exists()) {
mMounted = true;
mIcon = mInfo.loadIcon(mloader.mPm);
return mIcon;
}
} else {
return mIcon;
}
return mloader.getContext().getResources().getDrawable(
android.R.drawable.sym_def_app_icon);
}
@Override
public String toString() {
return mLabel;
}
void loadLabel(Context context) {
if (mLabel == null || !mMounted) {
if (!mApkFile.exists()) {
mMounted = false;
mLabel = mInfo.packageName;
} else {
mMounted = true;
CharSequence label = mInfo.loadLabel(context.getPackageManager());
mLabel = label != null ? label.toString() : mInfo.packageName;
}
}
}
private final AppListLoader mloader;
private final ApplicationInfo mInfo;
private final File mApkFile;
private String mLabel;
private Drawable mIcon;
private boolean mMounted;
}
/**
* Perform alphabetical comparison of application entry objects.
*/
public static final Comparator<AppEntry> ALPHA_COMParaTOR = new Comparator<AppEntry>() {
private final Collator sCollator = Collator.getInstance();
@Override
public int compare(AppEntry object1, AppEntry object2) {
return sCollator.compare(object1.getLabel(), object2.getLabel());
}
};
/**
* Helper for determining if the configuration has changed in an interesting
* way so we need to rebuild the app list.
*/
public static class InterestingConfigChanges {
final Configuration mLastConfiguration = new Configuration();
int mLastDensity;
boolean applyNewConfig(Resources res) {
int configChanges = mLastConfiguration.updateFrom(res.getConfiguration());
boolean densityChanged = mLastDensity != res.getdisplayMetrics().densityDpi;
if (densityChanged || (configChanges&(ActivityInfo.CONfig_LOCALE
|ActivityInfoCompat.CONfig_UI_MODE|ActivityInfo.CONfig_SCREEN_LAYOUT)) != 0) {
mLastDensity = res.getdisplayMetrics().densityDpi;
return true;
}
return false;
}
}
/**
* Helper class to look for interesting changes to the installed apps
* so that the loader can be updated.
*/
public static class PackageIntentReceiver extends broadcastReceiver {
final AppListLoader mloader;
public PackageIntentReceiver(AppListLoader loader) {
mloader = loader;
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
filter.addDataScheme("package");
mloader.getContext().registerReceiver(this, filter);
// Register for events related to sdcard installation.
IntentFilter sdFilter = new IntentFilter();
sdFilter.addAction(IntentCompat.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
sdFilter.addAction(IntentCompat.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
mloader.getContext().registerReceiver(this, sdFilter);
}
@Override
public void onReceive(Context context, Intent intent) {
// Tell the loader about the change.
mloader.onContentChanged();
}
}
/**
* A custom Loader that loads all of the installed applications.
*/
public static class AppListLoader extends AsyncTaskLoader<List<AppEntry>> {
final InterestingConfigChanges mLastConfig = new InterestingConfigChanges();
final PackageManager mPm;
List<AppEntry> mApps;
PackageIntentReceiver mPackageObserver;
public AppListLoader(Context context) {
super(context);
// Retrieve the package manager for later use; note we don't
// use 'context' directly but instead the save global application
// context returned by getContext().
mPm = getContext().getPackageManager();
}
/**
* This is where the bulk of our work is done. This function is
* called in a background thread and should generate a new set of
* data to be published by the loader.
*/
@Override
public List<AppEntry> loadInBackground() {
// Retrieve all kNown applications.
List<ApplicationInfo> apps = mPm.getInstalledApplications(
PackageManager.GET_UNINSTALLED_PACKAGES |
PackageManager.GET_disABLED_COMPONENTS);
if (apps == null) {
apps = new ArrayList<ApplicationInfo>();
}
final Context context = getContext();
// Create corresponding array of entries and load their labels.
List<AppEntry> entries = new ArrayList<AppEntry>(apps.size());
for (int i=0; i<apps.size(); i++) {
AppEntry entry = new AppEntry(this, apps.get(i));
entry.loadLabel(context);
entries.add(entry);
}
// Sort the list.
Collections.sort(entries, ALPHA_COMParaTOR);
// Done!
return entries;
}
/**
* Called when there is new data to deliver to the client. The
* super class will take care of delivering it; the implementation
* here just adds a little more logic.
*/
@Override
public void deliverResult(List<AppEntry> apps) {
if (isReset()) {
// An async query came in while the loader is stopped. We
// don't need the result.
if (apps != null) {
onReleaseResources(apps);
}
}
List<AppEntry> oldApps = apps;
mApps = apps;
if (isstarted()) {
// If the Loader is currently started, we can immediately
// deliver its results.
super.deliverResult(apps);
}
// At this point we can release the resources associated with
// 'oldApps' if needed; Now that the new result is delivered we
// kNow that it is no longer in use.
if (oldApps != null) {
onReleaseResources(oldApps);
}
}
/**
* Handles a request to start the Loader.
*/
@Override
protected void onStartLoading() {
if (mApps != null) {
// If we currently have a result available, deliver it
// immediately.
deliverResult(mApps);
}
// Start watching for changes in the app data.
if (mPackageObserver == null) {
mPackageObserver = new PackageIntentReceiver(this);
}
// Has something interesting in the configuration changed since we
// last built the app list?
boolean configChange = mLastConfig.applyNewConfig(getContext().getResources());
if (takeContentChanged() || mApps == null || configChange) {
// If the data has changed since the last time it was loaded
// or is not currently available, start a load.
forceLoad();
}
}
/**
* Handles a request to stop the Loader.
*/
@Override
protected void onStopLoading() {
// Attempt to cancel the current load task if possible.
cancelLoad();
}
/**
* Handles a request to cancel a load.
*/
@Override
public void onCanceled(List<AppEntry> apps) {
super.onCanceled(apps);
// At this point we can release the resources associated with 'apps'
// if needed.
onReleaseResources(apps);
}
/**
* Handles a request to completely reset the Loader.
*/
@Override
protected void onReset() {
super.onReset();
// Ensure the loader is stopped
onStopLoading();
// At this point we can release the resources associated with 'apps'
// if needed.
if (mApps != null) {
onReleaseResources(mApps);
mApps = null;
}
// Stop monitoring for changes.
if (mPackageObserver != null) {
getContext().unregisterReceiver(mPackageObserver);
mPackageObserver = null;
}
}
/**
* Helper function to take care of releasing resources associated
* with an actively loaded data set.
*/
protected void onReleaseResources(List<AppEntry> apps) {
// For a simple List<> there is nothing to do. For something
// like a Cursor, we would close it here.
}
}
public static class Applistadapter extends ArrayAdapter<AppEntry> {
private final LayoutInflater mInflater;
public Applistadapter(Context context) {
super(context, android.R.layout.simple_list_item_2);
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void setData(List<AppEntry> data) {
clear();
if (data != null) {
for (AppEntry appEntry : data) {
add(appEntry);
}
}
}
/**
* Populate new items in the list.
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if (convertView == null) {
view = mInflater.inflate(R.layout.list_item_icon_text, parent, false);
} else {
view = convertView;
}
AppEntry item = getItem(position);
((ImageView)view.findViewById(R.id.icon)).setimageDrawable(item.getIcon());
((TextView)view.findViewById(R.id.text)).setText(item.getLabel());
return view;
}
}
public static class AppListFragment extends SherlockListFragment
implements LoaderManager.LoaderCallbacks<List<AppEntry>> {
// This is the Adapter being used to display the list's data.
Applistadapter mAdapter;
// If non-null, this is the current filter the user has provided.
String mCurFilter;
OnQueryTextListenerCompat mOnQueryTextListenerCompat;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Give some text to display if there is no data. In a real
// application this would come from a resource.
setEmptyText("No applications");
// We have a menu item to show in action bar.
setHasOptionsMenu(true);
// Create an empty adapter we will use to display the loaded data.
mAdapter = new Applistadapter(getActivity());
setlistadapter(mAdapter);
// Start out with a progress indicator.
setListShown(false);
// Prepare the loader. Either re-connect with an existing one,
// or start a new one.
getLoaderManager().initLoader(0, null, this);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Place an action bar item for searching.
MenuItem item = menu.add("Search");
item.setIcon(android.R.drawable.ic_menu_search);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
View searchView = SearchViewCompat.newSearchView(getActivity());
if (searchView != null) {
SearchViewCompat.setonQueryTextListener(searchView,
new OnQueryTextListenerCompat() {
@Override
public boolean onQueryTextChange(String newText) {
// Called when the action bar search text has changed. Since this
// is a simple array adapter, we can just have it do the filtering.
mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
mAdapter.getFilter().filter(mCurFilter);
return true;
}
});
item.setActionView(searchView);
}
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Insert desired behavior here.
Log.i("LoaderCustom", "Item clicked: " + id);
//Here i want to kNow the package name of the selected app item in the list
}
@Override
public Loader<List<AppEntry>> onCreateLoader(int id, Bundle args) {
// This is called when a new Loader needs to be created. This
// sample only has one Loader with no arguments, so it is simple.
return new AppListLoader(getActivity());
}
@Override
public void onl oadFinished(Loader<List<AppEntry>> loader, List<AppEntry> data) {
// Set the new data in the adapter.
mAdapter.setData(data);
// The list should Now be shown.
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
}
}
@Override
public void onl oaderReset(Loader<List<AppEntry>> loader) {
// Clear the data in the adapter.
mAdapter.setData(null);
}
}
}
解决方法:
这是代码:
final PackageManager pm = getPackageManager();
//get a list of installed apps.
List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_Meta_DATA);
for (ApplicationInfo packageInfo : packages) {
Log.d(TAG, "Installed package :" + packageInfo.packageName);
Log.d(TAG, "Launch Activity :" + pm.getLaunchIntentForPackage(packageInfo.packageName));
}
Android5.0以下 源码分析Notification的notify
分析下Notification的更新机制。
涉及Service:
StatusBarManagerService
NotificationManagerService
这个两个service都会在 frameworks/base/services/java/com/android/server/SystemServer.java文件里面进行启动的
class ServerThread extends Thread { public void run() { ...... StatusBarManagerService statusBar = null; NotificationManagerService notification = null; ...... statusBar = new StatusBarManagerService(context, wm); ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar); ...... notification = new NotificationManagerService(context, statusBar, lights); ServiceManager.addService(Context.NOTIFICATION_SERVICE, notification); ...... } }
下面开始跟踪Notification的Notify流程。
1.
当在Activity里面创建一个Notification,并Notify
NotificationManager nm = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); Notification n = new Notification(R.drawable.chat, "Hello,there!", System.currentTimeMillis()); n.flags = Notification.FLAG_AUTO_CANCEL; Intent i = new Intent(arg0.getContext(), NotificationShow.class); i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK); //PendingIntent PendingIntent contentIntent = PendingIntent.getActivity( arg0.getContext(), R.string.app_name, i, PendingIntent.FLAG_UPDATE_CURRENT); n.setLatestEventInfo( arg0.getContext(), "Hello,there!", "Hello,there,I''m john.", contentIntent); nm.notify(R.string.app_name, n);
2.调用NotificationManager.notify,进入notify 方法
public void notify(int id, Notification notification) { notify(null, id, notification); } public void notify(String tag, int id, Notification notification) { ...... INotificationManager service = getService(); ...... service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id, notification, idOut, UserHandle.myUserId()); ...... }
3.在调用notify(String tag, int id, Notification notification)时,会调用getService()
static public INotificationManager getService() 78 { 79 if (sService != null) { 80 return sService; 81 } 82 IBinder b = ServiceManager.getService("notification"); 83 sService = INotificationManager.Stub.asInterface(b); 84 return sService; 85 }
这里发现,会调用ServiceManager.getService("notification"), 这样就会获取到文章刚开始讲的NotificationManagerService 的一个binder对象。获取回到第二步调用service.enqueueNotificationWithTAG.
4.进入NotificationManagerService的enqueueNotificationWithTAG
public void enqueueNotificationWithTag(String pkg, String basePkg, String tag, int id, 1621 Notification notification, int[] idOut, int userId) 1622 { 1623 enqueueNotificationInternal(pkg, basePkg, Binder.getCallingUid(), Binder.getCallingPid(), 1624 tag, id, notification, idOut, userId); 1625 } 1634 public void enqueueNotificationInternal(final String pkg, String basePkg, final int callingUid, 1635 final int callingPid, final String tag, final int id, final Notification notification, 1636 int[] idOut, int incomingUserId) 1637 { ...... final StatusBarNotification n = new StatusBarNotification( 1755 pkg, id, tag, callingUid, callingPid, score, notification, user); 1792 mStatusBar.updateNotification(r.statusBarKey, n); 1793 ...... }
在这个方法里,会将前面传递进来的Notification封装成一个StatusBarNotification对象,然后调用mStatusBar.updateNotification去更新,这个mStatusBar是什么?
5. 文章最开始提到会在ServerThread里面添加NotificationManagerService,在创建的NotificationManagerService的时候,会调用它的构造函数
NotificationManagerService(Context context, StatusBarManagerService statusBar, 1291 LightsService lights) 1292 { ....... }
这里面就会传递进来,在ServerThread里刚刚创建的StatusBarManagerService. 所以在第4步的时候我们能够调用mStatusBar.updateNotification()。
6. StatusBarManagerService 中mStatusBar .updateNotification()方法
public void updateNotification(IBinder key, StatusBarNotification notification) { 512 synchronized (mNotifications) { 516 mNotifications.put(key, notification); ...... 519 mBar.updateNotification(key, notification); ...... 524 }
这里会调用mBar.updateNotification(),mBar是什么?
7. StatusBarManagerService 中 mBar对象
volatile IStatusBar mBar; // Callbacks from the status bar service. 428 // ================================================================================ 429 public void registerStatusBar(IStatusBar bar, StatusBarIconList iconList, 430 List<IBinder> notificationKeys, List<StatusBarNotification> notifications, 431 int switches[], List<IBinder> binders) { ......
上面发现有个registerStatusBar方法,会传递进来一个IStatusBar 对象,那这个方法会在哪里调用呢?
8. 在StatusBarManagerService中,我们发现调用mBar对象都是去处理StatusBar的UI,那这个StatusBar是哪里的?SystemUI里面的。检索下SystemUI的代码,果然发现在
BaseStatusBar里面:
public void start() { mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications, 250 switches, binders); }
在这里registerStatusBar, 而这个mCommandQueue参数就是前面IStatusBar对象。
9. mCommanQueue变量
protected CommandQueue mCommandQueue;
28/** 29 * This class takes the functions from IStatusBar that come in on 30 * binder pool threads and posts messages to get them onto the main 31 * thread, and calls onto Callbacks. It also takes care of 32 * coalescing these calls so they don''t stack up. For the calls 33 * are coalesced, note that they are all idempotent. 34 */ 35public class CommandQueue extends IStatusBar.Stub{ /** 78 * These methods are called back on the main thread. 79 */ 80 public interface Callbacks { 81 public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon); 82 public void updateIcon(String slot, int index, int viewIndex, 83 StatusBarIcon old, StatusBarIcon icon); 84 public void removeIcon(String slot, int index, int viewIndex); 85 public void addNotification(IBinder key, StatusBarNotification notification); 86 public void updateNotification(IBinder key, StatusBarNotification notification); 87 public void removeNotification(IBinder key); 88 public void disable(int state); 89 public void animateExpandNotificationsPanel(); 90 public void animateCollapsePanels(int flags); 91 public void animateExpandSettingsPanel(); 92 public void setSystemUiVisibility(int vis, int mask); 93 public void topAppWindowChanged(boolean visible); 94 public void setImeWindowStatus(IBinder token, int vis, int backDisposition); 95 public void setHardKeyboardStatus(boolean available, boolean enabled); 96 public void toggleRecentApps(); 97 public void preloadRecentApps(); 98 public void showSearchPanel(); 99 public void hideSearchPanel(); 100 public void cancelPreloadRecentApps(); 101 public void setNavigationIconHints(int hints); 102 public void setWindowState(int window, int state); 103 } }
发现这个方法继承IStatusBar.stub,里面有一连串的回调函数。这些回调函数在BaseStatusBar里面实现的
public abstract class BaseStatusBar extends SystemUI implements 79 CommandQueue.Callbacks {
10. 回到第6步,当在StatusBarManagerService中调用mBar.updateNotification时,根据7,8,9的分析,最终会调用在BaseStatusBar里面实现的UpdateNotification方法
updateNotification(IBinder key, StatusBarNotification notification) { ...... }
在这里会将Notification显 示在StatusBar上面。
这里面主要涉及到两个NotificationManagerService和StatusBarManager的交互。
第一步。
系统启动时在ServerThread里生成StatusBarManagerService和NotificationManagerService,并将StatusBarManagerService对象作为一个参数传递到NotificationManagerService的构造方法中。
系统加载应用,SystemUI中, BaseStatusBar实现回调函数CommandQueue.Callbacks, 并调用StatusBarManagerService的registerStatusBar方法,将CommandQueue对象传递进去
第二步
Activity里调用notify方法,在NotificationManagerService将Notification封装成StatusBarNotification。
NotificationManagerService调用statusBarManagerService的updateNotification()。
第三步
StatusBarManagerService调用CommandQueue实现的回调函数,最终将Notification显示在SystemUI上面。
ApplicationInfo-Android动态获取包名-Android获取所有的应用程序信息-Android获取应用程序的占用空间大小-Android应用程序管理系列(三)
Android ApplicationInfo 应用程序信息
1、简述
1 ApplicationInfo是android.content.pm包下的一个实体类,用于封装应用的信息,flags是其中的一个成员变量public int flags = 0;用于保存应用的标志信息。
2 ApplicationInfo 通过它可以得到一个应用基本信息。
这些信息是从AndroidManifest.xml的< application >标签获取的
3 ApplicationInfo对象里保存的信息都是<application>标签里的属性值
4 ApplicationInfo与ResolveInfo比较:前者能够得到Icon、Label、meta-data、description。后者只能得到Icon、Label
2、获取ApplicationInfo
2.1 、获取手机上安装所有程序对应的 ApplicationInfo
/**
* 获取手机上安装的所有的程序对应的 ApplicationInfo
* 它是通过解析AndroidManifest.xml的< application>标签中得到的,所以它能得到所有的app
*
* 获取手机上的所有的安装的应用程序信息
* 参数为 标识 一般为 PackageManager.GET_UNINSTALLED_PACKAGES
*/
List<ApplicationInfo> list = packageManager.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
2.2 、获取指定包名对应的 ApplicationInfo
/**
* 获取指定应用程序 ApplicationInfo
* 参数一对应应用程序的包名
* 参数二 应用程序对应的标识 通常为 0
*/
ApplicationInfo applicationInfo = packageManager.getApplicationInfo("com.androidlongs.contactsapplication", 0);
3、通过ApplicationInfo来获取应用程序的 基本信息
3.1 、获取应用程序对应的包名、应用名称
//获取应用图标
Drawable drawable = applicationInfo.loadIcon(packageManager);
//获取应用程序的 包名
String appPackageName = applicationInfo.packageName;
//获取应用名
//参数 packageManager 是应用管理者对象
String appName =applicationInfo.loadLabel(packageManager).toString();
3.2 、获取应用程序对应数据的目录以及占用的空间大小
//获取应用存放数据目录
String dir = applicationInfo.sourceDir;
Log.d("app ","应用存放数据目录 " +dir);
//获取应用数据大小
ong length = new File(dir).length();
//转换为 M
float size = length*1f/1024/1024;
Log.d("app ","应用数据大小 " +length+"\t"+size);
3.3 、判断是否安装在外置储存空间存
//判断是否安装在外存
int flags = applicationInfo.flags;
if((flags&ApplicationInfo.FLAG_EXTERNAL_STORAGE)==ApplicationInfo.FLAG_EXTERNAL_STORAGE){
Log.d("app "," 安装在 外置存储空间 ");
}else {
Log.d("app "," 安装在 内置存储空间 ");
}
3.4 、判断应用程序是否是系统应用
//判断是否是系统应用
if((flags&ApplicationInfo.FLAG_SYSTEM)==ApplicationInfo.FLAG_SYSTEM){
Log.d("app "," 是系统应用 ");
}else{
Log.d("app "," 不是系统应用 ");
}
3.5 、manageSpaceActivityName
/**
* 从”android:manageSpaceActivity“属性得到
* 用于指定一个Activity来管理数据,
* 它最终会出现在设置->应用程序管理中,
* 默认为按钮为”清除数据”,指定此属性后,该按钮可点击跳转到该Activity, 让用户选择性清除哪些数据。若不设置则为null.
*/
String activityName = applicationInfo.manageSpaceActivityName;
Log.i("applicationInfo", "activityName: " + activityName);
3.6 、获取应用程序运行的进程
/**
* 从”android:process“属性得到,注明应用运行的进程名。或不设置则默认为应用包名。
*/
String processName = applicationInfo.processName;
Log.i("applicationInfo", "processName: " + processName);
3.7 、其他配置信息简述
// 配置文件中的android:backupAgent属性值,用于备份
String backupAgentName = applicationInfo.backupAgentName;
Log.i("applicationInfo", "backupAgentName: " + backupAgentName);
// 获取继承Application类的对象,维护全局的Application状态
//但一般都不用继承的方式,可以通过Context.getApplicationContext()方法得到
String className = applicationInfo.className;
Log.i("applicationInfo", "className: " + className);
/**
* 可选项,访问当前应用所有组件需要声明的权限,从”android:permission“属性得到。
*/
String permisson = applicationInfo.permission;
Log.i("applicationInfo", "permisson: " + permisson);
// 创建对象时,传入的是GET_SHARED_LIBRARY_FILES该属性才有值
String[] files = applicationInfo.sharedLibraryFiles;
Log.i("applicationInfo", "files: " + files);
// 存放数据的路径 应用数据目录。
String dataPath = applicationInfo.dataDir;
Log.i("applicationInfo", "dataPath: " + dataPath);
// 本地路径 JNI本地库存放路径。
String nativePath = applicationInfo.nativeLibraryDir;
Log.i("applicationInfo", "nativePath:" + nativePath);
// 公共资源路径
String punlicSourcePath = applicationInfo.publicSourceDir;
Log.i("applicationInfo", "punlicSourcePath: " + punlicSourcePath);
// 资源路径 应用APK的全路径
String sourcePath = applicationInfo.sourceDir;
Log.i("applicationInfo", "sourcePath: " + sourcePath);
/**
* 当前应用所有Activity的默认task密切性。
* 可以参考ActivityInfo的taskAffinity,从”android:taskAffinity“属性得到。
* 具体taskAffinity是怎么影响到Activity在task的启动, 后面会在Activity启动模式中细讲
*/
String taskAffinity = applicationInfo.taskAffinity;
Log.i("applicationInfo", "taskAffinity: " + taskAffinity);
// 如果是false,代表application里的所有组件都禁用
boolean enable = applicationInfo.enabled;
Log.i("applicationInfo", "enable: " + enable);
// 表述资源文件的标识
int descriRes = applicationInfo.descriptionRes;
Log.i("applicationInfo", "descriRes: " + descriRes);
int flag = applicationInfo.flags;
Log.i("applicationInfo", "flag: " + flag);
// 指定smallest screen width的值,超过这个值,就要开启屏幕兼容
int compatibleWidth = applicationInfo.compatibleWidthLimitDp;//android:compatibleWidthLimitDp属性
Log.i("applicationInfo", "compatibleWidth: " + compatibleWidth);
// 同上,只是这时候用户无法禁止屏幕兼容模式,说明是强制启动屏幕兼容
int largestWidth = applicationInfo.largestWidthLimitDp;//android:largestWidthLimitDp属性
Log.i("applicationInfo", "largestWidth: " + largestWidth);
// 所需屏幕空间的最短尺寸,
int samllestWidth = applicationInfo.requiresSmallestWidthDp;//android:requiresSmallestWidthDp属性
Log.i("applicationInfo", "samllestWidth: " + samllestWidth);
// 应用所需的最小sdk版本
int sdkVersion = applicationInfo.targetSdkVersion;
Log.i("applicationInfo", "sdkVersion: " + sdkVersion);
int theme = applicationInfo.theme;
Log.i("applicationInfo", "theme: " + theme);//android:theme=
int uid = applicationInfo.uid;
Log.i("applicationInfo", "uid: " + uid);
// 配置文件中的uiOptions属性的值
int uiOptions = applicationInfo.uiOptions;
Log.i("applicationInfo", "uiOptions: " + uiOptions);
完毕
本文同步分享在 博客“早起的年轻人”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
C# NotifyIcon 托盘控件
右下角以图标形式显示,双击图标显示界面,最小化界面时不显示在任务栏。
第一步:在界面上添加NotifyIcon控件。
第二步:设置notifyIcon1的属性,添加图标,将Visible设为true。当然,Visible也可以在代码中设置,true是显示在右下角,false不显示。
第三步:notifyIcon1添加事件,即双击显示界面。
1 private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
2 {
3 this.Show();//显示界面
4 this.WindowState = FormWindowState.Normal;
5 this.ShowInTaskbar = true;//显示在任务栏
6 }
第四步:最小化界面时不显示在任务栏。
1 private void FormMain_Resize(object sender, EventArgs e)
2 {
3 if (this.WindowState == FormWindowState.Minimized)
4 {
5 this.Hide();
6 this.ShowInTaskbar = false;
7 }
8 }
我们今天的关于获取应用程序的NotifyIcon矩形?和获取应用软件的方法的分享就到这里,谢谢您的阅读,如果想了解更多关于android-如何获取应用程序的程序包名称,然后使用Intent启动该应用程序?、Android5.0以下 源码分析Notification的notify、ApplicationInfo-Android动态获取包名-Android获取所有的应用程序信息-Android获取应用程序的占用空间大小-Android应用程序管理系列(三)、C# NotifyIcon 托盘控件的相关信息,可以在本站进行搜索。
本文标签: