BluetoothOppTransferHistory.java revision 5cc617943765df27844e459362c4bc1821305216
1/* 2 * Copyright (c) 2008-2009, Motorola, Inc. 3 * 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * - Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 12 * - Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * - Neither the name of the Motorola, Inc. nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33package com.android.bluetooth.opp; 34 35import com.android.bluetooth.R; 36 37import android.app.Activity; 38import android.app.AlertDialog; 39import android.content.DialogInterface; 40import android.content.Intent; 41import android.database.Cursor; 42import android.net.Uri; 43import android.os.Bundle; 44import android.util.Log; 45import android.view.ContextMenu; 46import android.view.Menu; 47import android.view.MenuInflater; 48import android.view.MenuItem; 49import android.view.View; 50import android.view.ContextMenu.ContextMenuInfo; 51import android.widget.AdapterView; 52import android.widget.ListView; 53import android.widget.AdapterView.OnItemClickListener; 54 55/** 56 * View showing the user's finished bluetooth opp transfers that the user does 57 * not confirm. Including outbound and inbound transfers, both successful and 58 * failed. * 59 */ 60public class BluetoothOppTransferHistory extends Activity implements 61 View.OnCreateContextMenuListener, OnItemClickListener { 62 private static final String TAG = "BluetoothOppTransferHistory"; 63 64 private static final boolean D = Constants.DEBUG; 65 66 private static final boolean V = Constants.VERBOSE; 67 68 private ListView mListView; 69 70 private Cursor mTransferCursor; 71 72 private BluetoothOppTransferAdapter mTransferAdapter; 73 74 private int mIdColumnId; 75 76 private int mContextMenuPosition; 77 78 @Override 79 public void onCreate(Bundle icicle) { 80 super.onCreate(icicle); 81 setContentView(R.layout.bluetooth_transfers_page); 82 mListView = (ListView)findViewById(R.id.list); 83 mListView.setEmptyView(findViewById(R.id.empty)); 84 85 String direction; 86 int dir = getIntent().getIntExtra("direction", 0); 87 if (dir == BluetoothShare.DIRECTION_OUTBOUND) { 88 setTitle(getText(R.string.outbound_history_title)); 89 direction = "(" + BluetoothShare.DIRECTION + " == " + BluetoothShare.DIRECTION_OUTBOUND 90 + ")"; 91 } else { 92 setTitle(getText(R.string.inbound_history_title)); 93 direction = "(" + BluetoothShare.DIRECTION + " == " + BluetoothShare.DIRECTION_INBOUND 94 + ")"; 95 } 96 97 final String selection = BluetoothShare.STATUS + " >= '200' AND " + "(" 98 + BluetoothShare.VISIBILITY + " IS NULL OR " + BluetoothShare.VISIBILITY + " == '" 99 + BluetoothShare.VISIBILITY_VISIBLE + "'" + ")" + " AND " + direction; 100 final String sortOrder = BluetoothShare.TIMESTAMP + " DESC"; 101 102 mTransferCursor = managedQuery(BluetoothShare.CONTENT_URI, new String[] { 103 "_id", BluetoothShare.FILENAME_HINT, BluetoothShare.STATUS, 104 BluetoothShare.TOTAL_BYTES, BluetoothShare._DATA, BluetoothShare.TIMESTAMP, 105 BluetoothShare.VISIBILITY, BluetoothShare.DESTINATION, BluetoothShare.DIRECTION 106 }, selection, sortOrder); 107 108 // only attach everything to the listbox if we can access 109 // the transfer database. Otherwise, just show it empty 110 if (mTransferCursor != null) { 111 mIdColumnId = mTransferCursor.getColumnIndexOrThrow(BluetoothShare._ID); 112 // Create a list "controller" for the data 113 mTransferAdapter = new BluetoothOppTransferAdapter(this, 114 R.layout.bluetooth_transfer_item, mTransferCursor); 115 mListView.setAdapter(mTransferAdapter); 116 mListView.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET); 117 mListView.setOnCreateContextMenuListener(this); 118 mListView.setOnItemClickListener(this); 119 } 120 } 121 122 @Override 123 public boolean onCreateOptionsMenu(Menu menu) { 124 if (mTransferCursor != null) { 125 MenuInflater inflater = getMenuInflater(); 126 inflater.inflate(R.menu.transferhistory, menu); 127 } 128 return true; 129 } 130 131 @Override 132 public boolean onPrepareOptionsMenu(Menu menu) { 133 boolean showClear = getClearableCount() > 0; 134 menu.findItem(R.id.transfer_menu_clear_all).setEnabled(showClear); 135 return super.onPrepareOptionsMenu(menu); 136 } 137 138 @Override 139 public boolean onOptionsItemSelected(MenuItem item) { 140 switch (item.getItemId()) { 141 case R.id.transfer_menu_clear_all: 142 promptClearList(); 143 return true; 144 } 145 return false; 146 } 147 148 @Override 149 public boolean onContextItemSelected(MenuItem item) { 150 mTransferCursor.moveToPosition(mContextMenuPosition); 151 switch (item.getItemId()) { 152 case R.id.transfer_menu_open: 153 openCompleteTransfer(); 154 return true; 155 156 case R.id.transfer_menu_clear: 157 int sessionId = mTransferCursor.getInt(mIdColumnId); 158 Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + sessionId); 159 BluetoothOppUtility.updateVisibilityToHidden(this, contentUri); 160 return true; 161 } 162 return false; 163 } 164 165 @Override 166 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 167 if (mTransferCursor != null) { 168 AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo; 169 mTransferCursor.moveToPosition(info.position); 170 mContextMenuPosition = info.position; 171 172 String fileName = mTransferCursor.getString(mTransferCursor 173 .getColumnIndexOrThrow(BluetoothShare.FILENAME_HINT)); 174 if (fileName == null) { 175 fileName = this.getString(R.string.unknown_file); 176 } 177 menu.setHeaderTitle(fileName); 178 179 MenuInflater inflater = getMenuInflater(); 180 inflater.inflate(R.menu.transferhistorycontextfinished, menu); 181 } 182 } 183 184 /** 185 * Prompt the user if they would like to clear the transfer history 186 */ 187 private void promptClearList() { 188 new AlertDialog.Builder(this).setTitle(R.string.transfer_clear_dlg_title).setMessage( 189 R.string.transfer_clear_dlg_msg).setPositiveButton(android.R.string.ok, 190 new DialogInterface.OnClickListener() { 191 public void onClick(DialogInterface dialog, int whichButton) { 192 clearAllDownloads(); 193 } 194 }).setNegativeButton(android.R.string.cancel, null).show(); 195 } 196 197 /** 198 * Get the number of finished transfers, including error and success. 199 */ 200 private int getClearableCount() { 201 int count = 0; 202 if (mTransferCursor.moveToFirst()) { 203 while (!mTransferCursor.isAfterLast()) { 204 int statusColumnId = mTransferCursor.getColumnIndexOrThrow(BluetoothShare.STATUS); 205 int status = mTransferCursor.getInt(statusColumnId); 206 if (BluetoothShare.isStatusCompleted(status)) { 207 count++; 208 } 209 mTransferCursor.moveToNext(); 210 } 211 } 212 return count; 213 } 214 215 /** 216 * Clear all finished transfers, error and success transfer items. 217 */ 218 private void clearAllDownloads() { 219 if (mTransferCursor.moveToFirst()) { 220 while (!mTransferCursor.isAfterLast()) { 221 int sessionId = mTransferCursor.getInt(mIdColumnId); 222 Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + sessionId); 223 BluetoothOppUtility.updateVisibilityToHidden(this, contentUri); 224 225 mTransferCursor.moveToNext(); 226 } 227 } 228 } 229 230 /* 231 * (non-Javadoc) 232 * @see 233 * android.widget.AdapterView.OnItemClickListener#onItemClick(android.widget 234 * .AdapterView, android.view.View, int, long) 235 */ 236 public void onItemClick(AdapterView parent, View view, int position, long id) { 237 // Open the selected item 238 mTransferCursor.moveToPosition(position); 239 openCompleteTransfer(); 240 } 241 242 /** 243 * Open the selected finished transfer. mDownloadCursor must be moved to 244 * appropriate position before calling this function 245 */ 246 private void openCompleteTransfer() { 247 int sessionId = mTransferCursor.getInt(mIdColumnId); 248 Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + sessionId); 249 BluetoothOppTransferInfo transInfo = new BluetoothOppTransferInfo(); 250 transInfo = BluetoothOppUtility.queryRecord(this, contentUri); 251 if (transInfo == null) { 252 Log.e(TAG, "Error: Can not get data from db"); 253 return; 254 } 255 if (transInfo.mDirection == BluetoothShare.DIRECTION_INBOUND 256 && BluetoothShare.isStatusSuccess(transInfo.mStatus)) { 257 // if received file successfully, open this file 258 BluetoothOppUtility.updateVisibilityToHidden(this, contentUri); 259 BluetoothOppUtility.openReceivedFile(this, transInfo.mFileName, transInfo.mFileType, 260 transInfo.mTimeStamp, contentUri); 261 } else { 262 Intent in = new Intent(this, BluetoothOppTransferActivity.class); 263 in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 264 in.setData(contentUri); 265 this.startActivity(in); 266 } 267 } 268} 269