• 导入/导出联系人通知栏显示处理


    导入/导出联系人过程,notification创建都是在com.android.contacts.common.vcard.NotificationImportExportListener中。

      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *        http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License
     15  */
     16 
     17 package com.android.contacts.common.vcard;
     18 
     19 import android.app.Activity;
     20 import android.app.Notification;
     21 import android.app.NotificationManager;
     22 import android.app.PendingIntent;
     23 import android.content.ContentUris;
     24 import android.content.Context;
     25 import android.content.Intent;
     26 import android.net.Uri;
     27 import android.os.Handler;
     28 import android.os.Message;
     29 import android.provider.ContactsContract.RawContacts;
     30 import android.widget.Toast;
     31 
     32 import com.android.contacts.common.R;
     33 import com.android.vcard.VCardEntry;
     34 
     35 public class NotificationImportExportListener implements VCardImportExportListener,
     36         Handler.Callback {
     37     /** The tag used by vCard-related notifications. */
     38     /* package */ static final String DEFAULT_NOTIFICATION_TAG = "VCardServiceProgress";
     39     /**
     40      * The tag used by vCard-related failure notifications.
     41      * <p>
     42      * Use a different tag from {@link #DEFAULT_NOTIFICATION_TAG} so that failures do not get
     43      * replaced by other notifications and vice-versa.
     44      */
     45     /* package */ static final String FAILURE_NOTIFICATION_TAG = "VCardServiceFailure";
     46 
     47     private final NotificationManager mNotificationManager;
     48     private final Activity mContext;
     49     private final Handler mHandler;
     50 
     51     public NotificationImportExportListener(Activity activity) {
     52         mContext = activity;
     53         mNotificationManager = (NotificationManager) activity.getSystemService(
     54                 Context.NOTIFICATION_SERVICE);
     55         mHandler = new Handler(this);
     56     }
     57 
     58     @Override
     59     public boolean handleMessage(Message msg) {
     60         String text = (String) msg.obj;
     61         Toast.makeText(mContext, text, Toast.LENGTH_LONG).show();
     62         return true;
     63     }
     64 
     65     @Override
     66     public void onImportProcessed(ImportRequest request, int jobId, int sequence) {
     67         // Show a notification about the status
     68         final String displayName;
     69         final String message;
     70         if (request.displayName != null) {
     71             displayName = request.displayName;
     72             message = mContext.getString(R.string.vcard_import_will_start_message, displayName);
     73         } else {
     74             displayName = mContext.getString(R.string.vcard_unknown_filename);
     75             message = mContext.getString(
     76                     R.string.vcard_import_will_start_message_with_default_name);
     77         }
     78 
     79         // We just want to show notification for the first vCard.
     80         if (sequence == 0) {
     81             // TODO: Ideally we should detect the current status of import/export and
     82             // show "started" when we can import right now and show "will start" when
     83             // we cannot.
     84             mHandler.obtainMessage(0, message).sendToTarget();
     85         }
     86 
     87         final Notification notification = constructProgressNotification(mContext,
     88                 VCardService.TYPE_IMPORT, message, message, jobId, displayName, -1, 0);
     89         mNotificationManager.notify(DEFAULT_NOTIFICATION_TAG, jobId, notification);
     90     }
     91 
     92     @Override
     93     public void onImportParsed(ImportRequest request, int jobId, VCardEntry entry, int currentCount,
     94             int totalCount) {
     95         if (entry.isIgnorable()) {
     96             return;
     97         }
     98         
     99         if(currentCount!=totalCount && currentCount%100 !=1 ) return ;//for  slow down the notification speed
    100 
    101         final String totalCountString = String.valueOf(totalCount);
    102         //modified ------
    103         /*final String tickerText =
    104                 mContext.getString(R.string.progress_notifier_message,
    105                         String.valueOf(currentCount),
    106                         totalCountString,
    107                         entry.getDisplayName());
    108         final String description = mContext.getString(R.string.importing_vcard_description,
    109                 entry.getDisplayName());*/
    110         final String tickerText =mContext.getString(R.string.progress_notifier_message_importing);
    111         final String description = tickerText;
    112         //end modified ------
    113         final Notification notification = constructProgressNotification(
    114                 mContext.getApplicationContext(), VCardService.TYPE_IMPORT, description, tickerText,
    115                 jobId, request.displayName, totalCount, currentCount);
    116         mNotificationManager.notify(DEFAULT_NOTIFICATION_TAG, jobId, notification);
    117     }
    118 
    119     @Override
    120     public void onImportFinished(ImportRequest request, int jobId, Uri createdUri) {
    121         final String description = mContext.getString(R.string.importing_vcard_finished_title,
    122                 request.displayName);
    123         final Intent intent;
    124         if (createdUri != null) {
    125             final long rawContactId = ContentUris.parseId(createdUri);
    126             final Uri contactUri = RawContacts.getContactLookupUri(
    127                     mContext.getContentResolver(), ContentUris.withAppendedId(
    128                             RawContacts.CONTENT_URI, rawContactId));
    129             intent = new Intent(Intent.ACTION_VIEW, contactUri);
    130         } else {
    131             intent = null;
    132         }
    133         final Notification notification =
    134                 NotificationImportExportListener.constructFinishNotification(mContext,
    135                         VCardService.TYPE_IMPORT, description, null, intent);
    136         mNotificationManager.notify(NotificationImportExportListener.DEFAULT_NOTIFICATION_TAG,
    137                 jobId, notification);
    138     }
    139 
    140     @Override
    141     public void onImportFailed(ImportRequest request) {
    142         // TODO: a little unkind to show Toast in this case, which is shown just a moment.
    143         // Ideally we should show some persistent something users can notice more easily.
    144         mHandler.obtainMessage(0,
    145                 mContext.getString(R.string.vcard_import_request_rejected_message)).sendToTarget();
    146     }
    147 
    148     @Override
    149     public void onImportCanceled(ImportRequest request, int jobId) {
    150         final String description = mContext.getString(R.string.importing_vcard_canceled_title,
    151                 request.displayName);
    152         final Notification notification =
    153                 NotificationImportExportListener.constructCancelNotification(mContext, description);
    154         mNotificationManager.notify(NotificationImportExportListener.DEFAULT_NOTIFICATION_TAG,
    155                 jobId, notification);
    156     }
    157 
    158     @Override
    159     public void onExportProcessed(ExportRequest request, int jobId) {
    160         final String displayName = request.destUri.getLastPathSegment();
    161         final String message = mContext.getString(R.string.vcard_export_will_start_message,
    162                 displayName);
    163 
    164         mHandler.obtainMessage(0, message).sendToTarget();
    165         final Notification notification =
    166                 NotificationImportExportListener.constructProgressNotification(mContext,
    167                         VCardService.TYPE_EXPORT, message, message, jobId, displayName, -1, 0);
    168         mNotificationManager.notify(DEFAULT_NOTIFICATION_TAG, jobId, notification);
    169     }
    170 
    171     @Override
    172     public void onExportFailed(ExportRequest request) {
    173         mHandler.obtainMessage(0,
    174                 mContext.getString(R.string.vcard_export_request_rejected_message)).sendToTarget();
    175     }
    176 
    177     @Override
    178     public void onCancelRequest(CancelRequest request, int type) {
    179         final String description = type == VCardService.TYPE_IMPORT ?
    180                 mContext.getString(R.string.importing_vcard_canceled_title, request.displayName) :
    181                 mContext.getString(R.string.exporting_vcard_canceled_title, request.displayName);
    182         final Notification notification = constructCancelNotification(mContext, description);
    183         mNotificationManager.notify(DEFAULT_NOTIFICATION_TAG, request.jobId, notification);
    184     }
    185 
    186     /**
    187      * Constructs a {@link Notification} showing the current status of import/export.
    188      * Users can cancel the process with the Notification.
    189      *
    190      * @param context
    191      * @param type import/export
    192      * @param description Content of the Notification.
    193      * @param tickerText
    194      * @param jobId
    195      * @param displayName Name to be shown to the Notification (e.g. "finished importing XXXX").
    196      * Typycally a file name.
    197      * @param totalCount The number of vCard entries to be imported. Used to show progress bar.
    198      * -1 lets the system show the progress bar with "indeterminate" state.
    199      * @param currentCount The index of current vCard. Used to show progress bar.
    200      */
    201     /* package */ static Notification constructProgressNotification(
    202             Context context, int type, String description, String tickerText,
    203             int jobId, String displayName, int totalCount, int currentCount) {
    204         // Note: We cannot use extra values here (like setIntExtra()), as PendingIntent doesn't
    205         // preserve them across multiple Notifications. PendingIntent preserves the first extras
    206         // (when flag is not set), or update them when PendingIntent#getActivity() is called
    207         // (See PendingIntent#FLAG_UPDATE_CURRENT). In either case, we cannot preserve extras as we
    208         // expect (for each vCard import/export request).
    209         //
    210         // We use query parameter in Uri instead.
    211         // Scheme and Authority is arbitorary, assuming CancelActivity never refers them.
    212         final Intent intent = new Intent(context, CancelActivity.class);
    213         final Uri uri = (new Uri.Builder())
    214                 .scheme("invalidscheme")
    215                 .authority("invalidauthority")
    216                 .appendQueryParameter(CancelActivity.JOB_ID, String.valueOf(jobId))
    217                 .appendQueryParameter(CancelActivity.DISPLAY_NAME, displayName)
    218                 .appendQueryParameter(CancelActivity.TYPE, String.valueOf(type)).build();
    219         intent.setData(uri);
    220 
    221         final Notification.Builder builder = new Notification.Builder(context);
    222         builder.setOngoing(true)
    223                 .setProgress(totalCount, currentCount, totalCount == - 1)
    224                 .setTicker(tickerText)
    225                 .setContentTitle(description)
    226                 .setSmallIcon(type == VCardService.TYPE_IMPORT
    227                         ? android.R.drawable.stat_sys_download
    228                         : android.R.drawable.stat_sys_upload)
    229                 .setContentIntent(PendingIntent.getActivity(context, 0, intent, 0));
    230         if (totalCount > 0) {
    231             builder.setContentText(context.getString(R.string.percentage,
    232                     String.valueOf(currentCount * 100 / totalCount)));
    233         }
    234         return builder.getNotification();
    235     }
    236 
    237     /**
    238      * Constructs a Notification telling users the process is canceled.
    239      *
    240      * @param context
    241      * @param description Content of the Notification
    242      */
    243     /* package */ static Notification constructCancelNotification(
    244             Context context, String description) {
    245         return new Notification.Builder(context)
    246                 .setAutoCancel(true)
    247                 .setSmallIcon(android.R.drawable.stat_notify_error)
    248                 .setContentTitle(description)
    249                 .setContentText(description)
    250                 .setContentIntent(PendingIntent.getActivity(context, 0, new Intent(), 0))
    251                 .getNotification();
    252     }
    253 
    254     /**
    255      * Constructs a Notification telling users the process is finished.
    256      *
    257      * @param context
    258      * @param description Content of the Notification
    259      * @param intent Intent to be launched when the Notification is clicked. Can be null.
    260      */
    261     /* package */ static Notification constructFinishNotification(
    262             Context context, int type, String title, String description, Intent intent) {
    263         return new Notification.Builder(context)
    264                 .setAutoCancel(true)
    265                 .setSmallIcon(type == VCardService.TYPE_IMPORT
    266                         ? android.R.drawable.stat_sys_download_done
    267                         : android.R.drawable.stat_sys_upload_done)
    268                 .setContentTitle(title)
    269                 .setContentText(description)
    270                 .setContentIntent(PendingIntent.getActivity(context, 0,
    271                         (intent != null ? intent : new Intent()), 0))
    272                 .getNotification();
    273     }
    274 
    275     /**
    276      * Constructs a Notification telling the vCard import has failed.
    277      *
    278      * @param context
    279      * @param reason The reason why the import has failed. Shown in description field.
    280      */
    281     /* package */ static Notification constructImportFailureNotification(
    282             Context context, String reason) {
    283         return new Notification.Builder(context)
    284                 .setAutoCancel(true)
    285                 .setSmallIcon(android.R.drawable.stat_notify_error)
    286                 .setContentTitle(context.getString(R.string.vcard_import_failed))
    287                 .setContentText(reason)
    288                 .setContentIntent(PendingIntent.getActivity(context, 0, new Intent(), 0))
    289                 .getNotification();
    290     }
    291 
    292     @Override
    293     public void onComplete() {
    294         mContext.finish();
    295     }
    296 }
    View Code

    导入联系人:

    处理每个Vcard文件时的通知(每个Vcard对应一条单独的通知,排队Import)

     1  public void onImportProcessed(ImportRequest request, int jobId, int sequence) {
     2         // Show a notification about the status
     3         final String displayName;
     4         final String message;
     5         if (request.displayName != null) {
     6             displayName = request.displayName;
     7             message = mContext.getString(R.string.vcard_import_will_start_message, displayName);
     8         } else {
     9             displayName = mContext.getString(R.string.vcard_unknown_filename);
    10             message = mContext.getString(
    11                     R.string.vcard_import_will_start_message_with_default_name);
    12         }
    13 
    14         // We just want to show notification for the first vCard.
    15         if (sequence == 0) {
    16             // TODO: Ideally we should detect the current status of import/export and
    17             // show "started" when we can import right now and show "will start" when
    18             // we cannot.
    19             mHandler.obtainMessage(0, message).sendToTarget();
    20         }
    21 
    22         final Notification notification = constructProgressNotification(mContext,
    23                 VCardService.TYPE_IMPORT, message, message, jobId, displayName, -1, 0);
    24         mNotificationManager.notify(DEFAULT_NOTIFICATION_TAG, jobId, notification);
    25     }

    处理具体Vcard文件中每个contact时的通知(百分比进度条显示):

     1 public void onImportParsed(ImportRequest request, int jobId, VCardEntry entry, int currentCount,
     2             int totalCount) {
     3         if (entry.isIgnorable()) {
     4             return;
     5         }
     6         
     7         if(currentCount!=totalCount && currentCount%100 !=1 ) return ;//slow down the notification speed
     8 
     9         final String totalCountString = String.valueOf(totalCount);
    10         //modified 
    11         /*final String tickerText =
    12                 mContext.getString(R.string.progress_notifier_message,
    13                         String.valueOf(currentCount),
    14                         totalCountString,
    15                         entry.getDisplayName());
    16         final String description = mContext.getString(R.string.importing_vcard_description,
    17                 entry.getDisplayName());*/
    18         final String tickerText =mContext.getString(R.string.progress_notifier_message_importing);
    19         final String description = tickerText;
    20         //end modified
    21         final Notification notification = constructProgressNotification(
    22                 mContext.getApplicationContext(), VCardService.TYPE_IMPORT, description, tickerText,
    23                 jobId, request.displayName, totalCount, currentCount);
    24         mNotificationManager.notify(DEFAULT_NOTIFICATION_TAG, jobId, notification);
    25     }

    ----------------------------------------------------分割线----------------------------------------------------

    导出联系人:

    总的提示

     1 public void onExportProcessed(ExportRequest request, int jobId) {
     2         final String displayName = request.destUri.getLastPathSegment();
     3         final String message = mContext.getString(R.string.vcard_export_will_start_message,
     4                 displayName);
     5 
     6         mHandler.obtainMessage(0, message).sendToTarget();
     7         final Notification notification =
     8                 NotificationImportExportListener.constructProgressNotification(mContext,
     9                         VCardService.TYPE_EXPORT, message, message, jobId, displayName, -1, 0);
    10         mNotificationManager.notify(DEFAULT_NOTIFICATION_TAG, jobId, notification);
    11     }

    具体每个Contact导出提示(百分比进度条显示):

    在com.android.contacts.common.vcard.ExportProcessor中处理

     1 private void doProgressNotification(Uri uri, int totalCount, int currentCount) {
     2         final String displayName = uri.getLastPathSegment();
     3         final String description =
     4                 mService.getString(R.string.exporting_contact_list_message, displayName);
     5         final String tickerText =
     6                 mService.getString(R.string.exporting_contact_list_title);
     7         final Notification notification =
     8                 NotificationImportExportListener.constructProgressNotification(mService,
     9                         VCardService.TYPE_EXPORT, description, tickerText, mJobId, displayName,
    10                         totalCount, currentCount);
    11         mNotificationManager.notify(NotificationImportExportListener.DEFAULT_NOTIFICATION_TAG,
    12                 mJobId, notification);
    13     }

    总结:导入导出联系人notification显示——对contacts总数进行while循环,每次循环都会new一个notificaiton,所以通知栏可以看到notification一闪一闪的显示。

             而通知栏下载进度条却是进度条更新显示,notification条不闪烁,UI效果更好。

  • 相关阅读:
    四层、七层负载均衡的区别
    confd+etcd实现高可用自动发现
    从零开始搭建etcd分布式存储系统+web管理界面
    从零开始搭建Prometheus自动监控报警系统
    tcpdump工具使用说明
    Nginx的负载均衡
    Nginx的正向代理与反向代理详解
    linux集群自动化搭建(生成密钥对+分发公钥+远程批量执行脚本)
    linux文件权限总结(创建root不可以删除文件、只可追加的日志文件等)
    前端技巧备忘
  • 原文地址:https://www.cnblogs.com/antoon/p/4372679.html
Copyright © 2020-2023  润新知