3
3
import android .content .ActivityNotFoundException ;
4
4
import android .content .DialogInterface ;
5
5
import android .content .Intent ;
6
+ import android .content .pm .PackageManager ;
6
7
import android .net .Uri ;
7
8
import android .os .Bundle ;
8
9
import android .text .InputType ;
17
18
18
19
import androidx .activity .result .ActivityResultLauncher ;
19
20
import androidx .activity .result .contract .ActivityResultContracts ;
21
+ import androidx .annotation .NonNull ;
20
22
import androidx .annotation .Nullable ;
21
23
import androidx .appcompat .app .AlertDialog ;
22
24
import androidx .appcompat .widget .Toolbar ;
25
+ import androidx .work .Data ;
26
+ import androidx .work .OneTimeWorkRequest ;
27
+ import androidx .work .OutOfQuotaPolicy ;
28
+ import androidx .work .WorkManager ;
29
+ import androidx .work .WorkRequest ;
23
30
24
31
import com .google .android .material .dialog .MaterialAlertDialogBuilder ;
25
32
import com .google .android .material .textfield .TextInputLayout ;
28
35
import java .io .InputStream ;
29
36
import java .io .OutputStream ;
30
37
import java .util .ArrayList ;
38
+ import java .util .Arrays ;
31
39
import java .util .List ;
32
40
33
41
import protect .card_locker .async .TaskHandler ;
34
42
import protect .card_locker .databinding .ImportExportActivityBinding ;
35
43
import protect .card_locker .importexport .DataFormat ;
36
44
import protect .card_locker .importexport .ImportExportResult ;
37
45
import protect .card_locker .importexport .ImportExportResultType ;
46
+ import protect .card_locker .importexport .ImportExportWorker ;
38
47
39
48
public class ImportExportActivity extends CatimaAppCompatActivity {
40
49
private ImportExportActivityBinding binding ;
41
50
private static final String TAG = "Catima" ;
42
51
43
- private ImportExportTask importExporter ;
44
-
45
52
private String importAlertTitle ;
46
53
private String importAlertMessage ;
47
54
private DataFormat importDataFormat ;
@@ -51,7 +58,10 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
51
58
private ActivityResultLauncher <String > fileOpenLauncher ;
52
59
private ActivityResultLauncher <Intent > filePickerLauncher ;
53
60
54
- final private TaskHandler mTasks = new TaskHandler ();
61
+ private static final int PERMISSION_REQUEST_EXPORT = 100 ;
62
+ private static final int PERMISSION_REQUEST_IMPORT = 101 ;
63
+
64
+ private WorkRequest mRequestedWorkRequest ;
55
65
56
66
@ Override
57
67
protected void onCreate (Bundle savedInstanceState ) {
@@ -80,15 +90,20 @@ protected void onCreate(Bundle savedInstanceState) {
80
90
Log .e (TAG , "Activity returned NULL uri" );
81
91
return ;
82
92
}
83
- try {
84
- OutputStream writer = getContentResolver ().openOutputStream (uri );
85
- Log .e (TAG , "Starting file export with: " + result .toString ());
86
- startExport (writer , uri , exportPassword .toCharArray (), true );
87
- } catch (IOException e ) {
88
- Log .e (TAG , "Failed to export file: " + result .toString (), e );
89
- onExportComplete (new ImportExportResult (ImportExportResultType .GenericFailure , result .toString ()), uri );
90
- }
91
93
94
+ Data exportRequestData = new Data .Builder ()
95
+ .putString (ImportExportWorker .INPUT_URI , uri .toString ())
96
+ .putString (ImportExportWorker .INPUT_ACTION , ImportExportWorker .ACTION_EXPORT )
97
+ .putString (ImportExportWorker .INPUT_FORMAT , DataFormat .Catima .name ())
98
+ .putString (ImportExportWorker .INPUT_PASSWORD , exportPassword )
99
+ .build ();
100
+
101
+ mRequestedWorkRequest = new OneTimeWorkRequest .Builder (ImportExportWorker .class )
102
+ .setInputData (exportRequestData )
103
+ .setExpedited (OutOfQuotaPolicy .RUN_AS_NON_EXPEDITED_WORK_REQUEST )
104
+ .build ();
105
+
106
+ PermissionUtils .requestPostNotificationsPermission (this , PERMISSION_REQUEST_EXPORT );
92
107
});
93
108
fileOpenLauncher = registerForActivityResult (new ActivityResultContracts .GetContent (), result -> {
94
109
if (result == null ) {
@@ -160,14 +175,19 @@ protected void onCreate(Bundle savedInstanceState) {
160
175
}
161
176
162
177
private void openFileForImport (Uri uri , char [] password ) {
163
- try {
164
- InputStream reader = getContentResolver ().openInputStream (uri );
165
- Log .e (TAG , "Starting file import with: " + uri .toString ());
166
- startImport (reader , uri , importDataFormat , password , true );
167
- } catch (IOException e ) {
168
- Log .e (TAG , "Failed to import file: " + uri .toString (), e );
169
- onImportComplete (new ImportExportResult (ImportExportResultType .GenericFailure , e .toString ()), uri , importDataFormat );
170
- }
178
+ Data importRequestData = new Data .Builder ()
179
+ .putString (ImportExportWorker .INPUT_URI , uri .toString ())
180
+ .putString (ImportExportWorker .INPUT_ACTION , ImportExportWorker .ACTION_IMPORT )
181
+ .putString (ImportExportWorker .INPUT_FORMAT , importDataFormat .name ())
182
+ .putString (ImportExportWorker .INPUT_PASSWORD , Arrays .toString (password ))
183
+ .build ();
184
+
185
+ mRequestedWorkRequest = new OneTimeWorkRequest .Builder (ImportExportWorker .class )
186
+ .setInputData (importRequestData )
187
+ .setExpedited (OutOfQuotaPolicy .RUN_AS_NON_EXPEDITED_WORK_REQUEST )
188
+ .build ();
189
+
190
+ PermissionUtils .requestPostNotificationsPermission (this , PERMISSION_REQUEST_IMPORT );
171
191
}
172
192
173
193
private void chooseImportType (boolean choosePicker ,
@@ -232,20 +252,17 @@ private void chooseImportType(boolean choosePicker,
232
252
new MaterialAlertDialogBuilder (this )
233
253
.setTitle (importAlertTitle )
234
254
.setMessage (importAlertMessage )
235
- .setPositiveButton (R .string .ok , new DialogInterface .OnClickListener () {
236
- @ Override
237
- public void onClick (DialogInterface dialog , int which ) {
238
- try {
239
- if (choosePicker ) {
240
- final Intent intentPickAction = new Intent (Intent .ACTION_PICK );
241
- filePickerLauncher .launch (intentPickAction );
242
- } else {
243
- fileOpenLauncher .launch ("*/*" );
244
- }
245
- } catch (ActivityNotFoundException e ) {
246
- Toast .makeText (getApplicationContext (), R .string .failedOpeningFileManager , Toast .LENGTH_LONG ).show ();
247
- Log .e (TAG , "No activity found to handle intent" , e );
255
+ .setPositiveButton (R .string .ok , (dialog1 , which1 ) -> {
256
+ try {
257
+ if (choosePicker ) {
258
+ final Intent intentPickAction = new Intent (Intent .ACTION_PICK );
259
+ filePickerLauncher .launch (intentPickAction );
260
+ } else {
261
+ fileOpenLauncher .launch ("*/*" );
248
262
}
263
+ } catch (ActivityNotFoundException e ) {
264
+ Toast .makeText (getApplicationContext (), R .string .failedOpeningFileManager , Toast .LENGTH_LONG ).show ();
265
+ Log .e (TAG , "No activity found to handle intent" , e );
249
266
}
250
267
})
251
268
.setNegativeButton (R .string .cancel , null )
@@ -254,55 +271,6 @@ public void onClick(DialogInterface dialog, int which) {
254
271
builder .show ();
255
272
}
256
273
257
- private void startImport (final InputStream target , final Uri targetUri , final DataFormat dataFormat , final char [] password , final boolean closeWhenDone ) {
258
- mTasks .flushTaskList (TaskHandler .TYPE .IMPORT , true , false , false );
259
- ImportExportTask .TaskCompleteListener listener = new ImportExportTask .TaskCompleteListener () {
260
- @ Override
261
- public void onTaskComplete (ImportExportResult result , DataFormat dataFormat ) {
262
- onImportComplete (result , targetUri , dataFormat );
263
- if (closeWhenDone ) {
264
- try {
265
- target .close ();
266
- } catch (IOException ioException ) {
267
- ioException .printStackTrace ();
268
- }
269
- }
270
- }
271
- };
272
-
273
- importExporter = new ImportExportTask (ImportExportActivity .this ,
274
- dataFormat , target , password , listener );
275
- mTasks .executeTask (TaskHandler .TYPE .IMPORT , importExporter );
276
- }
277
-
278
- private void startExport (final OutputStream target , final Uri targetUri , char [] password , final boolean closeWhenDone ) {
279
- mTasks .flushTaskList (TaskHandler .TYPE .EXPORT , true , false , false );
280
- ImportExportTask .TaskCompleteListener listener = new ImportExportTask .TaskCompleteListener () {
281
- @ Override
282
- public void onTaskComplete (ImportExportResult result , DataFormat dataFormat ) {
283
- onExportComplete (result , targetUri );
284
- if (closeWhenDone ) {
285
- try {
286
- target .close ();
287
- } catch (IOException ioException ) {
288
- ioException .printStackTrace ();
289
- }
290
- }
291
- }
292
- };
293
-
294
- importExporter = new ImportExportTask (ImportExportActivity .this ,
295
- DataFormat .Catima , target , password , listener );
296
- mTasks .executeTask (TaskHandler .TYPE .EXPORT , importExporter );
297
- }
298
-
299
- @ Override
300
- protected void onDestroy () {
301
- mTasks .flushTaskList (TaskHandler .TYPE .IMPORT , true , false , false );
302
- mTasks .flushTaskList (TaskHandler .TYPE .EXPORT , true , false , false );
303
- super .onDestroy ();
304
- }
305
-
306
274
@ Override
307
275
public boolean onOptionsItemSelected (MenuItem item ) {
308
276
int id = item .getItemId ();
@@ -343,68 +311,39 @@ private void retryWithPassword(DataFormat dataFormat, Uri uri) {
343
311
builder .show ();
344
312
}
345
313
346
- private String buildResultDialogMessage (ImportExportResult result , boolean isImport ) {
347
- int messageId ;
348
-
349
- if (result .resultType () == ImportExportResultType .Success ) {
350
- messageId = isImport ? R .string .importSuccessful : R .string .exportSuccessful ;
351
- } else {
352
- messageId = isImport ? R .string .importFailed : R .string .exportFailed ;
353
- }
354
-
355
- StringBuilder messageBuilder = new StringBuilder (getResources ().getString (messageId ));
356
- if (result .developerDetails () != null ) {
357
- messageBuilder .append ("\n \n " );
358
- messageBuilder .append (getResources ().getString (R .string .include_if_asking_support ));
359
- messageBuilder .append ("\n \n " );
360
- messageBuilder .append (result .developerDetails ());
361
- }
362
-
363
- return messageBuilder .toString ();
364
- }
365
-
366
- private void onImportComplete (ImportExportResult result , Uri path , DataFormat dataFormat ) {
367
- ImportExportResultType resultType = result .resultType ();
368
-
369
- if (resultType == ImportExportResultType .BadPassword ) {
370
- retryWithPassword (dataFormat , path );
371
- return ;
372
- }
373
-
374
- AlertDialog .Builder builder = new MaterialAlertDialogBuilder (this );
375
- builder .setTitle (resultType == ImportExportResultType .Success ? R .string .importSuccessfulTitle : R .string .importFailedTitle );
376
- builder .setMessage (buildResultDialogMessage (result , true ));
377
- builder .setNeutralButton (R .string .ok , (dialog , which ) -> dialog .dismiss ());
314
+ @ Override
315
+ public void onRequestPermissionsResult (int requestCode , @ NonNull String [] permissions , @ NonNull int [] grantResults ) {
316
+ super .onRequestPermissionsResult (requestCode , permissions , grantResults );
378
317
379
- builder . create (). show ( );
318
+ onMockedRequestPermissionsResult ( requestCode , permissions , grantResults );
380
319
}
381
320
382
- private void onExportComplete (ImportExportResult result , final Uri path ) {
383
- ImportExportResultType resultType = result .resultType ();
321
+ public void onMockedRequestPermissionsResult (int requestCode , @ NonNull String [] permissions , @ NonNull int [] grantResults ) {
322
+ boolean granted = grantResults .length > 0 && grantResults [0 ] == PackageManager .PERMISSION_GRANTED ;
323
+ Integer failureReason = null ;
384
324
385
- AlertDialog .Builder builder = new MaterialAlertDialogBuilder (this );
386
- builder .setTitle (resultType == ImportExportResultType .Success ? R .string .exportSuccessfulTitle : R .string .exportFailedTitle );
387
- builder .setMessage (buildResultDialogMessage (result , false ));
388
- builder .setNeutralButton (R .string .ok , (dialog , which ) -> dialog .dismiss ());
325
+ if (requestCode == PERMISSION_REQUEST_EXPORT ) {
326
+ if (granted ) {
327
+ WorkManager .getInstance (this ).enqueue (mRequestedWorkRequest );
389
328
390
- if (resultType == ImportExportResultType .Success ) {
391
- final CharSequence sendLabel = ImportExportActivity .this .getResources ().getText (R .string .sendLabel );
392
-
393
- builder .setPositiveButton (sendLabel , (dialog , which ) -> {
394
- Intent sendIntent = new Intent (Intent .ACTION_SEND );
395
- sendIntent .putExtra (Intent .EXTRA_STREAM , path );
396
- sendIntent .setType ("text/csv" );
329
+ Toast .makeText (this , R .string .exportStartedCheckNotifications , Toast .LENGTH_LONG ).show ();
330
+ return ;
331
+ }
397
332
398
- // set flag to give temporary permission to external app to use the FileProvider
399
- sendIntent .setFlags (Intent .FLAG_GRANT_READ_URI_PERMISSION );
333
+ failureReason = R .string .postNotificationsPermissionRequired ;
334
+ } else if (requestCode == PERMISSION_REQUEST_IMPORT ) {
335
+ if (granted ) {
336
+ WorkManager .getInstance (this ).enqueue (mRequestedWorkRequest );
400
337
401
- ImportExportActivity .this .startActivity (Intent .createChooser (sendIntent ,
402
- sendLabel ));
338
+ Toast .makeText (this , R .string .importStartedCheckNotifications , Toast .LENGTH_LONG ).show ();
339
+ return ;
340
+ }
403
341
404
- dialog .dismiss ();
405
- });
342
+ failureReason = R .string .postNotificationsPermissionRequired ;
406
343
}
407
344
408
- builder .create ().show ();
345
+ if (failureReason != null ) {
346
+ Toast .makeText (this , failureReason , Toast .LENGTH_LONG ).show ();
347
+ }
409
348
}
410
349
}
0 commit comments