@SuppressLint({"InlinedApi", "NewApi"}) public void startDownload(ClementineMessage message) { mItem = message.getMessage().getRequestDownloadSongs().getDownloadItem(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { this.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, message); } else { this.execute(message); } }
@Override public void onReceive(Context context, Intent intent) { // Check if we have an media button intent if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) { // Get the key event and obtain a new message KeyEvent event = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); Message msg = Message.obtain(); // Only on KeyDown if (event.getAction() == KeyEvent.ACTION_UP) { // Check which key was pressed switch (event.getKeyCode()) { case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: msg.obj = ClementineMessage.getMessage(MsgType.PLAYPAUSE); break; case KeyEvent.KEYCODE_MEDIA_NEXT: msg.obj = ClementineMessage.getMessage(MsgType.NEXT); break; case KeyEvent.KEYCODE_MEDIA_PREVIOUS: msg.obj = ClementineMessage.getMessage(MsgType.PREVIOUS); break; case KeyEvent.KEYCODE_VOLUME_DOWN: msg.obj = ClementineMessageFactory.buildVolumeMessage(App.mClementine.getVolume() - 10); break; case KeyEvent.KEYCODE_VOLUME_UP: msg.obj = ClementineMessageFactory.buildVolumeMessage(App.mClementine.getVolume() + 10); break; default: msg = null; break; } // Now send the message if (msg != null && App.mClementineConnection != null) { App.mClementineConnection.mHandler.sendMessage(msg); } } } }
@Override public void onClick(View v) { Message msg = Message.obtain(); switch (v.getId()) { case R.id.btnNext: msg.obj = ClementineMessage.getMessage(MsgType.NEXT); break; case R.id.btnPrev: msg.obj = ClementineMessage.getMessage(MsgType.PREVIOUS); break; case R.id.btnPlaypause: msg.obj = ClementineMessage.getMessage(MsgType.PLAYPAUSE); break; default: break; } // Send the request to the thread if (msg.obj != null) { App.mClementineConnection.mHandler.sendMessage(msg); } }
/** * Send a request to clementine * * @param message The request as a RequestToThread object * @return true if data was sent, false if not */ public boolean sendRequest(ClementineMessage message) { // Create the protocolbuffer byte[] data = message.getMessage().toByteArray(); try { mOut.writeInt(data.length); mOut.write(data); mOut.flush(); } catch (Exception e) { // Try to reconnect closeSocket(); return false; } return true; }
/** * Disconnect from Clementine * * @param message The RequestDisconnect Object */ public void disconnect(ClementineMessage message) { if (isConnected()) { // Send the disconnect message to clementine byte[] data = message.getMessage().toByteArray(); try { // Now send the data mOut.writeInt(data.length); mOut.write(data); mOut.flush(); closeSocket(); } catch (IOException e) { } } }
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.library_menu_refresh: mAdapters.clear(); showList(); App.libraryDownloader = new ClementineLibraryDownloader(getActivity()); App.libraryDownloader.addOnLibraryDownloadListener(mOnLibraryDownloadListener); App.libraryDownloader.startDownload(ClementineMessage.getMessage(MsgType.GET_LIBRARY)); createDownloadProgressDialog(); break; default: return super.onOptionsItemSelected(item); } return true; }
@Override public boolean onLongClick(View v) { boolean ret = false; Message msg = Message.obtain(); switch (v.getId()) { case R.id.btnPlaypause: Toast.makeText(getActivity(), R.string.player_stop_after_current, Toast.LENGTH_SHORT) .show(); msg.obj = ClementineMessage.getMessage(MsgType.STOP_AFTER); ret = true; break; default: break; } App.mClementineConnection.mHandler.sendMessage(msg); return ret; }
/** * Try to connect to Clementine * * @param message The Request Object. Stores the ip to connect to. */ @Override public boolean createConnection(ClementineMessage message) { boolean connected = false; // Reset the connected flag mLastKeepAlive = 0; // Now try to connect and set the input and output streams connected = super.createConnection(message); // Check if Clementine dropped the connection. // Is possible when we connect from a public ip and clementine rejects it if (connected && !mSocket.isClosed()) { // Enter the main loop in the thread Message msg = Message.obtain(); msg.arg1 = CHECK_FOR_DATA_ARG; mHandler.sendMessage(msg); // Now we are connected mLastSong = null; mLastState = App.mClementine.getState(); // Setup the MediaButtonReceiver and the RemoteControlClient registerRemoteControlClient(); // Register MediaButtonReceiver IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON); App.mApp.registerReceiver(mMediaButtonBroadcastReceiver, filter); updateNotification(); // The device shall be awake mWakeLock.acquire(); // We can now reconnect MAX_RECONNECTS times when // we get a keep alive timeout mLeftReconnects = MAX_RECONNECTS; // Set the current time to last keep alive setLastKeepAlive(System.currentTimeMillis()); // Until we get a new connection request from ui, // don't request the first data a second time mRequestConnect = ClementineMessageFactory.buildConnectMessage( message.getIp(), message.getPort(), message.getMessage().getRequestConnect().getAuthCode(), false, message.getMessage().getRequestConnect().getDownloader()); // Save started transmitted bytes int uid = App.mApp.getApplicationInfo().uid; mStartTx = TrafficStats.getUidTxBytes(uid); mStartRx = TrafficStats.getUidRxBytes(uid); mStartTime = new Date().getTime(); } else { sendUiMessage(new ClementineMessage(ErrorMessage.NO_CONNECTION)); } return connected; }
/** Start the Download */ private DownloaderResult startDownloading(ClementineMessage clementineMessage) { boolean downloadFinished = false; DownloaderResult result = new DownloaderResult(DownloadResult.SUCCESSFUL); File f = null; FileOutputStream fo = null; publishProgress(0); // Now request the songs mClient.sendRequest(clementineMessage); while (!downloadFinished) { // Check if the user canceled the process if (isCancelled()) { // Close the stream and delete the incomplete file try { if (fo != null) { fo.flush(); fo.close(); } if (f != null) { f.delete(); } } catch (IOException e) { } Log.d(TAG, "isCancelled"); break; } // Get the raw protocol buffer ClementineMessage message = mClient.getProtoc(); if (message.isErrorMessage()) { result = new DownloaderResult(DownloadResult.CONNECTION_ERROR); break; } // Is the download forbidden? if (message.getMessageType() == MsgType.DISCONNECT) { result = new DownloaderResult(DownloadResult.FOBIDDEN); break; } // Ignore other elements! if (message.getMessageType() != MsgType.LIBRARY_CHUNK) { continue; } ResponseLibraryChunk chunk = message.getMessage().getResponseLibraryChunk(); try { // Check if we need to create a new file if (f == null) { // Check if we have enougth free space // size times 2, because we optimise the table later and // need space for that too! if ((chunk.getSize() * 2) > Utilities.getFreeSpaceExternal()) { result = new DownloaderResult(DownloadResult.INSUFFIANT_SPACE); break; } f = mLibrary.getLibraryDb(); // User wants to override files, so delete it here! // The check was already done in processSongOffer() if (f.exists()) { f.delete(); } f.createNewFile(); fo = new FileOutputStream(f); } // Write chunk to sdcard fo.write(chunk.getData().toByteArray()); // Have we downloaded all chunks? if (chunk.getChunkCount() == chunk.getChunkNumber()) { fo.flush(); fo.close(); f = null; downloadFinished = true; } // Update notification updateProgress(chunk); } catch (IOException e) { result = new DownloaderResult(DownloaderResult.DownloadResult.NOT_MOUNTED); break; } } // Disconnect at the end mClient.disconnect(ClementineMessage.getMessage(MsgType.DISCONNECT)); // Optimize library table if (mLibrary.getLibraryDb().exists()) { mLibrary.optimizeTable(); } return result; }
/** Start the Downlaod */ private DownloaderResult startDownloading(ClementineMessage clementineMessage) { boolean downloadFinished = false; DownloaderResult result = new DownloaderResult(DownloadResult.SUCCESSFUL); File f = null; FileOutputStream fo = null; // Do we have a playlist? mIsPlaylist = (clementineMessage.getMessage().getRequestDownloadSongs().getDownloadItem() == DownloadItem.APlaylist); if (mIsPlaylist) { int id = clementineMessage.getMessage().getRequestDownloadSongs().getPlaylistId(); mPlaylistName = App.mClementine.getPlaylistManager().getPlaylist(id).getName(); } publishProgress(0); // Now request the songs mClient.sendRequest(clementineMessage); while (!downloadFinished) { // Check if the user canceled the process if (isCancelled()) { // Close the stream and delete the incomplete file try { if (fo != null) { fo.flush(); fo.close(); } if (f != null) { f.delete(); } } catch (IOException e) { } break; } // Get the raw protocol buffer ClementineMessage message = mClient.getProtoc(); // Check if an error occured if (message == null || message.isErrorMessage()) { result = new DownloaderResult(DownloadResult.CONNECTION_ERROR); break; } // Is the download forbidden? if (message.getMessageType() == MsgType.DISCONNECT) { result = new DownloaderResult(DownloadResult.FOBIDDEN); break; } // Download finished? if (message.getMessageType() == MsgType.DOWNLOAD_QUEUE_EMPTY) { break; } // Ignore other elements! if (message.getMessageType() != MsgType.SONG_FILE_CHUNK) { continue; } ResponseSongFileChunk chunk = message.getMessage().getResponseSongFileChunk(); // If we received chunk no 0, then we have to decide wether to // accept the song offered or not if (chunk.getChunkNumber() == 0) { processSongOffer(chunk); // Update progress here to. If the first (and only) file exists and shall not be // overriten, the notification bar shows NULL. mCurrentSong = MySong.fromProtocolBuffer(chunk.getSongMetadata()); publishProgress(mCurrentProgress); continue; } try { // Check if we need to create a new file if (f == null) { // Check if we have enougth free space if (chunk.getSize() > Utilities.getFreeSpaceExternal()) { result = new DownloaderResult(DownloadResult.INSUFFIANT_SPACE); break; } File dir = new File(BuildDirPath(chunk)); f = new File(BuildFilePath(chunk)); // User wants to override files, so delete it here! // The check was already done in processSongOffer() if (f.exists()) { f.delete(); } dir.mkdirs(); f.createNewFile(); fo = new FileOutputStream(f); // File for download fragment mFileUri = Uri.fromFile(f); } // Write chunk to sdcard fo.write(chunk.getData().toByteArray()); // Have we downloaded all chunks? if (chunk.getChunkCount() == chunk.getChunkNumber()) { // Index file MediaScannerConnection.scanFile(mContext, new String[] {f.getAbsolutePath()}, null, null); fo.flush(); fo.close(); f = null; } // Update notification updateProgress(chunk); } catch (IOException e) { result = new DownloaderResult(DownloaderResult.DownloadResult.NOT_MOUNTED); break; } } // Disconnect at the end mClient.disconnect(ClementineMessage.getMessage(MsgType.DISCONNECT)); return result; }