Differential D16491 Diff 53464 src/org/kde/kdeconnect/Plugins/SharePlugin/CompositeReceiveFileJob.java
Changeset View
Changeset View
Standalone View
Standalone View
src/org/kde/kdeconnect/Plugins/SharePlugin/CompositeReceiveFileJob.java
- This file was moved from src/org/kde/kdeconnect/Plugins/SharePlugin/CompositeReceiveFileRunnable.java.
Show All 19 Lines | |||||
20 | 20 | | |||
21 | package org.kde.kdeconnect.Plugins.SharePlugin; | 21 | package org.kde.kdeconnect.Plugins.SharePlugin; | ||
22 | 22 | | |||
23 | import android.app.DownloadManager; | 23 | import android.app.DownloadManager; | ||
24 | import android.content.Context; | 24 | import android.content.Context; | ||
25 | import android.content.Intent; | 25 | import android.content.Intent; | ||
26 | import android.net.Uri; | 26 | import android.net.Uri; | ||
27 | import android.os.Build; | 27 | import android.os.Build; | ||
28 | import android.os.Handler; | | |||
29 | import android.os.Looper; | | |||
30 | import android.util.Log; | 28 | import android.util.Log; | ||
31 | 29 | | |||
32 | import org.kde.kdeconnect.Device; | 30 | import org.kde.kdeconnect.Device; | ||
33 | import org.kde.kdeconnect.Helpers.FilesHelper; | 31 | import org.kde.kdeconnect.Helpers.FilesHelper; | ||
34 | import org.kde.kdeconnect.Helpers.MediaStoreHelper; | 32 | import org.kde.kdeconnect.Helpers.MediaStoreHelper; | ||
35 | import org.kde.kdeconnect.NetworkPacket; | 33 | import org.kde.kdeconnect.NetworkPacket; | ||
34 | import org.kde.kdeconnect.async.BackgroundJob; | ||||
36 | import org.kde.kdeconnect_tp.R; | 35 | import org.kde.kdeconnect_tp.R; | ||
37 | 36 | | |||
38 | import java.io.BufferedOutputStream; | 37 | import java.io.BufferedOutputStream; | ||
39 | import java.io.File; | 38 | import java.io.File; | ||
40 | import java.io.IOException; | 39 | import java.io.IOException; | ||
41 | import java.io.InputStream; | 40 | import java.io.InputStream; | ||
42 | import java.io.OutputStream; | 41 | import java.io.OutputStream; | ||
43 | import java.util.ArrayList; | 42 | import java.util.ArrayList; | ||
44 | import java.util.List; | 43 | import java.util.List; | ||
45 | 44 | | |||
46 | import androidx.core.content.FileProvider; | 45 | import androidx.core.content.FileProvider; | ||
47 | import androidx.documentfile.provider.DocumentFile; | 46 | import androidx.documentfile.provider.DocumentFile; | ||
48 | 47 | | |||
49 | class CompositeReceiveFileRunnable implements Runnable { | 48 | public class CompositeReceiveFileJob extends BackgroundJob<Device, Void> { | ||
50 | interface CallBack { | | |||
51 | void onSuccess(CompositeReceiveFileRunnable runnable); | | |||
52 | void onError(CompositeReceiveFileRunnable runnable, Throwable error); | | |||
53 | } | | |||
54 | | ||||
55 | private final Device device; | | |||
56 | private final ShareNotification shareNotification; | 49 | private final ShareNotification shareNotification; | ||
57 | private NetworkPacket currentNetworkPacket; | 50 | private NetworkPacket currentNetworkPacket; | ||
58 | private String currentFileName; | 51 | private String currentFileName; | ||
59 | private int currentFileNum; | 52 | private int currentFileNum; | ||
60 | private long totalReceived; | 53 | private long totalReceived; | ||
61 | private long lastProgressTimeMillis; | 54 | private long lastProgressTimeMillis; | ||
62 | private long prevProgressPercentage; | 55 | private long prevProgressPercentage; | ||
63 | 56 | | |||
64 | private final CallBack callBack; | | |||
65 | private final Handler handler; | | |||
66 | | ||||
67 | private final Object lock; //Use to protect concurrent access to the variables below | 57 | private final Object lock; //Use to protect concurrent access to the variables below | ||
68 | private final List<NetworkPacket> networkPacketList; | 58 | private final List<NetworkPacket> networkPacketList; | ||
69 | private int totalNumFiles; | 59 | private int totalNumFiles; | ||
70 | private long totalPayloadSize; | 60 | private long totalPayloadSize; | ||
71 | private boolean isRunning; | 61 | private boolean isRunning; | ||
72 | 62 | | |||
73 | CompositeReceiveFileRunnable(Device device, CallBack callBack) { | 63 | CompositeReceiveFileJob(Device device, BackgroundJob.Callback<Void> callBack) { | ||
74 | this.device = device; | 64 | super(device, callBack); | ||
75 | this.callBack = callBack; | | |||
76 | 65 | | |||
77 | lock = new Object(); | 66 | lock = new Object(); | ||
78 | networkPacketList = new ArrayList<>(); | 67 | networkPacketList = new ArrayList<>(); | ||
79 | shareNotification = new ShareNotification(device); | 68 | shareNotification = new ShareNotification(device); | ||
69 | shareNotification.setJobId(getId()); | ||||
80 | currentFileNum = 0; | 70 | currentFileNum = 0; | ||
81 | totalNumFiles = 0; | 71 | totalNumFiles = 0; | ||
82 | totalPayloadSize = 0; | 72 | totalPayloadSize = 0; | ||
83 | totalReceived = 0; | 73 | totalReceived = 0; | ||
84 | lastProgressTimeMillis = 0; | 74 | lastProgressTimeMillis = 0; | ||
85 | prevProgressPercentage = 0; | 75 | prevProgressPercentage = 0; | ||
86 | handler = new Handler(Looper.getMainLooper()); | 76 | } | ||
77 | | ||||
78 | private Device getDevice() { | ||||
79 | return requestInfo; | ||||
87 | } | 80 | } | ||
88 | 81 | | |||
89 | boolean isRunning() { return isRunning; } | 82 | boolean isRunning() { return isRunning; } | ||
90 | 83 | | |||
91 | void updateTotals(int numberOfFiles, long totalPayloadSize) { | 84 | void updateTotals(int numberOfFiles, long totalPayloadSize) { | ||
92 | synchronized (lock) { | 85 | synchronized (lock) { | ||
93 | this.totalNumFiles = numberOfFiles; | 86 | this.totalNumFiles = numberOfFiles; | ||
94 | this.totalPayloadSize = totalPayloadSize; | 87 | this.totalPayloadSize = totalPayloadSize; | ||
95 | 88 | | |||
96 | shareNotification.setTitle(device.getContext().getResources() | 89 | shareNotification.setTitle(getDevice().getContext().getResources() | ||
97 | .getQuantityString(R.plurals.incoming_file_title, totalNumFiles, totalNumFiles, device.getName())); | 90 | .getQuantityString(R.plurals.incoming_file_title, totalNumFiles, totalNumFiles, getDevice().getName())); | ||
98 | } | 91 | } | ||
99 | } | 92 | } | ||
100 | 93 | | |||
101 | void addNetworkPacket(NetworkPacket networkPacket) { | 94 | void addNetworkPacket(NetworkPacket networkPacket) { | ||
102 | synchronized (lock) { | 95 | synchronized (lock) { | ||
103 | if (!networkPacketList.contains(networkPacket)) { | 96 | if (!networkPacketList.contains(networkPacket)) { | ||
104 | networkPacketList.add(networkPacket); | 97 | networkPacketList.add(networkPacket); | ||
105 | 98 | | |||
106 | totalNumFiles = networkPacket.getInt(SharePlugin.KEY_NUMBER_OF_FILES, 1); | 99 | totalNumFiles = networkPacket.getInt(SharePlugin.KEY_NUMBER_OF_FILES, 1); | ||
107 | totalPayloadSize = networkPacket.getLong(SharePlugin.KEY_TOTAL_PAYLOAD_SIZE); | 100 | totalPayloadSize = networkPacket.getLong(SharePlugin.KEY_TOTAL_PAYLOAD_SIZE); | ||
108 | 101 | | |||
109 | shareNotification.setTitle(device.getContext().getResources() | 102 | shareNotification.setTitle(getDevice().getContext().getResources() | ||
110 | .getQuantityString(R.plurals.incoming_file_title, totalNumFiles, totalNumFiles, device.getName())); | 103 | .getQuantityString(R.plurals.incoming_file_title, totalNumFiles, totalNumFiles, getDevice().getName())); | ||
111 | } | 104 | } | ||
112 | } | 105 | } | ||
113 | } | 106 | } | ||
114 | 107 | | |||
115 | @Override | 108 | @Override | ||
116 | public void run() { | 109 | public void run() { | ||
117 | boolean done; | 110 | boolean done; | ||
118 | OutputStream outputStream = null; | 111 | OutputStream outputStream = null; | ||
119 | 112 | | |||
120 | synchronized (lock) { | 113 | synchronized (lock) { | ||
121 | done = networkPacketList.isEmpty(); | 114 | done = networkPacketList.isEmpty(); | ||
122 | } | 115 | } | ||
123 | 116 | | |||
124 | try { | 117 | try { | ||
125 | DocumentFile fileDocument = null; | 118 | DocumentFile fileDocument = null; | ||
126 | 119 | | |||
127 | isRunning = true; | 120 | isRunning = true; | ||
128 | 121 | | |||
129 | while (!done) { | 122 | while (!done && !canceled) { | ||
130 | synchronized (lock) { | 123 | synchronized (lock) { | ||
131 | currentNetworkPacket = networkPacketList.get(0); | 124 | currentNetworkPacket = networkPacketList.get(0); | ||
132 | } | 125 | } | ||
133 | currentFileName = currentNetworkPacket.getString("filename", Long.toString(System.currentTimeMillis())); | 126 | currentFileName = currentNetworkPacket.getString("filename", Long.toString(System.currentTimeMillis())); | ||
134 | currentFileNum++; | 127 | currentFileNum++; | ||
135 | 128 | | |||
136 | setProgress((int)prevProgressPercentage); | 129 | setProgress((int)prevProgressPercentage); | ||
137 | 130 | | |||
138 | fileDocument = getDocumentFileFor(currentFileName, currentNetworkPacket.getBoolean("open")); | 131 | fileDocument = getDocumentFileFor(currentFileName, currentNetworkPacket.getBoolean("open")); | ||
139 | 132 | | |||
140 | if (currentNetworkPacket.hasPayload()) { | 133 | if (currentNetworkPacket.hasPayload()) { | ||
141 | outputStream = new BufferedOutputStream(device.getContext().getContentResolver().openOutputStream(fileDocument.getUri())); | 134 | outputStream = new BufferedOutputStream(getDevice().getContext().getContentResolver().openOutputStream(fileDocument.getUri())); | ||
142 | InputStream inputStream = currentNetworkPacket.getPayload().getInputStream(); | 135 | InputStream inputStream = currentNetworkPacket.getPayload().getInputStream(); | ||
143 | 136 | | |||
144 | long received = receiveFile(inputStream, outputStream); | 137 | long received = receiveFile(inputStream, outputStream); | ||
145 | 138 | | |||
146 | currentNetworkPacket.getPayload().close(); | 139 | currentNetworkPacket.getPayload().close(); | ||
147 | 140 | | |||
148 | if ( received != currentNetworkPacket.getPayloadSize()) { | 141 | if ( received != currentNetworkPacket.getPayloadSize()) { | ||
149 | fileDocument.delete(); | 142 | fileDocument.delete(); | ||
143 | | ||||
144 | if (!canceled) { | ||||
150 | throw new RuntimeException("Failed to receive: " + currentFileName + " received:" + received + " bytes, expected: " + currentNetworkPacket.getPayloadSize() + " bytes"); | 145 | throw new RuntimeException("Failed to receive: " + currentFileName + " received:" + received + " bytes, expected: " + currentNetworkPacket.getPayloadSize() + " bytes"); | ||
146 | } | ||||
151 | } else { | 147 | } else { | ||
152 | publishFile(fileDocument, received); | 148 | publishFile(fileDocument, received); | ||
153 | } | 149 | } | ||
154 | } else { | 150 | } else { | ||
155 | setProgress(100); | 151 | setProgress(100); | ||
156 | publishFile(fileDocument, 0); | 152 | publishFile(fileDocument, 0); | ||
157 | } | 153 | } | ||
158 | 154 | | |||
159 | boolean listIsEmpty; | 155 | boolean listIsEmpty; | ||
160 | 156 | | |||
161 | synchronized (lock) { | 157 | synchronized (lock) { | ||
162 | networkPacketList.remove(0); | 158 | networkPacketList.remove(0); | ||
163 | listIsEmpty = networkPacketList.isEmpty(); | 159 | listIsEmpty = networkPacketList.isEmpty(); | ||
164 | } | 160 | } | ||
165 | 161 | | |||
166 | if (listIsEmpty) { | 162 | if (listIsEmpty && !canceled) { | ||
167 | try { | 163 | try { | ||
168 | Thread.sleep(1000); | 164 | Thread.sleep(1000); | ||
169 | } catch (InterruptedException ignored) {} | 165 | } catch (InterruptedException ignored) {} | ||
170 | 166 | | |||
171 | synchronized (lock) { | 167 | synchronized (lock) { | ||
172 | if (currentFileNum < totalNumFiles && networkPacketList.isEmpty()) { | 168 | if (currentFileNum < totalNumFiles && networkPacketList.isEmpty()) { | ||
173 | throw new RuntimeException("Failed to receive " + (totalNumFiles - currentFileNum + 1) + " files"); | 169 | throw new RuntimeException("Failed to receive " + (totalNumFiles - currentFileNum + 1) + " files"); | ||
174 | } | 170 | } | ||
175 | } | 171 | } | ||
176 | } | 172 | } | ||
177 | 173 | | |||
178 | synchronized (lock) { | 174 | synchronized (lock) { | ||
179 | done = networkPacketList.isEmpty(); | 175 | done = networkPacketList.isEmpty(); | ||
180 | } | 176 | } | ||
181 | } | 177 | } | ||
182 | 178 | | |||
183 | isRunning = false; | 179 | isRunning = false; | ||
184 | 180 | | |||
181 | if (canceled) { | ||||
182 | Log.e("ERIK", "I've been cancelled"); | ||||
183 | shareNotification.cancel(); | ||||
184 | return; | ||||
185 | } | ||||
186 | | ||||
185 | int numFiles; | 187 | int numFiles; | ||
186 | synchronized (lock) { | 188 | synchronized (lock) { | ||
187 | numFiles = totalNumFiles; | 189 | numFiles = totalNumFiles; | ||
188 | } | 190 | } | ||
189 | 191 | | |||
190 | if (numFiles == 1 && currentNetworkPacket.has("open")) { | 192 | if (numFiles == 1 && currentNetworkPacket.has("open")) { | ||
191 | shareNotification.cancel(); | 193 | shareNotification.cancel(); | ||
192 | openFile(fileDocument); | 194 | openFile(fileDocument); | ||
193 | } else { | 195 | } else { | ||
194 | //Update the notification and allow to open the file from it | 196 | //Update the notification and allow to open the file from it | ||
195 | shareNotification.setFinished(device.getContext().getResources().getQuantityString(R.plurals.received_files_title, numFiles, device.getName(), numFiles)); | 197 | shareNotification.setFinished(getDevice().getContext().getResources().getQuantityString(R.plurals.received_files_title, numFiles, getDevice().getName(), numFiles)); | ||
196 | 198 | | |||
197 | if (totalNumFiles == 1 && fileDocument != null) { | 199 | if (totalNumFiles == 1 && fileDocument != null) { | ||
198 | shareNotification.setURI(fileDocument.getUri(), fileDocument.getType(), fileDocument.getName()); | 200 | shareNotification.setURI(fileDocument.getUri(), fileDocument.getType(), fileDocument.getName()); | ||
199 | } | 201 | } | ||
200 | 202 | | |||
201 | shareNotification.show(); | 203 | shareNotification.show(); | ||
202 | } | 204 | } | ||
203 | handler.post(() -> callBack.onSuccess(this)); | 205 | reportResult(null); | ||
204 | } catch (Exception e) { | 206 | } catch (Exception e) { | ||
205 | isRunning = false; | 207 | isRunning = false; | ||
206 | 208 | | |||
207 | int failedFiles; | 209 | int failedFiles; | ||
208 | synchronized (lock) { | 210 | synchronized (lock) { | ||
209 | failedFiles = (totalNumFiles - currentFileNum + 1); | 211 | failedFiles = (totalNumFiles - currentFileNum + 1); | ||
210 | } | 212 | } | ||
211 | shareNotification.setFinished(device.getContext().getResources().getQuantityString(R.plurals.received_files_fail_title, failedFiles, device.getName(), failedFiles, totalNumFiles)); | 213 | | ||
214 | shareNotification.setFinished(getDevice().getContext().getResources().getQuantityString(R.plurals.received_files_fail_title, failedFiles, getDevice().getName(), failedFiles, totalNumFiles)); | ||||
212 | shareNotification.show(); | 215 | shareNotification.show(); | ||
213 | handler.post(() -> callBack.onError(this, e)); | 216 | reportError(e); | ||
214 | } finally { | 217 | } finally { | ||
218 | Log.e("ERIK", "Closing all input and output streams"); | ||||
215 | closeAllInputStreams(); | 219 | closeAllInputStreams(); | ||
216 | networkPacketList.clear(); | 220 | networkPacketList.clear(); | ||
217 | if (outputStream != null) { | 221 | if (outputStream != null) { | ||
218 | try { | 222 | try { | ||
219 | outputStream.close(); | 223 | outputStream.close(); | ||
220 | } catch (IOException ignored) {} | 224 | } catch (IOException ignored) {} | ||
221 | } | 225 | } | ||
222 | } | 226 | } | ||
223 | } | 227 | } | ||
224 | 228 | | |||
225 | private DocumentFile getDocumentFileFor(final String filename, final boolean open) throws RuntimeException { | 229 | private DocumentFile getDocumentFileFor(final String filename, final boolean open) throws RuntimeException { | ||
226 | final DocumentFile destinationFolderDocument; | 230 | final DocumentFile destinationFolderDocument; | ||
227 | 231 | | |||
228 | String filenameToUse = filename; | 232 | String filenameToUse = filename; | ||
229 | 233 | | |||
230 | //We need to check for already existing files only when storing in the default path. | 234 | //We need to check for already existing files only when storing in the default path. | ||
231 | //User-defined paths use the new Storage Access Framework that already handles this. | 235 | //User-defined paths use the new Storage Access Framework that already handles this. | ||
232 | //If the file should be opened immediately store it in the standard location to avoid the FileProvider trouble (See ShareNotification::setURI) | 236 | //If the file should be opened immediately store it in the standard location to avoid the FileProvider trouble (See ShareNotification::setURI) | ||
233 | if (open || !ShareSettingsFragment.isCustomDestinationEnabled(device.getContext())) { | 237 | if (open || !ShareSettingsFragment.isCustomDestinationEnabled(getDevice().getContext())) { | ||
234 | final String defaultPath = ShareSettingsFragment.getDefaultDestinationDirectory().getAbsolutePath(); | 238 | final String defaultPath = ShareSettingsFragment.getDefaultDestinationDirectory().getAbsolutePath(); | ||
235 | filenameToUse = FilesHelper.findNonExistingNameForNewFile(defaultPath, filenameToUse); | 239 | filenameToUse = FilesHelper.findNonExistingNameForNewFile(defaultPath, filenameToUse); | ||
236 | destinationFolderDocument = DocumentFile.fromFile(new File(defaultPath)); | 240 | destinationFolderDocument = DocumentFile.fromFile(new File(defaultPath)); | ||
237 | } else { | 241 | } else { | ||
238 | destinationFolderDocument = ShareSettingsFragment.getDestinationDirectory(device.getContext()); | 242 | destinationFolderDocument = ShareSettingsFragment.getDestinationDirectory(getDevice().getContext()); | ||
239 | } | 243 | } | ||
240 | String displayName = FilesHelper.getFileNameWithoutExt(filenameToUse); | 244 | String displayName = FilesHelper.getFileNameWithoutExt(filenameToUse); | ||
241 | String mimeType = FilesHelper.getMimeTypeFromFile(filenameToUse); | 245 | String mimeType = FilesHelper.getMimeTypeFromFile(filenameToUse); | ||
242 | 246 | | |||
243 | if ("*/*".equals(mimeType)) { | 247 | if ("*/*".equals(mimeType)) { | ||
244 | displayName = filenameToUse; | 248 | displayName = filenameToUse; | ||
245 | } | 249 | } | ||
246 | 250 | | |||
247 | DocumentFile fileDocument = destinationFolderDocument.createFile(mimeType, displayName); | 251 | DocumentFile fileDocument = destinationFolderDocument.createFile(mimeType, displayName); | ||
248 | 252 | | |||
249 | if (fileDocument == null) { | 253 | if (fileDocument == null) { | ||
250 | throw new RuntimeException(device.getContext().getString(R.string.cannot_create_file, filenameToUse)); | 254 | throw new RuntimeException(getDevice().getContext().getString(R.string.cannot_create_file, filenameToUse)); | ||
251 | } | 255 | } | ||
252 | 256 | | |||
253 | return fileDocument; | 257 | return fileDocument; | ||
254 | } | 258 | } | ||
255 | 259 | | |||
256 | private long receiveFile(InputStream input, OutputStream output) throws IOException { | 260 | private long receiveFile(InputStream input, OutputStream output) throws IOException { | ||
257 | byte data[] = new byte[4096]; | 261 | byte data[] = new byte[4096]; | ||
258 | int count; | 262 | int count; | ||
259 | long received = 0; | 263 | long received = 0; | ||
260 | 264 | | |||
261 | while ((count = input.read(data)) >= 0) { | 265 | while ((count = input.read(data)) >= 0 && !canceled) { | ||
262 | received += count; | 266 | received += count; | ||
263 | totalReceived += count; | 267 | totalReceived += count; | ||
264 | 268 | | |||
265 | output.write(data, 0, count); | 269 | output.write(data, 0, count); | ||
266 | 270 | | |||
267 | long progressPercentage; | 271 | long progressPercentage; | ||
268 | synchronized (lock) { | 272 | synchronized (lock) { | ||
269 | progressPercentage = (totalReceived * 100 / totalPayloadSize); | 273 | progressPercentage = (totalReceived * 100 / totalPayloadSize); | ||
Show All 10 Lines | |||||
280 | 284 | | |||
281 | output.flush(); | 285 | output.flush(); | ||
282 | 286 | | |||
283 | return received; | 287 | return received; | ||
284 | } | 288 | } | ||
285 | 289 | | |||
286 | private void closeAllInputStreams() { | 290 | private void closeAllInputStreams() { | ||
287 | for (NetworkPacket np : networkPacketList) { | 291 | for (NetworkPacket np : networkPacketList) { | ||
292 | Log.e("ERIK", "closing a networkPackets payload"); | ||||
288 | np.getPayload().close(); | 293 | np.getPayload().close(); | ||
289 | } | 294 | } | ||
290 | } | 295 | } | ||
291 | 296 | | |||
292 | private void setProgress(int progress) { | 297 | private void setProgress(int progress) { | ||
293 | synchronized (lock) { | 298 | synchronized (lock) { | ||
294 | shareNotification.setProgress(progress, device.getContext().getResources() | 299 | shareNotification.setProgress(progress, getDevice().getContext().getResources() | ||
295 | .getQuantityString(R.plurals.incoming_files_text, totalNumFiles, currentFileName, currentFileNum, totalNumFiles)); | 300 | .getQuantityString(R.plurals.incoming_files_text, totalNumFiles, currentFileName, currentFileNum, totalNumFiles)); | ||
296 | } | 301 | } | ||
297 | shareNotification.show(); | 302 | shareNotification.show(); | ||
298 | } | 303 | } | ||
299 | 304 | | |||
300 | private void publishFile(DocumentFile fileDocument, long size) { | 305 | private void publishFile(DocumentFile fileDocument, long size) { | ||
301 | if (!ShareSettingsFragment.isCustomDestinationEnabled(device.getContext())) { | 306 | if (!ShareSettingsFragment.isCustomDestinationEnabled(getDevice().getContext())) { | ||
302 | Log.i("SharePlugin", "Adding to downloads"); | 307 | Log.i("SharePlugin", "Adding to downloads"); | ||
303 | DownloadManager manager = (DownloadManager) device.getContext().getSystemService(Context.DOWNLOAD_SERVICE); | 308 | DownloadManager manager = (DownloadManager) getDevice().getContext().getSystemService(Context.DOWNLOAD_SERVICE); | ||
304 | manager.addCompletedDownload(fileDocument.getUri().getLastPathSegment(), device.getName(), true, fileDocument.getType(), fileDocument.getUri().getPath(), size, false); | 309 | manager.addCompletedDownload(fileDocument.getUri().getLastPathSegment(), getDevice().getName(), true, fileDocument.getType(), fileDocument.getUri().getPath(), size, false); | ||
305 | } else { | 310 | } else { | ||
306 | //Make sure it is added to the Android Gallery anyway | 311 | //Make sure it is added to the Android Gallery anyway | ||
307 | Log.i("SharePlugin", "Adding to gallery"); | 312 | Log.i("SharePlugin", "Adding to gallery"); | ||
308 | MediaStoreHelper.indexFile(device.getContext(), fileDocument.getUri()); | 313 | MediaStoreHelper.indexFile(getDevice().getContext(), fileDocument.getUri()); | ||
309 | } | 314 | } | ||
310 | } | 315 | } | ||
311 | 316 | | |||
312 | private void openFile(DocumentFile fileDocument) { | 317 | private void openFile(DocumentFile fileDocument) { | ||
313 | String mimeType = FilesHelper.getMimeTypeFromFile(fileDocument.getName()); | 318 | String mimeType = FilesHelper.getMimeTypeFromFile(fileDocument.getName()); | ||
314 | Intent intent = new Intent(Intent.ACTION_VIEW); | 319 | Intent intent = new Intent(Intent.ACTION_VIEW); | ||
315 | if (Build.VERSION.SDK_INT >= 24) { | 320 | if (Build.VERSION.SDK_INT >= 24) { | ||
316 | //Nougat and later require "content://" uris instead of "file://" uris | 321 | //Nougat and later require "content://" uris instead of "file://" uris | ||
317 | File file = new File(fileDocument.getUri().getPath()); | 322 | File file = new File(fileDocument.getUri().getPath()); | ||
318 | Uri contentUri = FileProvider.getUriForFile(device.getContext(), "org.kde.kdeconnect_tp.fileprovider", file); | 323 | Uri contentUri = FileProvider.getUriForFile(getDevice().getContext(), "org.kde.kdeconnect_tp.fileprovider", file); | ||
319 | intent.setDataAndType(contentUri, mimeType); | 324 | intent.setDataAndType(contentUri, mimeType); | ||
320 | intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); | 325 | intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); | ||
321 | } else { | 326 | } else { | ||
322 | intent.setDataAndType(fileDocument.getUri(), mimeType); | 327 | intent.setDataAndType(fileDocument.getUri(), mimeType); | ||
323 | } | 328 | } | ||
324 | 329 | | |||
325 | device.getContext().startActivity(intent); | 330 | getDevice().getContext().startActivity(intent); | ||
326 | } | 331 | } | ||
327 | } | 332 | } |