HandoverTransfer.java revision be1939b4b6003ac7a65fcb95a3912f5e1ce8e75f
1be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectpackage com.android.nfc.handover; 2be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 3be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.app.Notification; 4be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.app.NotificationManager; 5be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.app.PendingIntent; 6be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.app.Notification.Builder; 7be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.bluetooth.BluetoothDevice; 8be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.content.ContentResolver; 9be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.content.Context; 10be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.content.Intent; 11be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.media.MediaScannerConnection; 12be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.net.Uri; 13be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.os.Environment; 14be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.os.Handler; 15be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.os.Looper; 16be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.os.Message; 17be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.os.SystemClock; 18be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.os.UserHandle; 19be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.util.Log; 20be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 21be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport com.android.nfc.R; 22be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 23be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport java.io.File; 24be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport java.text.SimpleDateFormat; 25be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport java.util.ArrayList; 26be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport java.util.Date; 27be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport java.util.HashMap; 28be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 29be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project/** 30be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * A HandoverTransfer object represents a set of files 31be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * that were received through NFC connection handover 32be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * from the same source address. 33be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * 34be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * For Bluetooth, files are received through OPP, and 35be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * we have no knowledge how many files will be transferred 36be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * as part of a single transaction. 37be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * Hence, a transfer has a notion of being "alive": if 38be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * the last update to a transfer was within WAIT_FOR_NEXT_TRANSFER_MS 39be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * milliseconds, we consider a new file transfer from the 40be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * same source address as part of the same transfer. 41be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * The corresponding URIs will be grouped in a single folder. 42be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * 43be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project */ 44be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectpublic class HandoverTransfer implements Handler.Callback, 45be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project MediaScannerConnection.OnScanCompletedListener { 46be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 47be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project interface Callback { 48be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project void onTransferComplete(HandoverTransfer transfer, boolean success); 49be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project }; 50be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 51be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project static final String TAG = "HandoverTransfer"; 52be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 53be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project static final Boolean DBG = true; 54be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 55be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // In the states below we still accept new file transfer 56be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project static final int STATE_NEW = 0; 57be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project static final int STATE_IN_PROGRESS = 1; 58be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project static final int STATE_W4_NEXT_TRANSFER = 2; 59be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 60be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // In the states below no new files are accepted. 61be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project static final int STATE_W4_MEDIA_SCANNER = 3; 62be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project static final int STATE_FAILED = 4; 63be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project static final int STATE_SUCCESS = 5; 64be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project static final int STATE_CANCELLED = 6; 65be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 66be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project static final int MSG_NEXT_TRANSFER_TIMER = 0; 67be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project static final int MSG_TRANSFER_TIMEOUT = 1; 68be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 69be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // We need to receive an update within this time period 70be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // to still consider this transfer to be "alive" (ie 71be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // a reason to keep the handover transport enabled). 72be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project static final int ALIVE_CHECK_MS = 20000; 73be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 74be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // The amount of time to wait for a new transfer 75be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // once the current one completes. 76be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project static final int WAIT_FOR_NEXT_TRANSFER_MS = 4000; 77be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 78be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project static final String BEAM_DIR = "beam"; 79be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 80be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project final boolean mIncoming; // whether this is an incoming transfer 81be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project final int mTransferId; // Unique ID of this transfer used for notifications 82be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project final PendingIntent mCancelIntent; 83be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project final Context mContext; 84be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project final Handler mHandler; 85be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project final NotificationManager mNotificationManager; 86be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project final BluetoothDevice mRemoteDevice; 87be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project final Callback mCallback; 88be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 89be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // Variables below are only accessed on the main thread 90be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project int mState; 91be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project boolean mCalledBack; 92be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project Long mLastUpdate; // Last time an event occurred for this transfer 93be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project float mProgress; // Progress in range [0..1] 94be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project ArrayList<Uri> mBtUris; // Received uris from Bluetooth OPP 95be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project ArrayList<String> mBtMimeTypes; // Mime-types received from Bluetooth OPP 96be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 97be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project ArrayList<String> mPaths; // Raw paths on the filesystem for Beam-stored files 98be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project HashMap<String, String> mMimeTypes; // Mime-types associated with each path 99be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project HashMap<String, Uri> mMediaUris; // URIs found by the media scanner for each path 100be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project int mUrisScanned; 101be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 102be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project public HandoverTransfer(Context context, Callback callback, 103be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project PendingHandoverTransfer pendingTransfer) { 104be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mContext = context; 105be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mCallback = callback; 106be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mRemoteDevice = pendingTransfer.remoteDevice; 107be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mIncoming = pendingTransfer.incoming; 108be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mTransferId = pendingTransfer.id; 109be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mLastUpdate = SystemClock.elapsedRealtime(); 110be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mProgress = 0.0f; 111be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mState = STATE_NEW; 112be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mBtUris = new ArrayList<Uri>(); 113be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mBtMimeTypes = new ArrayList<String>(); 114be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mPaths = new ArrayList<String>(); 115be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mMimeTypes = new HashMap<String, String>(); 116be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mMediaUris = new HashMap<String, Uri>(); 117be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mCancelIntent = buildCancelIntent(); 118be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mUrisScanned = 0; 119be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 120be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mHandler = new Handler(Looper.getMainLooper(), this); 121be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mHandler.sendEmptyMessageDelayed(MSG_TRANSFER_TIMEOUT, ALIVE_CHECK_MS); 122be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mNotificationManager = (NotificationManager) mContext.getSystemService( 123be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project Context.NOTIFICATION_SERVICE); 124be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 125be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 126be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project void whitelistOppDevice(BluetoothDevice device) { 127be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (DBG) Log.d(TAG, "Whitelisting " + device + " for BT OPP"); 128be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project Intent intent = new Intent(HandoverManager.ACTION_WHITELIST_DEVICE); 129be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 130be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT); 131be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 132be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 133be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project public void updateFileProgress(float progress) { 134be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (!isRunning()) return; // Ignore when we're no longer running 135be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 136be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mHandler.removeMessages(MSG_NEXT_TRANSFER_TIMER); 137be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 138be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project this.mProgress = progress; 139be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 140be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // We're still receiving data from this device - keep it in 141be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // the whitelist for a while longer 142be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (mIncoming) whitelistOppDevice(mRemoteDevice); 143be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 144be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project updateStateAndNotification(STATE_IN_PROGRESS); 145be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 146be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 147be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project public void finishTransfer(boolean success, Uri uri, String mimeType) { 148be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (!isRunning()) return; // Ignore when we're no longer running 149be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 150be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (success && uri != null) { 151be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (DBG) Log.d(TAG, "Transfer success, uri " + uri + " mimeType " + mimeType); 152be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project this.mProgress = 1.0f; 153be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (mimeType == null) { 154be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mimeType = BluetoothOppHandover.getMimeTypeForUri(mContext, uri); 155be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 156be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (mimeType != null) { 157be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mBtUris.add(uri); 158be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mBtMimeTypes.add(mimeType); 159be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } else { 160be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (DBG) Log.d(TAG, "Could not get mimeType for file."); 161be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 162be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } else { 163be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project Log.e(TAG, "Handover transfer failed"); 164be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // Do wait to see if there's another file coming. 165be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 166be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mHandler.removeMessages(MSG_NEXT_TRANSFER_TIMER); 167be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mHandler.sendEmptyMessageDelayed(MSG_NEXT_TRANSFER_TIMER, WAIT_FOR_NEXT_TRANSFER_MS); 168be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project updateStateAndNotification(STATE_W4_NEXT_TRANSFER); 169be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 170be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 171be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project public boolean isRunning() { 172be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (mState != STATE_NEW && mState != STATE_IN_PROGRESS && mState != STATE_W4_NEXT_TRANSFER) { 173be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project return false; 174be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } else { 175be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project return true; 176be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 177be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 178be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 179be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project void cancel() { 180be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (!isRunning()) return; 181be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 182be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // Delete all files received so far 183be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project for (Uri uri : mBtUris) { 184be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project File file = new File(uri.getPath()); 185be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (file.exists()) file.delete(); 186be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 187be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 188be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project updateStateAndNotification(STATE_CANCELLED); 189be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 190be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 191be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project void updateNotification() { 192be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (!mIncoming) return; // No notifications for outgoing transfers 193be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 194be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project Builder notBuilder = new Notification.Builder(mContext); 195be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 196be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (mState == STATE_NEW || mState == STATE_IN_PROGRESS || 197be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mState == STATE_W4_NEXT_TRANSFER || mState == STATE_W4_MEDIA_SCANNER) { 198be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setAutoCancel(false); 199be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setSmallIcon(android.R.drawable.stat_sys_download); 200be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setTicker(mContext.getString(R.string.beam_progress)); 201be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setContentTitle(mContext.getString(R.string.beam_progress)); 202be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.addAction(R.drawable.ic_menu_cancel_holo_dark, 203be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mContext.getString(R.string.cancel), mCancelIntent); 204be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setDeleteIntent(mCancelIntent); 205be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // We do have progress indication on a per-file basis, but in a multi-file 206be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // transfer we don't know the total progress. So for now, just show an 207be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // indeterminate progress bar. 208be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setProgress(100, 0, true); 209be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } else if (mState == STATE_SUCCESS) { 210be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setAutoCancel(true); 211be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setSmallIcon(android.R.drawable.stat_sys_download_done); 212be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setTicker(mContext.getString(R.string.beam_complete)); 213be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setContentTitle(mContext.getString(R.string.beam_complete)); 214be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setContentText(mContext.getString(R.string.beam_touch_to_view)); 215be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 216be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project Intent viewIntent = buildViewIntent(); 217be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project PendingIntent contentIntent = PendingIntent.getActivity( 218be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mContext, 0, viewIntent, 0, null); 219be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 220be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setContentIntent(contentIntent); 221be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } else if (mState == STATE_FAILED) { 222be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setAutoCancel(false); 223be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setSmallIcon(android.R.drawable.stat_sys_download_done); 224be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setTicker(mContext.getString(R.string.beam_failed)); 225be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setContentTitle(mContext.getString(R.string.beam_failed)); 226be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } else if (mState == STATE_CANCELLED) { 227be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setAutoCancel(false); 228be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setSmallIcon(android.R.drawable.stat_sys_download_done); 229be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setTicker(mContext.getString(R.string.beam_canceled)); 230be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project notBuilder.setContentTitle(mContext.getString(R.string.beam_canceled)); 231be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } else { 232be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project return; 233be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 234be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 235be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mNotificationManager.notify(null, mTransferId, notBuilder.build()); 236be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 237be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 238be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project void updateStateAndNotification(int newState) { 239be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project this.mState = newState; 240be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project this.mLastUpdate = SystemClock.elapsedRealtime(); 241be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 242be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (mHandler.hasMessages(MSG_TRANSFER_TIMEOUT)) { 243be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // Update timeout timer 244be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mHandler.removeMessages(MSG_TRANSFER_TIMEOUT); 245be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mHandler.sendEmptyMessageDelayed(MSG_TRANSFER_TIMEOUT, ALIVE_CHECK_MS); 246be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 247be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 248be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project updateNotification(); 249be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 250be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if ((mState == STATE_SUCCESS || mState == STATE_FAILED || mState == STATE_CANCELLED) 251be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project && !mCalledBack) { 252be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mCalledBack = true; 253be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // Notify that we're done with this transfer 254be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mCallback.onTransferComplete(this, mState == STATE_SUCCESS); 255be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 256be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 257be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 258be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project void processFiles() { 259be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // Check the amount of files we received in this transfer; 260be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // If more than one, create a separate directory for it. 261be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project String extRoot = Environment.getExternalStorageDirectory().getPath(); 262be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project File beamPath = new File(extRoot + "/" + BEAM_DIR); 263be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 264be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (!checkMediaStorage(beamPath) || mBtUris.size() == 0) { 265be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project Log.e(TAG, "Media storage not valid or no uris received."); 266be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project updateStateAndNotification(STATE_FAILED); 267be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project return; 268be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 269be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 270be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (mBtUris.size() > 1) { 271be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project beamPath = generateMultiplePath(extRoot + "/" + BEAM_DIR + "/"); 272be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (!beamPath.isDirectory() && !beamPath.mkdir()) { 273be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project Log.e(TAG, "Failed to create multiple path " + beamPath.toString()); 274be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project updateStateAndNotification(STATE_FAILED); 275be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project return; 276be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 277be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 278be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 279be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project for (int i = 0; i < mBtUris.size(); i++) { 280be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project Uri uri = mBtUris.get(i); 281be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project String mimeType = mBtMimeTypes.get(i); 282be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 283be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project File srcFile = new File(uri.getPath()); 284be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 285be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project File dstFile = generateUniqueDestination(beamPath.getAbsolutePath(), 286be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project uri.getLastPathSegment()); 287be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (!srcFile.renameTo(dstFile)) { 288be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (DBG) Log.d(TAG, "Failed to rename from " + srcFile + " to " + dstFile); 289be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project srcFile.delete(); 290be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project return; 291be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } else { 292be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mPaths.add(dstFile.getAbsolutePath()); 293be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mMimeTypes.put(dstFile.getAbsolutePath(), mimeType); 294be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (DBG) Log.d(TAG, "Did successful rename from " + srcFile + " to " + dstFile); 295be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 296be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 297be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 298be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // We can either add files to the media provider, or provide an ACTION_VIEW 299be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // intent to the file directly. We base this decision on the mime type 300be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // of the first file; if it's media the platform can deal with, 301be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // use the media provider, if it's something else, just launch an ACTION_VIEW 302be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // on the file. 303be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project String mimeType = mMimeTypes.get(mPaths.get(0)); 304be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (mimeType.startsWith("image/") || mimeType.startsWith("video/") || 305be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mimeType.startsWith("audio/")) { 306be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project String[] arrayPaths = new String[mPaths.size()]; 307be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project MediaScannerConnection.scanFile(mContext, mPaths.toArray(arrayPaths), null, this); 308be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project updateStateAndNotification(STATE_W4_MEDIA_SCANNER); 309be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } else { 310be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // We're done. 311be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project updateStateAndNotification(STATE_SUCCESS); 312be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 313be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 314be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 315be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 316be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project public int getTransferId() { 317be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project return mTransferId; 318be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 319be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 320be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project public boolean handleMessage(Message msg) { 321be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (msg.what == MSG_NEXT_TRANSFER_TIMER) { 322be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // We didn't receive a new transfer in time, finalize this one 323be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (mIncoming) { 324be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project processFiles(); 325be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } else { 326be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project updateStateAndNotification(STATE_SUCCESS); 327be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 328be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project return true; 329be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } else if (msg.what == MSG_TRANSFER_TIMEOUT) { 330be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // No update on this transfer for a while, check 331be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // to see if it's still running, and fail it if it is. 332be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (isRunning()) { 333be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project updateStateAndNotification(STATE_FAILED); 334be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 335be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 336be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project return false; 337be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 338be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 339be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project public synchronized void onScanCompleted(String path, Uri uri) { 340be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (DBG) Log.d(TAG, "Scan completed, path " + path + " uri " + uri); 341be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (uri != null) { 342be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mMediaUris.put(path, uri); 343be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 344be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project mUrisScanned++; 345be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (mUrisScanned == mPaths.size()) { 346be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // We're done 347be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project updateStateAndNotification(STATE_SUCCESS); 348be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 349be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 350be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 351be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project boolean checkMediaStorage(File path) { 352be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { 353be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (!path.isDirectory() && !path.mkdir()) { 354be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project Log.e(TAG, "Not dir or not mkdir " + path.getAbsolutePath()); 355be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project return false; 356be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 357be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project return true; 358be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } else { 359be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project Log.e(TAG, "External storage not mounted, can't store file."); 360be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project return false; 361be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 362be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 363be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 364be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project Intent buildViewIntent() { 365be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (mPaths.size() == 0) return null; 366be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 367be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project Intent viewIntent = new Intent(Intent.ACTION_VIEW); 368be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 369be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project String filePath = mPaths.get(0); 370be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project Uri mediaUri = mMediaUris.get(filePath); 371be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project Uri uri = mediaUri != null ? mediaUri : 372be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project Uri.parse(ContentResolver.SCHEME_FILE + "://" + filePath); 373be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project viewIntent.setDataAndTypeAndNormalize(uri, mMimeTypes.get(filePath)); 374be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project viewIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 375be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project return viewIntent; 376be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 377be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 378be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project PendingIntent buildCancelIntent() { 379be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project Intent intent = new Intent(HandoverService.ACTION_CANCEL_HANDOVER_TRANSFER); 380be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project intent.putExtra(HandoverService.EXTRA_SOURCE_ADDRESS, mRemoteDevice.getAddress()); 381be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent, 0); 382be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 383be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project return pi; 384be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 385be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 386be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project File generateUniqueDestination(String path, String fileName) { 387be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project int dotIndex = fileName.lastIndexOf("."); 388be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project String extension = null; 389be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project String fileNameWithoutExtension = null; 390be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (dotIndex < 0) { 391be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project extension = ""; 392be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project fileNameWithoutExtension = fileName; 393be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } else { 394be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project extension = fileName.substring(dotIndex); 395be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project fileNameWithoutExtension = fileName.substring(0, dotIndex); 396be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 397be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project File dstFile = new File(path + File.separator + fileName); 398be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project int count = 0; 399be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project while (dstFile.exists()) { 400be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project dstFile = new File(path + File.separator + fileNameWithoutExtension + "-" + 401be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project Integer.toString(count) + extension); 402be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project count++; 403be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 404be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project return dstFile; 405be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 406be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 407be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project File generateMultiplePath(String beamRoot) { 408be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project // Generate a unique directory with the date 409be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project String format = "yyyy-MM-dd"; 410be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project SimpleDateFormat sdf = new SimpleDateFormat(format); 411be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project String newPath = beamRoot + "beam-" + sdf.format(new Date()); 412be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project File newFile = new File(newPath); 413be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project int count = 0; 414be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project while (newFile.exists()) { 415be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project newPath = beamRoot + "beam-" + sdf.format(new Date()) + "-" + 416be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project Integer.toString(count); 417be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project newFile = new File(newPath); 418be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project count++; 419be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 420be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project return newFile; 421be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 422be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project} 423be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project 424