Changeset View
Changeset View
Standalone View
Standalone View
src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java
Show All 34 Lines | |||||
35 | import android.graphics.drawable.Drawable; | 35 | import android.graphics.drawable.Drawable; | ||
36 | import android.net.Uri; | 36 | import android.net.Uri; | ||
37 | import android.os.Build; | 37 | import android.os.Build; | ||
38 | import android.os.Bundle; | 38 | import android.os.Bundle; | ||
39 | import android.provider.MediaStore; | 39 | import android.provider.MediaStore; | ||
40 | import android.support.v4.app.NotificationCompat; | 40 | import android.support.v4.app.NotificationCompat; | ||
41 | import android.support.v4.app.TaskStackBuilder; | 41 | import android.support.v4.app.TaskStackBuilder; | ||
42 | import android.support.v4.content.ContextCompat; | 42 | import android.support.v4.content.ContextCompat; | ||
43 | import android.support.v4.content.FileProvider; | ||||
43 | import android.support.v4.provider.DocumentFile; | 44 | import android.support.v4.provider.DocumentFile; | ||
44 | import android.util.Log; | 45 | import android.util.Log; | ||
45 | import android.widget.Toast; | 46 | import android.widget.Toast; | ||
46 | 47 | | |||
47 | import org.kde.kdeconnect.Device; | 48 | import org.kde.kdeconnect.Device; | ||
48 | import org.kde.kdeconnect.Helpers.FilesHelper; | 49 | import org.kde.kdeconnect.Helpers.FilesHelper; | ||
49 | import org.kde.kdeconnect.Helpers.MediaStoreHelper; | 50 | import org.kde.kdeconnect.Helpers.MediaStoreHelper; | ||
50 | import org.kde.kdeconnect.Helpers.NotificationHelper; | 51 | import org.kde.kdeconnect.Helpers.NotificationHelper; | ||
▲ Show 20 Lines • Show All 136 Lines • ▼ Show 20 Line(s) | 64 | public class SharePlugin extends Plugin { | |||
187 | } | 188 | } | ||
188 | 189 | | |||
189 | private void receiveFile(NetworkPacket np) { | 190 | private void receiveFile(NetworkPacket np) { | ||
190 | 191 | | |||
191 | final InputStream input = np.getPayload(); | 192 | final InputStream input = np.getPayload(); | ||
192 | final long fileLength = np.getPayloadSize(); | 193 | final long fileLength = np.getPayloadSize(); | ||
193 | final String originalFilename = np.getString("filename", Long.toString(System.currentTimeMillis())); | 194 | final String originalFilename = np.getString("filename", Long.toString(System.currentTimeMillis())); | ||
194 | 195 | | |||
196 | String filename = originalFilename; | ||||
197 | final DocumentFile destinationFolderDocument; | ||||
198 | | ||||
195 | //We need to check for already existing files only when storing in the default path. | 199 | //We need to check for already existing files only when storing in the default path. | ||
196 | //User-defined paths use the new Storage Access Framework that already handles this. | 200 | //User-defined paths use the new Storage Access Framework that already handles this. | ||
197 | final boolean customDestination = ShareSettingsActivity.isCustomDestinationEnabled(context); | 201 | //If the file should be opened immediately store it in the standard location to avoid the FileProvider trouble (See ShareNotification::setURI) | ||
202 | if (np.getBoolean("open") || !ShareSettingsActivity.isCustomDestinationEnabled(context)) { | ||||
198 | final String defaultPath = ShareSettingsActivity.getDefaultDestinationDirectory().getAbsolutePath(); | 203 | final String defaultPath = ShareSettingsActivity.getDefaultDestinationDirectory().getAbsolutePath(); | ||
199 | final String filename = customDestination ? originalFilename : FilesHelper.findNonExistingNameForNewFile(defaultPath, originalFilename); | 204 | filename = FilesHelper.findNonExistingNameForNewFile(defaultPath, originalFilename); | ||
200 | 205 | destinationFolderDocument = DocumentFile.fromFile(new File(defaultPath)); | |||
206 | } else { | ||||
207 | destinationFolderDocument = ShareSettingsActivity.getDestinationDirectory(context); | ||||
208 | } | ||||
201 | String displayName = FilesHelper.getFileNameWithoutExt(filename); | 209 | String displayName = FilesHelper.getFileNameWithoutExt(filename); | ||
202 | final String mimeType = FilesHelper.getMimeTypeFromFile(filename); | 210 | final String mimeType = FilesHelper.getMimeTypeFromFile(filename); | ||
203 | 211 | | |||
204 | if ("*/*".equals(mimeType)) { | 212 | if ("*/*".equals(mimeType)) { | ||
205 | displayName = filename; | 213 | displayName = filename; | ||
206 | } | 214 | } | ||
207 | 215 | | |||
208 | final DocumentFile destinationFolderDocument = ShareSettingsActivity.getDestinationDirectory(context); | | |||
209 | final DocumentFile destinationDocument = destinationFolderDocument.createFile(mimeType, displayName); | 216 | final DocumentFile destinationDocument = destinationFolderDocument.createFile(mimeType, displayName); | ||
210 | final OutputStream destinationOutput; | 217 | final OutputStream destinationOutput; | ||
211 | try { | 218 | try { | ||
212 | destinationOutput = context.getContentResolver().openOutputStream(destinationDocument.getUri()); | 219 | destinationOutput = context.getContentResolver().openOutputStream(destinationDocument.getUri()); | ||
213 | } catch (FileNotFoundException e) { | 220 | } catch (FileNotFoundException e) { | ||
214 | e.printStackTrace(); | 221 | e.printStackTrace(); | ||
215 | return; | 222 | return; | ||
216 | } | 223 | } | ||
Show All 25 Lines | 235 | while ((count = input.read(data)) >= 0) { | |||
242 | } | 249 | } | ||
243 | //else Log.e("SharePlugin", "Infinite loop? :D"); | 250 | //else Log.e("SharePlugin", "Infinite loop? :D"); | ||
244 | } | 251 | } | ||
245 | 252 | | |||
246 | destinationOutput.flush(); | 253 | destinationOutput.flush(); | ||
247 | 254 | | |||
248 | Log.i("SharePlugin", "Transfer finished: " + destinationUri.getPath()); | 255 | Log.i("SharePlugin", "Transfer finished: " + destinationUri.getPath()); | ||
249 | 256 | | |||
257 | | ||||
258 | if (np.getBoolean("open")) { | ||||
259 | | ||||
260 | notification.cancel(); | ||||
261 | | ||||
262 | Intent intent = new Intent(Intent.ACTION_VIEW); | ||||
263 | if (Build.VERSION.SDK_INT >= 24) { | ||||
264 | //Nougat and later require "content://" uris instead of "file://" uris | ||||
265 | File file = new File(destinationUri.getPath()); | ||||
266 | Uri contentUri = FileProvider.getUriForFile(device.getContext(), "org.kde.kdeconnect_tp.fileprovider", file); | ||||
267 | intent.setDataAndType(contentUri, mimeType); | ||||
268 | intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); | ||||
269 | } else { | ||||
270 | intent.setDataAndType(destinationUri, mimeType); | ||||
271 | } | ||||
272 | | ||||
273 | context.startActivity(intent); | ||||
274 | } else { | ||||
275 | | ||||
250 | //Update the notification and allow to open the file from it | 276 | //Update the notification and allow to open the file from it | ||
251 | notification.setFinished(true); | 277 | notification.setFinished(true); | ||
252 | notification.setURI(destinationUri, mimeType); | 278 | notification.setURI(destinationUri, mimeType); | ||
253 | notification.show(); | 279 | notification.show(); | ||
254 | 280 | | |||
255 | if (!customDestination && Build.VERSION.SDK_INT >= 12) { | 281 | if (!ShareSettingsActivity.isCustomDestinationEnabled(context) && Build.VERSION.SDK_INT >= 12) { | ||
albertvaka: Don't check for SDK version > 12. | |||||
256 | Log.i("SharePlugin", "Adding to downloads"); | 282 | Log.i("SharePlugin", "Adding to downloads"); | ||
257 | DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); | 283 | DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); | ||
258 | manager.addCompletedDownload(destinationUri.getLastPathSegment(), device.getName(), true, mimeType, destinationUri.getPath(), fileLength, false); | 284 | manager.addCompletedDownload(destinationUri.getLastPathSegment(), device.getName(), true, mimeType, destinationUri.getPath(), fileLength, false); | ||
259 | } else { | 285 | } else { | ||
260 | //Make sure it is added to the Android Gallery anyway | 286 | //Make sure it is added to the Android Gallery anyway | ||
261 | MediaStoreHelper.indexFile(context, destinationUri); | 287 | MediaStoreHelper.indexFile(context, destinationUri); | ||
262 | } | 288 | } | ||
263 | 289 | } | |||
264 | } catch (Exception e) { | 290 | } catch (Exception e) { | ||
265 | Log.e("SharePlugin", "Receiver thread exception"); | 291 | Log.e("SharePlugin", "Receiver thread exception"); | ||
266 | e.printStackTrace(); | 292 | e.printStackTrace(); | ||
267 | notification.setFinished(false); | 293 | notification.setFinished(false); | ||
268 | notification.show(); | 294 | notification.show(); | ||
269 | } finally { | 295 | } finally { | ||
270 | try { | 296 | try { | ||
271 | destinationOutput.close(); | 297 | destinationOutput.close(); | ||
Show All 10 Lines | |||||
282 | @Override | 308 | @Override | ||
283 | public void startPreferencesActivity(SettingsActivity parentActivity) { | 309 | public void startPreferencesActivity(SettingsActivity parentActivity) { | ||
284 | Intent intent = new Intent(parentActivity, ShareSettingsActivity.class); | 310 | Intent intent = new Intent(parentActivity, ShareSettingsActivity.class); | ||
285 | intent.putExtra("plugin_display_name", getDisplayName()); | 311 | intent.putExtra("plugin_display_name", getDisplayName()); | ||
286 | intent.putExtra("plugin_key", getPluginKey()); | 312 | intent.putExtra("plugin_key", getPluginKey()); | ||
287 | parentActivity.startActivity(intent); | 313 | parentActivity.startActivity(intent); | ||
288 | } | 314 | } | ||
289 | 315 | | |||
290 | static void queuedSendUriList(Context context, final Device device, final ArrayList<Uri> uriList) { | 316 | static void queuedSendUriList(Context context, final Device device, | ||
317 | final ArrayList<Uri> uriList) { | ||||
291 | 318 | | |||
292 | //Read all the data early, as we only have permissions to do it while the activity is alive | 319 | //Read all the data early, as we only have permissions to do it while the activity is alive | ||
293 | final ArrayList<NetworkPacket> toSend = new ArrayList<>(); | 320 | final ArrayList<NetworkPacket> toSend = new ArrayList<>(); | ||
294 | for (Uri uri : uriList) { | 321 | for (Uri uri : uriList) { | ||
295 | toSend.add(uriToNetworkPacket(context, uri)); | 322 | toSend.add(uriToNetworkPacket(context, uri)); | ||
296 | } | 323 | } | ||
297 | 324 | | |||
298 | //Callback that shows a progress notification | 325 | //Callback that shows a progress notification | ||
▲ Show 20 Lines • Show All 166 Lines • Show Last 20 Lines |
Don't check for SDK version > 12.