1
1
package com.example.android.mediacontroller
2
2
3
3
import android.content.Context
4
- import android.os.Environment
5
4
import android.os.Handler
6
5
import android.os.Looper
7
6
import android.support.v4.media.MediaBrowserCompat
8
7
import android.support.v4.media.MediaBrowserCompat.SubscriptionCallback
9
8
import android.util.Log
10
9
import android.widget.Toast
11
- import java.io.File
12
- import java.io.FileOutputStream
13
- import java.io.IOException
10
+ import java.io.OutputStream
14
11
import java.io.PrintWriter
15
12
import java.util.concurrent.ExecutorService
16
13
import java.util.concurrent.Executors
17
14
import java.util.concurrent.Semaphore
18
15
19
- class MediaBrowseTreeSnapshot (private val mBrowser : MediaBrowserCompat , private val mContext : Context ) {
16
+
17
+ class MediaBrowseTreeSnapshot (private val context : Context , private val browser : MediaBrowserCompat ) {
20
18
private val TAG = " MediaBrowseTreeSnapshot"
21
19
22
- fun takeBrowserSnapshot () {
20
+ /* *
21
+ * Loads the browsers top level children and runs a DFS on them printing out
22
+ * each media item's contentes as it is visited.
23
+ */
24
+ fun takeBrowserSnapshot (outputStream : OutputStream ) {
23
25
val loaded = Semaphore (1 )
24
26
val executorService = Executors .newFixedThreadPool(4 )
25
27
val mItems: MutableList <MediaBrowserCompat .MediaItem > = ArrayList ()
@@ -29,7 +31,7 @@ class MediaBrowseTreeSnapshot(private val mBrowser: MediaBrowserCompat, private
29
31
} catch (e: InterruptedException ) {
30
32
e.printStackTrace()
31
33
}
32
- mBrowser .subscribe(mBrowser .root, object : SubscriptionCallback () {
34
+ browser .subscribe(browser .root, object : SubscriptionCallback () {
33
35
override fun onChildrenLoaded (parentId : String ,
34
36
children : List <MediaBrowserCompat .MediaItem >) {
35
37
// Notify the main thread that all of the children have loaded
@@ -49,42 +51,23 @@ class MediaBrowseTreeSnapshot(private val mBrowser: MediaBrowserCompat, private
49
51
}
50
52
51
53
if (mItems.size > 0 ) {
52
- initDFSOnBrowseTree (mItems, executorService)
54
+ runDFSOnBrowseTree (mItems, executorService, outputStream )
53
55
} else {
54
56
notifyUser(" No media items found, could not save tree." )
55
57
}
56
58
}
57
59
}
58
60
59
- private fun initDFSOnBrowseTree (mItems : MutableList <MediaBrowserCompat .MediaItem >, executorService : ExecutorService ) {
60
- val root = Environment .getExternalStorageDirectory()
61
- val dirsPath = root.absolutePath + " /Temp/"
62
- val dirs = File (dirsPath)
63
- dirs.mkdirs()
64
- val file = File (dirs.absolutePath,
65
- " _BrowseTreeContent.txt" )
66
- if (file.exists()) {
67
- file.delete()
68
- }
69
- try {
70
- val f = FileOutputStream (file)
71
- val pw = PrintWriter (f)
72
- runDFSOnBrowseTree(mItems, executorService, pw)
73
- pw.flush()
74
- pw.close()
75
- f.close()
76
- } catch (e: IOException ) {
77
- e.printStackTrace()
78
- }
79
- notifyUser(" MediaItems saved to " +
80
- file.absolutePath)
81
- }
82
-
83
- private fun runDFSOnBrowseTree (mItems : MutableList <MediaBrowserCompat .MediaItem >, executorService : ExecutorService , printWriter : PrintWriter ) {
61
+ /* *
62
+ * Kicks off the browse tree depth first search by visiting all of the top level media
63
+ * item nodes.
64
+ */
65
+ private fun runDFSOnBrowseTree (mediaItems : MutableList <MediaBrowserCompat .MediaItem >, executorService : ExecutorService , outputStream : OutputStream ) {
66
+ val printWriter = PrintWriter (outputStream)
84
67
printWriter.println (" Root:" )
85
68
val writeCompleted = Semaphore (1 )
86
69
executorService.execute {
87
- for (item in mItems ) {
70
+ for (item in mediaItems ) {
88
71
try {
89
72
writeCompleted.acquire()
90
73
} catch (e: InterruptedException ) {
@@ -94,9 +77,16 @@ class MediaBrowseTreeSnapshot(private val mBrowser: MediaBrowserCompat, private
94
77
executorService)
95
78
writeCompleted.release()
96
79
}
80
+ printWriter.flush()
81
+ printWriter.close()
82
+ outputStream.close()
83
+ notifyUser(" MediaItems saved to specified location." )
97
84
}
98
85
}
99
86
87
+ /* *
88
+ * Visits a media item node by printing out its contents and then visiting all of its children.
89
+ */
100
90
private fun visitMediaItemNode (mediaItem : MediaBrowserCompat .MediaItem ? , printWriter : PrintWriter , depth : Int ,
101
91
executorService : ExecutorService ) {
102
92
if (mediaItem != null ) {
@@ -111,14 +101,14 @@ class MediaBrowseTreeSnapshot(private val mBrowser: MediaBrowserCompat, private
111
101
} catch (e: InterruptedException ) {
112
102
e.printStackTrace()
113
103
}
114
- val mChildren : MutableList <MediaBrowserCompat .MediaItem > = ArrayList ()
104
+ val mediaChildren : MutableList <MediaBrowserCompat .MediaItem > = ArrayList ()
115
105
executorService.execute {
116
- mBrowser .subscribe(mid,
106
+ browser .subscribe(mid,
117
107
object : SubscriptionCallback () {
118
108
override fun onChildrenLoaded (parentId : String ,
119
109
children : List <MediaBrowserCompat .MediaItem >) {
120
110
// Notify the main thread that all of the children have loaded
121
- mChildren .addAll(children)
111
+ mediaChildren .addAll(children)
122
112
loaded.release()
123
113
super .onChildrenLoaded(parentId, children)
124
114
}
@@ -133,14 +123,17 @@ class MediaBrowseTreeSnapshot(private val mBrowser: MediaBrowserCompat, private
133
123
}
134
124
135
125
// Run visit on all of the nodes children
136
- for (mediaItemChild in mChildren ) {
126
+ for (mediaItemChild in mediaChildren ) {
137
127
visitMediaItemNode(mediaItemChild, printWriter, depth + 1 ,
138
128
executorService)
139
129
}
140
130
}
141
131
}
142
132
}
143
133
134
+ /* *
135
+ * Prints the contents of a media item using a print writer.
136
+ */
144
137
private fun printMediaItemDescription (printWriter : PrintWriter , mediaItem : MediaBrowserCompat .MediaItem , depth : Int ) {
145
138
val descriptionCompat = mediaItem.description
146
139
// Tab the media item to the respective depth
@@ -154,13 +147,17 @@ class MediaBrowseTreeSnapshot(private val mBrowser: MediaBrowserCompat, private
154
147
val infoStr = String .format(
155
148
" %sTitle:%s,Subtitle:%s,MediaId:%s,URI:%s,Description:%s" ,
156
149
tabStr, titleStr, subTitleStr, mIDStr, uriStr, desStr)
150
+ Log .i(TAG , " Writing media Item" );
157
151
printWriter.println (infoStr)
158
152
}
159
153
154
+ /* *
155
+ * Display formatted toast to user.
156
+ */
160
157
private fun notifyUser (textToNotify : String ) {
161
158
Handler (Looper .getMainLooper()).post {
162
159
val toast = Toast .makeText(
163
- mContext ,
160
+ context ,
164
161
textToNotify,
165
162
Toast .LENGTH_LONG )
166
163
toast.setMargin(50f , 50f )
0 commit comments