109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly/* 209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Copyright (c) 2008-2009, Motorola, Inc. 309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * All rights reserved. 509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Redistribution and use in source and binary forms, with or without 709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * modification, are permitted provided that the following conditions are met: 809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * - Redistributions of source code must retain the above copyright notice, 1009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * this list of conditions and the following disclaimer. 1109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 1209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * - Redistributions in binary form must reproduce the above copyright notice, 1309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * this list of conditions and the following disclaimer in the documentation 1409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * and/or other materials provided with the distribution. 1509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 1609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * - Neither the name of the Motorola, Inc. nor the names of its contributors 1709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * may be used to endorse or promote products derived from this software 1809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * without specific prior written permission. 1909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 2009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * POSSIBILITY OF SUCH DAMAGE. 3109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 3209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 3309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellypackage com.android.bluetooth.opp; 3409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 356769b59d715ea98bd72eafcfea9acd2714a887daTao Liejunimport com.android.bluetooth.R; 366769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun 3709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.content.Context; 3809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.app.Notification; 3909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.app.NotificationManager; 4009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.app.PendingIntent; 4109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.content.Intent; 4209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.database.Cursor; 4309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.net.Uri; 4409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.util.Log; 4509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.widget.RemoteViews; 46eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Taoimport android.os.Handler; 47eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Taoimport android.os.Message; 481ac5507790a87810061a19dadec36eb328a222eaTao Liejunimport android.os.Process; 4909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport java.util.HashMap; 5009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 5109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly/** 5209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * This class handles the updating of the Notification Manager for the cases 5309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * where there is an ongoing transfer, incoming transfer need confirm and 5409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * complete (successful or failed) transfer. 5509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 5609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyclass BluetoothOppNotification { 5709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private static final String TAG = "BluetoothOppNotification"; 58ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly private static final boolean V = Constants.VERBOSE; 5909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 6009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly static final String status = "(" + BluetoothShare.STATUS + " == '192'" + ")"; 6109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 6209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly static final String visible = "(" + BluetoothShare.VISIBILITY + " IS NULL OR " 6309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly + BluetoothShare.VISIBILITY + " == '" + BluetoothShare.VISIBILITY_VISIBLE + "'" + ")"; 6409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 6509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly static final String confirm = "(" + BluetoothShare.USER_CONFIRMATION + " == '" 6609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly + BluetoothShare.USER_CONFIRMATION_CONFIRMED + "' OR " 6709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly + BluetoothShare.USER_CONFIRMATION + " == '" 6809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly + BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED + "'" + ")"; 6909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 7009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly static final String WHERE_RUNNING = status + " AND " + visible + " AND " + confirm; 7109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 7209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly static final String WHERE_COMPLETED = BluetoothShare.STATUS + " >= '200' AND " + visible; 7309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 745cc617943765df27844e459362c4bc1821305216Lixin Yue private static final String WHERE_COMPLETED_OUTBOUND = WHERE_COMPLETED + " AND " + "(" 755cc617943765df27844e459362c4bc1821305216Lixin Yue + BluetoothShare.DIRECTION + " == " + BluetoothShare.DIRECTION_OUTBOUND + ")"; 765cc617943765df27844e459362c4bc1821305216Lixin Yue 775cc617943765df27844e459362c4bc1821305216Lixin Yue private static final String WHERE_COMPLETED_INBOUND = WHERE_COMPLETED + " AND " + "(" 785cc617943765df27844e459362c4bc1821305216Lixin Yue + BluetoothShare.DIRECTION + " == " + BluetoothShare.DIRECTION_INBOUND + ")"; 795cc617943765df27844e459362c4bc1821305216Lixin Yue 8009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly static final String WHERE_CONFIRM_PENDING = BluetoothShare.USER_CONFIRMATION + " == '" 8109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly + BluetoothShare.USER_CONFIRMATION_PENDING + "'" + " AND " + visible; 8209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 831ac5507790a87810061a19dadec36eb328a222eaTao Liejun public NotificationManager mNotificationMgr; 841ac5507790a87810061a19dadec36eb328a222eaTao Liejun 851ac5507790a87810061a19dadec36eb328a222eaTao Liejun private Context mContext; 861ac5507790a87810061a19dadec36eb328a222eaTao Liejun 871ac5507790a87810061a19dadec36eb328a222eaTao Liejun private HashMap<String, NotificationItem> mNotifications; 881ac5507790a87810061a19dadec36eb328a222eaTao Liejun 891ac5507790a87810061a19dadec36eb328a222eaTao Liejun private NotificationUpdateThread mUpdateNotificationThread; 901ac5507790a87810061a19dadec36eb328a222eaTao Liejun 91eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao private int mPendingUpdate = 0; 921ac5507790a87810061a19dadec36eb328a222eaTao Liejun 935cc617943765df27844e459362c4bc1821305216Lixin Yue private static final int NOTIFICATION_ID_OUTBOUND = -1000005; 945cc617943765df27844e459362c4bc1821305216Lixin Yue 955cc617943765df27844e459362c4bc1821305216Lixin Yue private static final int NOTIFICATION_ID_INBOUND = -1000006; 965cc617943765df27844e459362c4bc1821305216Lixin Yue 975cc617943765df27844e459362c4bc1821305216Lixin Yue private boolean mUpdateCompleteNotification = true; 985cc617943765df27844e459362c4bc1821305216Lixin Yue 995cc617943765df27844e459362c4bc1821305216Lixin Yue private int mActiveNotificationId = 0; 1005cc617943765df27844e459362c4bc1821305216Lixin Yue 10109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /** 10209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * This inner class is used to describe some properties for one transfer. 10309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 10409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly static class NotificationItem { 10509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int id; // This first field _id in db; 10609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 10709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int direction; // to indicate sending or receiving 10809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 10909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int totalCurrent = 0; // current transfer bytes 11009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 11109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int totalTotal = 0; // total bytes for current transfer 11209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 11374e5eba4a45ecca87eec3ac1762ca527cc614d78erik.ljungberg int timeStamp = 0; // Database time stamp. Used for sorting ongoing transfers. 11474e5eba4a45ecca87eec3ac1762ca527cc614d78erik.ljungberg 11509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly String description; // the text above progress bar 11609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 11709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 11809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /** 11909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Constructor 120239bc526513429995c61c4148c105725c395b1a9Jackson Fan * 121239bc526513429995c61c4148c105725c395b1a9Jackson Fan * @param ctx The context to use to obtain access to the Notification 122239bc526513429995c61c4148c105725c395b1a9Jackson Fan * Service 12309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 12409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly BluetoothOppNotification(Context ctx) { 12509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mContext = ctx; 12609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mNotificationMgr = (NotificationManager)mContext 12709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly .getSystemService(Context.NOTIFICATION_SERVICE); 12809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mNotifications = new HashMap<String, NotificationItem>(); 12909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 13009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 13109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /** 13209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Update the notification ui. 13309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 13409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public void updateNotification() { 135c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue synchronized (BluetoothOppNotification.this) { 136eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao mPendingUpdate++; 137eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao if (mPendingUpdate > 1) { 138eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao if (V) Log.v(TAG, "update too frequent, put in queue"); 139eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao return; 140eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao } 141eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao if (!mHandler.hasMessages(NOTIFY)) { 142eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao if (V) Log.v(TAG, "send message"); 143eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao mHandler.sendMessage(mHandler.obtainMessage(NOTIFY)); 1441ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 1451ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 1461ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 1471ac5507790a87810061a19dadec36eb328a222eaTao Liejun 148eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao private static final int NOTIFY = 0; 149eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao // Use 1 second timer to limit notification frequency. 150eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao // 1. On the first notification, create the update thread. 151eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao // Buffer other updates. 152eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao // 2. Update thread will clear mPendingUpdate. 153eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao // 3. Handler sends a delayed message to self 154eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao // 4. Handler checks if there are any more updates after 1 second. 155eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao // 5. If there is an update, update it else stop. 156eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao private Handler mHandler = new Handler() { 157eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao public void handleMessage(Message msg) { 158eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao switch (msg.what) { 159eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao case NOTIFY: 160eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao synchronized (BluetoothOppNotification.this) { 161eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao if (mPendingUpdate > 0 && mUpdateNotificationThread == null) { 162eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao if (V) Log.v(TAG, "new notify threadi!"); 163eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao mUpdateNotificationThread = new NotificationUpdateThread(); 164eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao mUpdateNotificationThread.start(); 165eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao if (V) Log.v(TAG, "send delay message"); 166eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao mHandler.sendMessageDelayed(mHandler.obtainMessage(NOTIFY), 1000); 167eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao } else if (mPendingUpdate > 0) { 168eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao if (V) Log.v(TAG, "previous thread is not finished yet"); 169eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao mHandler.sendMessageDelayed(mHandler.obtainMessage(NOTIFY), 1000); 170eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao } 171eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao break; 172eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao } 173eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao } 174eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao } 175eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao }; 176eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao 1771ac5507790a87810061a19dadec36eb328a222eaTao Liejun private class NotificationUpdateThread extends Thread { 1781ac5507790a87810061a19dadec36eb328a222eaTao Liejun 1791ac5507790a87810061a19dadec36eb328a222eaTao Liejun public NotificationUpdateThread() { 1801ac5507790a87810061a19dadec36eb328a222eaTao Liejun super("Notification Update Thread"); 1811ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 1821ac5507790a87810061a19dadec36eb328a222eaTao Liejun 1831ac5507790a87810061a19dadec36eb328a222eaTao Liejun @Override 1841ac5507790a87810061a19dadec36eb328a222eaTao Liejun public void run() { 1851ac5507790a87810061a19dadec36eb328a222eaTao Liejun Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 186eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao synchronized (BluetoothOppNotification.this) { 187eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao if (mUpdateNotificationThread != this) { 188eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao throw new IllegalStateException( 189eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao "multiple UpdateThreads in BluetoothOppNotification"); 1901ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 191eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao mPendingUpdate = 0; 192eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao } 193eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao updateActiveNotification(); 194eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao updateCompletedNotification(); 195eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao updateIncomingFileConfirmNotification(); 196eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao synchronized (BluetoothOppNotification.this) { 197eb77c4b1d9aa71d7dd8dd934e9d1971583f9c0e2Liejun Tao mUpdateNotificationThread = null; 1981ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 1991ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 20009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 20109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 20209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private void updateActiveNotification() { 20309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly // Active transfers 20409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Cursor cursor = mContext.getContentResolver().query(BluetoothShare.CONTENT_URI, null, 20509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly WHERE_RUNNING, null, BluetoothShare._ID); 20609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (cursor == null) { 20709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return; 20809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 20909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 2105cc617943765df27844e459362c4bc1821305216Lixin Yue // If there is active transfers, then no need to update completed transfer 2115cc617943765df27844e459362c4bc1821305216Lixin Yue // notifications 2125cc617943765df27844e459362c4bc1821305216Lixin Yue if (cursor.getCount() > 0) { 2135cc617943765df27844e459362c4bc1821305216Lixin Yue mUpdateCompleteNotification = false; 2145cc617943765df27844e459362c4bc1821305216Lixin Yue } else { 2155cc617943765df27844e459362c4bc1821305216Lixin Yue mUpdateCompleteNotification = true; 2165cc617943765df27844e459362c4bc1821305216Lixin Yue } 2175cc617943765df27844e459362c4bc1821305216Lixin Yue if (V) Log.v(TAG, "mUpdateCompleteNotification = " + mUpdateCompleteNotification); 2185cc617943765df27844e459362c4bc1821305216Lixin Yue 21909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly // Collate the notifications 2205cc617943765df27844e459362c4bc1821305216Lixin Yue final int timestampIndex = cursor.getColumnIndexOrThrow(BluetoothShare.TIMESTAMP); 2215cc617943765df27844e459362c4bc1821305216Lixin Yue final int directionIndex = cursor.getColumnIndexOrThrow(BluetoothShare.DIRECTION); 2225cc617943765df27844e459362c4bc1821305216Lixin Yue final int idIndex = cursor.getColumnIndexOrThrow(BluetoothShare._ID); 2235cc617943765df27844e459362c4bc1821305216Lixin Yue final int totalBytesIndex = cursor.getColumnIndexOrThrow(BluetoothShare.TOTAL_BYTES); 2245cc617943765df27844e459362c4bc1821305216Lixin Yue final int currentBytesIndex = cursor.getColumnIndexOrThrow(BluetoothShare.CURRENT_BYTES); 2255cc617943765df27844e459362c4bc1821305216Lixin Yue final int dataIndex = cursor.getColumnIndexOrThrow(BluetoothShare._DATA); 2265cc617943765df27844e459362c4bc1821305216Lixin Yue final int filenameHintIndex = cursor.getColumnIndexOrThrow(BluetoothShare.FILENAME_HINT); 2275cc617943765df27844e459362c4bc1821305216Lixin Yue 22809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mNotifications.clear(); 22909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { 2305cc617943765df27844e459362c4bc1821305216Lixin Yue int timeStamp = cursor.getInt(timestampIndex); 2315cc617943765df27844e459362c4bc1821305216Lixin Yue int dir = cursor.getInt(directionIndex); 2325cc617943765df27844e459362c4bc1821305216Lixin Yue int id = cursor.getInt(idIndex); 2335cc617943765df27844e459362c4bc1821305216Lixin Yue int total = cursor.getInt(totalBytesIndex); 2345cc617943765df27844e459362c4bc1821305216Lixin Yue int current = cursor.getInt(currentBytesIndex); 23509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 2365cc617943765df27844e459362c4bc1821305216Lixin Yue String fileName = cursor.getString(dataIndex); 23709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (fileName == null) { 2385cc617943765df27844e459362c4bc1821305216Lixin Yue fileName = cursor.getString(filenameHintIndex); 23909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 24009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (fileName == null) { 24109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly fileName = mContext.getString(R.string.unknown_file); 24209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 24309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 24409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly String batchID = Long.toString(timeStamp); 24509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 24609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly // sending objects in one batch has same timeStamp 24709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mNotifications.containsKey(batchID)) { 24809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly // NOTE: currently no such case 24909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly // Batch sending case 25009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 25109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly NotificationItem item = new NotificationItem(); 25274e5eba4a45ecca87eec3ac1762ca527cc614d78erik.ljungberg item.timeStamp = timeStamp; 25309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly item.id = id; 25409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly item.direction = dir; 25509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (item.direction == BluetoothShare.DIRECTION_OUTBOUND) { 256239bc526513429995c61c4148c105725c395b1a9Jackson Fan item.description = mContext.getString(R.string.notification_sending, fileName); 25709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else if (item.direction == BluetoothShare.DIRECTION_INBOUND) { 258239bc526513429995c61c4148c105725c395b1a9Jackson Fan item.description = mContext 259239bc526513429995c61c4148c105725c395b1a9Jackson Fan .getString(R.string.notification_receiving, fileName); 26009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 261ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "mDirection ERROR!"); 26209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 26309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly item.totalCurrent = current; 26409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly item.totalTotal = total; 26509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 26609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mNotifications.put(batchID, item); 26709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 268ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "ID=" + item.id + "; batchID=" + batchID + "; totoalCurrent" 26909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly + item.totalCurrent + "; totalTotal=" + item.totalTotal); 27009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 27109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 27209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.close(); 27309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 27409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly // Add the notifications 27509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly for (NotificationItem item : mNotifications.values()) { 27609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly // Build the notification object 277dec631a77ab9cc89c4d3867b80cfe300e7cf83e9Jake Hamby // TODO: split description into two rows with filename in second row 278dec631a77ab9cc89c4d3867b80cfe300e7cf83e9Jake Hamby Notification.Builder b = new Notification.Builder(mContext); 279dec631a77ab9cc89c4d3867b80cfe300e7cf83e9Jake Hamby b.setContentTitle(item.description); 280dec631a77ab9cc89c4d3867b80cfe300e7cf83e9Jake Hamby b.setContentInfo( 281dec631a77ab9cc89c4d3867b80cfe300e7cf83e9Jake Hamby BluetoothOppUtility.formatProgressText(item.totalTotal, item.totalCurrent)); 282dec631a77ab9cc89c4d3867b80cfe300e7cf83e9Jake Hamby b.setProgress(item.totalTotal, item.totalCurrent, item.totalTotal == -1); 283dec631a77ab9cc89c4d3867b80cfe300e7cf83e9Jake Hamby b.setWhen(item.timeStamp); 28409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (item.direction == BluetoothShare.DIRECTION_OUTBOUND) { 285dec631a77ab9cc89c4d3867b80cfe300e7cf83e9Jake Hamby b.setSmallIcon(android.R.drawable.stat_sys_upload); 28609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else if (item.direction == BluetoothShare.DIRECTION_INBOUND) { 287dec631a77ab9cc89c4d3867b80cfe300e7cf83e9Jake Hamby b.setSmallIcon(android.R.drawable.stat_sys_download); 28809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 289ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "mDirection ERROR!"); 29009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 291dec631a77ab9cc89c4d3867b80cfe300e7cf83e9Jake Hamby b.setOngoing(true); 29209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 29309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Intent intent = new Intent(Constants.ACTION_LIST); 29409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly intent.setClassName(Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName()); 29509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly intent.setData(Uri.parse(BluetoothShare.CONTENT_URI + "/" + item.id)); 29609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 297dec631a77ab9cc89c4d3867b80cfe300e7cf83e9Jake Hamby b.setContentIntent(PendingIntent.getBroadcast(mContext, 0, intent, 0)); 298dec631a77ab9cc89c4d3867b80cfe300e7cf83e9Jake Hamby mNotificationMgr.notify(item.id, b.getNotification()); 2995cc617943765df27844e459362c4bc1821305216Lixin Yue 3005cc617943765df27844e459362c4bc1821305216Lixin Yue mActiveNotificationId = item.id; 30109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 30209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 30309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 30409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private void updateCompletedNotification() { 3055cc617943765df27844e459362c4bc1821305216Lixin Yue String title; 3065cc617943765df27844e459362c4bc1821305216Lixin Yue String caption; 3075cc617943765df27844e459362c4bc1821305216Lixin Yue long timeStamp = 0; 3085cc617943765df27844e459362c4bc1821305216Lixin Yue int outboundSuccNumber = 0; 3095cc617943765df27844e459362c4bc1821305216Lixin Yue int outboundFailNumber = 0; 3105cc617943765df27844e459362c4bc1821305216Lixin Yue int outboundNum; 3115cc617943765df27844e459362c4bc1821305216Lixin Yue int inboundNum; 3125cc617943765df27844e459362c4bc1821305216Lixin Yue int inboundSuccNumber = 0; 3135cc617943765df27844e459362c4bc1821305216Lixin Yue int inboundFailNumber = 0; 3145cc617943765df27844e459362c4bc1821305216Lixin Yue Intent intent; 3155cc617943765df27844e459362c4bc1821305216Lixin Yue 3165cc617943765df27844e459362c4bc1821305216Lixin Yue // If there is active transfer, no need to update complete transfer 3175cc617943765df27844e459362c4bc1821305216Lixin Yue // notification 3185cc617943765df27844e459362c4bc1821305216Lixin Yue if (!mUpdateCompleteNotification) { 3195cc617943765df27844e459362c4bc1821305216Lixin Yue if (V) Log.v(TAG, "No need to update complete notification"); 3205cc617943765df27844e459362c4bc1821305216Lixin Yue return; 3215cc617943765df27844e459362c4bc1821305216Lixin Yue } 3225cc617943765df27844e459362c4bc1821305216Lixin Yue 3235cc617943765df27844e459362c4bc1821305216Lixin Yue // After merge complete notifications to 2 notifications, there is no 3245cc617943765df27844e459362c4bc1821305216Lixin Yue // chance to update the active notifications to complete notifications 3255cc617943765df27844e459362c4bc1821305216Lixin Yue // as before. So need cancel the active notification after the active 3265cc617943765df27844e459362c4bc1821305216Lixin Yue // transfer becomes complete. 3275cc617943765df27844e459362c4bc1821305216Lixin Yue if (mNotificationMgr != null && mActiveNotificationId != 0) { 3285cc617943765df27844e459362c4bc1821305216Lixin Yue mNotificationMgr.cancel(mActiveNotificationId); 3295cc617943765df27844e459362c4bc1821305216Lixin Yue if (V) Log.v(TAG, "ongoing transfer notification was removed"); 3305cc617943765df27844e459362c4bc1821305216Lixin Yue } 3315cc617943765df27844e459362c4bc1821305216Lixin Yue 3325cc617943765df27844e459362c4bc1821305216Lixin Yue // Creating outbound notification 33309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Cursor cursor = mContext.getContentResolver().query(BluetoothShare.CONTENT_URI, null, 3345cc617943765df27844e459362c4bc1821305216Lixin Yue WHERE_COMPLETED_OUTBOUND, null, BluetoothShare.TIMESTAMP + " DESC"); 33509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (cursor == null) { 33609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return; 33709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 33809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 3395cc617943765df27844e459362c4bc1821305216Lixin Yue final int timestampIndex = cursor.getColumnIndexOrThrow(BluetoothShare.TIMESTAMP); 3405cc617943765df27844e459362c4bc1821305216Lixin Yue final int statusIndex = cursor.getColumnIndexOrThrow(BluetoothShare.STATUS); 34109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 3425cc617943765df27844e459362c4bc1821305216Lixin Yue for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { 3435cc617943765df27844e459362c4bc1821305216Lixin Yue if (cursor.isFirst()) { 3445cc617943765df27844e459362c4bc1821305216Lixin Yue // Display the time for the latest transfer 3455cc617943765df27844e459362c4bc1821305216Lixin Yue timeStamp = cursor.getLong(timestampIndex); 34609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 3475cc617943765df27844e459362c4bc1821305216Lixin Yue int status = cursor.getInt(statusIndex); 34809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 34909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (BluetoothShare.isStatusError(status)) { 3505cc617943765df27844e459362c4bc1821305216Lixin Yue outboundFailNumber++; 35109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 3525cc617943765df27844e459362c4bc1821305216Lixin Yue outboundSuccNumber++; 35309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 3545cc617943765df27844e459362c4bc1821305216Lixin Yue } 3555cc617943765df27844e459362c4bc1821305216Lixin Yue if (V) Log.v(TAG, "outbound: succ-" + outboundSuccNumber + " fail-" + outboundFailNumber); 3565cc617943765df27844e459362c4bc1821305216Lixin Yue cursor.close(); 35709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 3585cc617943765df27844e459362c4bc1821305216Lixin Yue outboundNum = outboundSuccNumber + outboundFailNumber; 3595cc617943765df27844e459362c4bc1821305216Lixin Yue // create the outbound notification 360509a6cd43906cce5f9bc78a83bd2058a4e5249e7Lixin Yue if (outboundNum > 0) { 361de773e60fed15a4ad13325089a5609c9bc6ede59Lixin Yue Notification outNoti = new Notification(); 362de773e60fed15a4ad13325089a5609c9bc6ede59Lixin Yue outNoti.icon = android.R.drawable.stat_sys_upload_done; 363509a6cd43906cce5f9bc78a83bd2058a4e5249e7Lixin Yue title = mContext.getString(R.string.outbound_noti_title); 3645cc617943765df27844e459362c4bc1821305216Lixin Yue caption = mContext.getString(R.string.noti_caption, outboundSuccNumber, 3655cc617943765df27844e459362c4bc1821305216Lixin Yue outboundFailNumber); 366509a6cd43906cce5f9bc78a83bd2058a4e5249e7Lixin Yue intent = new Intent(Constants.ACTION_OPEN_OUTBOUND_TRANSFER); 367509a6cd43906cce5f9bc78a83bd2058a4e5249e7Lixin Yue intent.setClassName(Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName()); 368de773e60fed15a4ad13325089a5609c9bc6ede59Lixin Yue outNoti.setLatestEventInfo(mContext, title, caption, PendingIntent.getBroadcast( 3695cc617943765df27844e459362c4bc1821305216Lixin Yue mContext, 0, intent, 0)); 370ec6f2d44491bf1e3ffa7c75875985f9c16cf721dLixin Yue intent = new Intent(Constants.ACTION_COMPLETE_HIDE); 371ec6f2d44491bf1e3ffa7c75875985f9c16cf721dLixin Yue intent.setClassName(Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName()); 372ec6f2d44491bf1e3ffa7c75875985f9c16cf721dLixin Yue outNoti.deleteIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0); 373de773e60fed15a4ad13325089a5609c9bc6ede59Lixin Yue outNoti.when = timeStamp; 374de773e60fed15a4ad13325089a5609c9bc6ede59Lixin Yue mNotificationMgr.notify(NOTIFICATION_ID_OUTBOUND, outNoti); 3755cc617943765df27844e459362c4bc1821305216Lixin Yue } else { 376de773e60fed15a4ad13325089a5609c9bc6ede59Lixin Yue if (mNotificationMgr != null) { 3775cc617943765df27844e459362c4bc1821305216Lixin Yue mNotificationMgr.cancel(NOTIFICATION_ID_OUTBOUND); 3785cc617943765df27844e459362c4bc1821305216Lixin Yue if (V) Log.v(TAG, "outbound notification was removed."); 3795cc617943765df27844e459362c4bc1821305216Lixin Yue } 3805cc617943765df27844e459362c4bc1821305216Lixin Yue } 3815cc617943765df27844e459362c4bc1821305216Lixin Yue 3825cc617943765df27844e459362c4bc1821305216Lixin Yue // Creating inbound notification 3835cc617943765df27844e459362c4bc1821305216Lixin Yue cursor = mContext.getContentResolver().query(BluetoothShare.CONTENT_URI, null, 3845cc617943765df27844e459362c4bc1821305216Lixin Yue WHERE_COMPLETED_INBOUND, null, BluetoothShare.TIMESTAMP + " DESC"); 3855cc617943765df27844e459362c4bc1821305216Lixin Yue if (cursor == null) { 3865cc617943765df27844e459362c4bc1821305216Lixin Yue return; 3875cc617943765df27844e459362c4bc1821305216Lixin Yue } 38809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 3895cc617943765df27844e459362c4bc1821305216Lixin Yue for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { 3905cc617943765df27844e459362c4bc1821305216Lixin Yue if (cursor.isFirst()) { 3915cc617943765df27844e459362c4bc1821305216Lixin Yue // Display the time for the latest transfer 3925cc617943765df27844e459362c4bc1821305216Lixin Yue timeStamp = cursor.getLong(timestampIndex); 3935cc617943765df27844e459362c4bc1821305216Lixin Yue } 3945cc617943765df27844e459362c4bc1821305216Lixin Yue int status = cursor.getInt(statusIndex); 3955cc617943765df27844e459362c4bc1821305216Lixin Yue 3965cc617943765df27844e459362c4bc1821305216Lixin Yue if (BluetoothShare.isStatusError(status)) { 3975cc617943765df27844e459362c4bc1821305216Lixin Yue inboundFailNumber++; 3985cc617943765df27844e459362c4bc1821305216Lixin Yue } else { 3995cc617943765df27844e459362c4bc1821305216Lixin Yue inboundSuccNumber++; 4005cc617943765df27844e459362c4bc1821305216Lixin Yue } 40109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 4025cc617943765df27844e459362c4bc1821305216Lixin Yue if (V) Log.v(TAG, "inbound: succ-" + inboundSuccNumber + " fail-" + inboundFailNumber); 40309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.close(); 4045cc617943765df27844e459362c4bc1821305216Lixin Yue 4055cc617943765df27844e459362c4bc1821305216Lixin Yue inboundNum = inboundSuccNumber + inboundFailNumber; 4065cc617943765df27844e459362c4bc1821305216Lixin Yue // create the inbound notification 407509a6cd43906cce5f9bc78a83bd2058a4e5249e7Lixin Yue if (inboundNum > 0) { 408de773e60fed15a4ad13325089a5609c9bc6ede59Lixin Yue Notification inNoti = new Notification(); 409de773e60fed15a4ad13325089a5609c9bc6ede59Lixin Yue inNoti.icon = android.R.drawable.stat_sys_download_done; 410509a6cd43906cce5f9bc78a83bd2058a4e5249e7Lixin Yue title = mContext.getString(R.string.inbound_noti_title); 4115cc617943765df27844e459362c4bc1821305216Lixin Yue caption = mContext.getString(R.string.noti_caption, inboundSuccNumber, 4125cc617943765df27844e459362c4bc1821305216Lixin Yue inboundFailNumber); 413509a6cd43906cce5f9bc78a83bd2058a4e5249e7Lixin Yue intent = new Intent(Constants.ACTION_OPEN_INBOUND_TRANSFER); 414509a6cd43906cce5f9bc78a83bd2058a4e5249e7Lixin Yue intent.setClassName(Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName()); 415de773e60fed15a4ad13325089a5609c9bc6ede59Lixin Yue inNoti.setLatestEventInfo(mContext, title, caption, PendingIntent.getBroadcast( 4165cc617943765df27844e459362c4bc1821305216Lixin Yue mContext, 0, intent, 0)); 417ec6f2d44491bf1e3ffa7c75875985f9c16cf721dLixin Yue intent = new Intent(Constants.ACTION_COMPLETE_HIDE); 418ec6f2d44491bf1e3ffa7c75875985f9c16cf721dLixin Yue intent.setClassName(Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName()); 419ec6f2d44491bf1e3ffa7c75875985f9c16cf721dLixin Yue inNoti.deleteIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0); 420de773e60fed15a4ad13325089a5609c9bc6ede59Lixin Yue inNoti.when = timeStamp; 421de773e60fed15a4ad13325089a5609c9bc6ede59Lixin Yue mNotificationMgr.notify(NOTIFICATION_ID_INBOUND, inNoti); 4225cc617943765df27844e459362c4bc1821305216Lixin Yue } else { 423de773e60fed15a4ad13325089a5609c9bc6ede59Lixin Yue if (mNotificationMgr != null) { 4245cc617943765df27844e459362c4bc1821305216Lixin Yue mNotificationMgr.cancel(NOTIFICATION_ID_INBOUND); 4255cc617943765df27844e459362c4bc1821305216Lixin Yue if (V) Log.v(TAG, "inbound notification was removed."); 4265cc617943765df27844e459362c4bc1821305216Lixin Yue } 4275cc617943765df27844e459362c4bc1821305216Lixin Yue } 42809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 42909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 43009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private void updateIncomingFileConfirmNotification() { 43109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Cursor cursor = mContext.getContentResolver().query(BluetoothShare.CONTENT_URI, null, 43209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly WHERE_CONFIRM_PENDING, null, BluetoothShare._ID); 43309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 43409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (cursor == null) { 43509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return; 43609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 43709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 43809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { 439b0b662a98d8b7c099ee706d0e08bd239adcdffc7Jaikumar Ganesh CharSequence title = 440b0b662a98d8b7c099ee706d0e08bd239adcdffc7Jaikumar Ganesh mContext.getText(R.string.incoming_file_confirm_Notification_title); 441b0b662a98d8b7c099ee706d0e08bd239adcdffc7Jaikumar Ganesh CharSequence caption = mContext 442b0b662a98d8b7c099ee706d0e08bd239adcdffc7Jaikumar Ganesh .getText(R.string.incoming_file_confirm_Notification_caption); 44309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int id = cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare._ID)); 444dc3bacd6eb626a93f2c3c4c62b3ef6aa9e575d92Lixin Yue long timeStamp = cursor.getLong(cursor.getColumnIndexOrThrow(BluetoothShare.TIMESTAMP)); 44509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + id); 44609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 44709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Notification n = new Notification(); 448464d9d216ab1a6cf192e3e526596073c7e35e4a7L.X.YUE n.icon = R.drawable.bt_incomming_file_notification; 44909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly n.flags |= Notification.FLAG_ONLY_ALERT_ONCE; 450b0b662a98d8b7c099ee706d0e08bd239adcdffc7Jaikumar Ganesh n.flags |= Notification.FLAG_ONGOING_EVENT; 45109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly n.defaults = Notification.DEFAULT_SOUND; 45209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly n.tickerText = title; 453b0b662a98d8b7c099ee706d0e08bd239adcdffc7Jaikumar Ganesh 45409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Intent intent = new Intent(Constants.ACTION_INCOMING_FILE_CONFIRM); 45509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly intent.setClassName(Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName()); 45609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly intent.setData(contentUri); 4576ee2d0e0405a074cf827e0c0ac4bfbffd1850ceaLixin Yue 4586ee2d0e0405a074cf827e0c0ac4bfbffd1850ceaLixin Yue n.when = timeStamp; 45909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly n.setLatestEventInfo(mContext, title, caption, PendingIntent.getBroadcast(mContext, 0, 46009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly intent, 0)); 46109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 46209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly intent = new Intent(Constants.ACTION_HIDE); 46309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly intent.setClassName(Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName()); 46409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly intent.setData(contentUri); 46509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly n.deleteIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0); 46609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 46709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mNotificationMgr.notify(id, n); 46809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 46909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.close(); 47009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 47109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly} 472