@@ -146,10 +146,10 @@ public class MediaAppControllerActivity extends AppCompatActivity {
146
146
private MediaBrowserCompat mBrowserExtraSuggested ;
147
147
private AudioFocusHelper mAudioFocusHelper ;
148
148
private RatingUiHelper mRatingUiHelper ;
149
- private CustomControlsAdapter mCustomControlsAdapter = new CustomControlsAdapter ();
150
- private BrowseMediaItemsAdapter mBrowseMediaItemsAdapter = new BrowseMediaItemsAdapter ();
151
- private BrowseMediaItemsAdapter mBrowseMediaItemsExtraSuggestedAdapter = new BrowseMediaItemsAdapter ();
152
- private SearchMediaItemsAdapter mSearchMediaItemsAdapter = new SearchMediaItemsAdapter ();
149
+ private final CustomControlsAdapter mCustomControlsAdapter = new CustomControlsAdapter ();
150
+ private final BrowseMediaItemsAdapter mBrowseMediaItemsAdapter = new BrowseMediaItemsAdapter ();
151
+ private final BrowseMediaItemsAdapter mBrowseMediaItemsExtraSuggestedAdapter = new BrowseMediaItemsAdapter ();
152
+ private final SearchMediaItemsAdapter mSearchMediaItemsAdapter = new SearchMediaItemsAdapter ();
153
153
154
154
private ViewPager mViewPager ;
155
155
private Spinner mInputTypeView ;
@@ -275,6 +275,7 @@ public Object instantiateItem(@NonNull ViewGroup container, int position) {
275
275
mBrowseMediaItemsAdapter .init (findViewById (R .id .media_browse_tree_top ),
276
276
findViewById (R .id .media_browse_tree_up ), findViewById (R .id .media_browse_tree_save ));
277
277
278
+
278
279
final RecyclerView browseTreeListExtraSuggested = findViewById (R .id .media_items_list_extra_suggested );
279
280
browseTreeListExtraSuggested .setLayoutManager (new LinearLayoutManager (this ));
280
281
browseTreeListExtraSuggested .setHasFixedSize (true );
@@ -297,12 +298,10 @@ public Object instantiateItem(@NonNull ViewGroup container, int position) {
297
298
}
298
299
299
300
300
-
301
301
@ Override
302
302
public void onRequestPermissionsResult (int requestCode ,
303
303
@ NonNull String [] permissions ,
304
- @ NonNull int [] grantResults )
305
- {
304
+ @ NonNull int [] grantResults ) {
306
305
super .onRequestPermissionsResult (requestCode ,
307
306
permissions ,
308
307
grantResults );
@@ -314,8 +313,7 @@ public void onRequestPermissionsResult(int requestCode,
314
313
"Storage Permission Granted, can save browse tree." ,
315
314
Toast .LENGTH_SHORT )
316
315
.show ();
317
- }
318
- else {
316
+ } else {
319
317
Toast .makeText (getApplicationContext (),
320
318
"Storage Permission Denied, can not save browse tree to file." ,
321
319
Toast .LENGTH_SHORT )
@@ -440,6 +438,7 @@ private void setupMedia() {
440
438
public void onConnected () {
441
439
setupMediaController ();
442
440
mBrowseMediaItemsAdapter .setRoot (mBrowser .getRoot ());
441
+ Log .i (TAG , "Root of browse tree connected" );
443
442
}
444
443
445
444
@ Override
@@ -1155,13 +1154,14 @@ private class BrowseMediaItemsAdapter extends
1155
1154
RecyclerView .Adapter <BrowseMediaItemsAdapter .ViewHolder > {
1156
1155
1157
1156
private List <MediaBrowserCompat .MediaItem > mItems ;
1158
- private Stack <String > mNodes = new Stack <>();
1157
+ private final Stack <String > mNodes = new Stack <>();
1159
1158
1160
1159
MediaBrowserCompat .SubscriptionCallback callback =
1161
1160
new MediaBrowserCompat .SubscriptionCallback () {
1162
1161
@ Override
1163
1162
public void onChildrenLoaded (@ NonNull String parentId ,
1164
1163
@ NonNull List <MediaItem > children ) {
1164
+ Log .i (TAG , "Children loaded." );
1165
1165
updateItemsEmptyIfNull (children );
1166
1166
}
1167
1167
};
@@ -1174,9 +1174,13 @@ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
1174
1174
.inflate (R .layout .media_browse_item , parent , false ));
1175
1175
}
1176
1176
1177
+
1178
+
1177
1179
@ Override
1178
- public void onBindViewHolder (@ NonNull ViewHolder holder , int position ) {
1180
+ public void onBindViewHolder (@ NonNull ViewHolder holder , int position ){
1181
+ Log .i (TAG , "On Bind view holder" );
1179
1182
if (mNodes .size () == 0 ) {
1183
+ Log .i (TAG , "Setting to no browser" );
1180
1184
holder .name .setText (getString (R .string .media_no_browser ));
1181
1185
holder .name .setVisibility (View .VISIBLE );
1182
1186
holder .description .setVisibility (View .GONE );
@@ -1186,6 +1190,7 @@ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
1186
1190
return ;
1187
1191
}
1188
1192
if (mItems == null ) {
1193
+ Log .i (TAG , "Setting to loading" );
1189
1194
holder .name .setText (getString (R .string .media_browse_tree_loading ));
1190
1195
holder .name .setVisibility (View .VISIBLE );
1191
1196
holder .description .setVisibility (View .GONE );
@@ -1195,6 +1200,7 @@ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
1195
1200
return ;
1196
1201
}
1197
1202
if (mItems .size () == 0 ) {
1203
+ Log .i (TAG , "Setting to empty" );
1198
1204
holder .name .setText (getString (R .string .media_browse_tree_empty ));
1199
1205
holder .name .setVisibility (View .VISIBLE );
1200
1206
holder .description .setVisibility (View .GONE );
@@ -1203,7 +1209,7 @@ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
1203
1209
});
1204
1210
return ;
1205
1211
}
1206
-
1212
+ Log . i ( TAG , "Populating media items" );
1207
1213
final MediaBrowserCompat .MediaItem item = mItems .get (position );
1208
1214
holder .name .setText (item .getDescription ().getTitle ());
1209
1215
holder .name .setVisibility (View .VISIBLE );
@@ -1234,6 +1240,7 @@ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
1234
1240
});
1235
1241
}
1236
1242
1243
+
1237
1244
@ Override
1238
1245
public int getItemCount () {
1239
1246
if (mNodes .size () == 0 || mItems == null || mItems .size () == 0 ) {
@@ -1244,13 +1251,15 @@ public int getItemCount() {
1244
1251
1245
1252
void updateItemsEmptyIfNull (List <MediaBrowserCompat .MediaItem > items ) {
1246
1253
if (items == null ) {
1254
+ Log .i (TAG , "Trying to update an null list" );
1247
1255
updateItems (Collections .emptyList ());
1248
1256
} else {
1249
1257
updateItems (items );
1250
1258
}
1251
1259
}
1252
1260
1253
1261
void updateItems (List <MediaBrowserCompat .MediaItem > items ) {
1262
+ Log .i (TAG , "Updating items" );
1254
1263
mItems = items ;
1255
1264
notifyDataSetChanged ();
1256
1265
}
@@ -1283,88 +1292,91 @@ void init(View topButtonView, View upButtonView, View saveButtonView) {
1283
1292
});
1284
1293
}
1285
1294
if (saveButtonView != null ) {
1286
- notifyDataSetChanged ();
1287
1295
1288
1296
// Go to root of browse tree
1297
+ // TODO: Fix race condition with subscription callback
1289
1298
unsubscribe ();
1290
1299
while (mNodes .size () > 1 ) {
1291
1300
mNodes .pop ();
1292
1301
}
1293
1302
subscribe ();
1294
-
1295
1303
saveButtonView .setOnClickListener (
1296
1304
v -> {
1297
1305
1298
1306
if (mNodes .isEmpty ()) {
1299
1307
Toast toast =
1300
1308
Toast .makeText (
1301
- getApplicationContext (), "List Empty, nothing saved! " , Toast .LENGTH_LONG );
1309
+ getApplicationContext (),
1310
+ "List Empty, nothing saved! " , Toast .LENGTH_LONG );
1302
1311
toast .setMargin (50 , 50 );
1303
1312
toast .show ();
1304
1313
return ;
1305
1314
}
1315
+
1316
+ // Create output file
1306
1317
File root = android .os .Environment .getExternalStorageDirectory ();
1307
1318
String dirs_path = root .getAbsolutePath () + "/Temp/" ;
1308
1319
File dirs = new File (dirs_path );
1309
- File file = new File (dirs .getAbsolutePath (), "_BrowseTreeContent.txt" );
1310
- if (file .exists ()){
1320
+ dirs .mkdirs ();
1321
+ File file = new File (dirs .getAbsolutePath (),
1322
+ "_BrowseTreeContent.txt" );
1323
+ if (file .exists ()) {
1311
1324
file .delete ();
1312
1325
}
1313
1326
try {
1314
1327
final FileOutputStream f = new FileOutputStream (file );
1315
-
1316
- PrintWriter pw = new PrintWriter (f );
1317
- // We print the file path at the beginning of the file so that we can use it
1318
- // to pull the file from platform to local computer.
1319
-
1320
- pw .println (file .toString ());
1321
- if (mItems == null ){
1322
- Toast toast =
1323
- Toast .makeText (
1324
- getApplicationContext (),
1325
- "No media items found, could not save tree." ,
1326
- Toast .LENGTH_LONG );
1327
- toast .setMargin (50 , 50 );
1328
- toast .show ();
1329
- return ;
1330
- }
1331
- pw .println ("Root:" );
1332
- Semaphore writeCompleted = new Semaphore (1 );
1333
- ExecutorService executorService = Executors .newFixedThreadPool (4 );
1334
- executorService .execute (new Runnable () {
1335
- @ Override
1336
- public void run () {
1337
- for (MediaBrowserCompat .MediaItem item : mItems ) {
1338
- try {
1339
- writeCompleted .acquire ();
1340
- } catch (InterruptedException e ) {
1341
- e .printStackTrace ();
1342
- }
1343
- writeMediaItemToFile (item , pw , 1 , executorService );
1344
- writeCompleted .release ();
1345
-
1328
+ PrintWriter pw = new PrintWriter (f );
1329
+ if (mItems == null ){
1330
+ Log .i (TAG , "Nodes: " + mNodes .toString ());
1331
+ subscribe ();
1332
+ Toast toast =
1333
+ Toast .makeText (
1334
+ getApplicationContext (),
1335
+ "No media items found, could not save tree." ,
1336
+ Toast .LENGTH_LONG );
1337
+ toast .setMargin (50 , 50 );
1338
+ toast .show ();
1339
+ return ;
1346
1340
}
1347
-
1348
- Log .i (TAG , "CLOSING FILE" );
1349
- pw .flush ();
1350
- pw .close ();
1351
- try {
1352
- f .close ();
1353
- } catch (IOException e ) {
1354
- e .printStackTrace ();
1355
- }
1356
- runOnUiThread (new Runnable () {
1341
+ pw .println ("Root:" );
1342
+ Semaphore writeCompleted = new Semaphore (1 );
1343
+ ExecutorService executorService =
1344
+ Executors .newFixedThreadPool (4 );
1345
+ executorService .execute (new Runnable () {
1346
+ @ Override
1357
1347
public void run () {
1358
- Toast toast =
1359
- Toast .makeText (
1360
- getApplicationContext (),
1361
- "MediaItems saved to " + file .getAbsolutePath (),
1362
- Toast .LENGTH_LONG );
1363
- toast .setMargin (50 , 50 );
1364
- toast .show ();
1348
+ for (MediaBrowserCompat .MediaItem item : mItems ) {
1349
+ try {
1350
+ writeCompleted .acquire ();
1351
+ } catch (InterruptedException e ) {
1352
+ e .printStackTrace ();
1353
+ }
1354
+ writeMediaItemToFile (item , pw , 1 ,
1355
+ executorService );
1356
+ writeCompleted .release ();
1357
+
1358
+ }
1359
+ pw .flush ();
1360
+ pw .close ();
1361
+ try {
1362
+ f .close ();
1363
+ } catch (IOException e ) {
1364
+ e .printStackTrace ();
1365
+ }
1366
+ runOnUiThread (new Runnable () {
1367
+ public void run () {
1368
+ Toast toast =
1369
+ Toast .makeText (
1370
+ getApplicationContext (),
1371
+ "MediaItems saved to " +
1372
+ file .getAbsolutePath (),
1373
+ Toast .LENGTH_LONG );
1374
+ toast .setMargin (50 , 50 );
1375
+ toast .show ();
1376
+ }
1377
+ });
1365
1378
}
1366
1379
});
1367
- }});
1368
1380
} catch (FileNotFoundException e ) {
1369
1381
e .printStackTrace ();
1370
1382
}
@@ -1374,13 +1386,15 @@ public void run() {
1374
1386
}
1375
1387
1376
1388
@ RequiresApi (api = Build .VERSION_CODES .N )
1377
- private void writeMediaItemToFile (MediaItem mediaItem , PrintWriter printWriter , int depth , ExecutorService executorService ){
1378
- if (mediaItem != null ) {
1389
+ private void writeMediaItemToFile (MediaItem mediaItem , PrintWriter printWriter , int depth ,
1390
+ ExecutorService executorService ) {
1391
+ if (mediaItem != null ) {
1379
1392
MediaDescriptionCompat descriptionCompat = mediaItem .getDescription ();
1380
1393
if (descriptionCompat != null ) {
1381
1394
1382
1395
// Tab the media item to the respective depth
1383
- String tabStr = new String (new char [depth ]).replace ("\0 " , "\t " );
1396
+ String tabStr = new String (new char [depth ]).replace ("\0 " ,
1397
+ "\t " );
1384
1398
1385
1399
String titleStr = descriptionCompat .getTitle () != null
1386
1400
? descriptionCompat .getTitle ().toString ()
@@ -1389,18 +1403,21 @@ private void writeMediaItemToFile(MediaItem mediaItem, PrintWriter printWriter,
1389
1403
? descriptionCompat .getSubtitle ().toString ()
1390
1404
: "NAN" ;
1391
1405
String mIDStr = descriptionCompat .getMediaId () != null
1392
- ? descriptionCompat .getMediaId (). toString ()
1406
+ ? descriptionCompat .getMediaId ()
1393
1407
: "NAN" ;
1394
1408
String uriStr = descriptionCompat .getMediaUri () != null
1395
1409
? descriptionCompat .getMediaUri ().toString ()
1396
1410
: "NAN" ;
1397
1411
String desStr = descriptionCompat .getDescription () != null
1398
1412
? descriptionCompat .getDescription ().toString ()
1399
1413
: "NAN" ;
1400
- String infoStr = String .format ("%sTitle:%s,Subtitle:%s,MediaId:%s,URI:%s,Description:%s" , tabStr , titleStr , subTitleStr , mIDStr , uriStr , desStr );
1414
+ String infoStr = String .format (
1415
+ "%sTitle:%s,Subtitle:%s,MediaId:%s,URI:%s,Description:%s" ,
1416
+ tabStr , titleStr , subTitleStr , mIDStr , uriStr , desStr );
1401
1417
Log .i (TAG , "Logging media item: " + infoStr + " at depth: " + depth );
1402
1418
printWriter .println (infoStr );
1403
1419
}
1420
+ // If a media item is not a leaf continue DFS on it
1404
1421
if (mediaItem .isBrowsable ()) {
1405
1422
Log .i (TAG , "Media Item is browseable" );
1406
1423
Semaphore loaded = new Semaphore (1 );
@@ -1413,10 +1430,12 @@ private void writeMediaItemToFile(MediaItem mediaItem, PrintWriter printWriter,
1413
1430
executorService .execute (new Runnable () {
1414
1431
@ Override
1415
1432
public void run () {
1416
- mBrowser .subscribe (mediaItem .getMediaId (), new MediaBrowserCompat .SubscriptionCallback () {
1433
+ mBrowser .subscribe (mediaItem .getMediaId (),
1434
+ new MediaBrowserCompat .SubscriptionCallback () {
1417
1435
@ Override
1418
- public void onChildrenLoaded (@ NonNull String parentId , @ NonNull List <MediaItem > children ) {
1419
- Log .i (TAG , "Children loaded" );
1436
+ public void onChildrenLoaded (@ NonNull String parentId ,
1437
+ @ NonNull List <MediaItem > children ) {
1438
+ // Notify the main thread that all of the children have loaded
1420
1439
mChildren .addAll (children );
1421
1440
loaded .release ();
1422
1441
super .onChildrenLoaded (parentId , children );
@@ -1425,18 +1444,20 @@ public void onChildrenLoaded(@NonNull String parentId, @NonNull List
1425
1444
}
1426
1445
});
1427
1446
1447
+ // Wait for all of the media children to be loaded before continuing DFS
1428
1448
try {
1429
1449
loaded .acquire ();
1430
1450
} catch (InterruptedException e ) {
1431
1451
e .printStackTrace ();
1432
1452
}
1433
- Log .i (TAG , "Childeren finished loading" );
1453
+
1454
+ // Run DFS on all of the nodes children
1434
1455
for (MediaItem mediaItemChild : mChildren ) {
1435
- writeMediaItemToFile (mediaItemChild , printWriter , depth + 1 , executorService );
1456
+ writeMediaItemToFile (mediaItemChild , printWriter , depth + 1 ,
1457
+ executorService );
1436
1458
}
1437
1459
}
1438
1460
}
1439
-
1440
1461
}
1441
1462
1442
1463
protected void subscribe () {
0 commit comments