19
19
package org .kontalk .ui .prefs ;
20
20
21
21
import android .annotation .TargetApi ;
22
+ import android .app .Activity ;
23
+ import android .content .ActivityNotFoundException ;
22
24
import android .content .Context ;
25
+ import android .net .Uri ;
23
26
import android .os .Build ;
24
27
import android .os .Environment ;
28
+
29
+ import androidx .fragment .app .Fragment ;
25
30
import androidx .preference .Preference ;
26
31
import android .util .AttributeSet ;
27
32
import android .widget .Toast ;
28
33
34
+ import org .kontalk .Kontalk ;
35
+ import org .kontalk .Log ;
29
36
import org .kontalk .R ;
30
37
import org .kontalk .provider .MessagesProvider ;
38
+ import org .kontalk .reporting .ReportingManager ;
31
39
import org .kontalk .util .DataUtils ;
40
+ import org .kontalk .util .MediaStorage ;
32
41
33
42
import java .io .File ;
34
43
import java .io .FileInputStream ;
37
46
import java .io .InputStream ;
38
47
import java .io .OutputStream ;
39
48
49
+ import com .afollestad .materialdialogs .folderselector .FolderChooserDialog ;
50
+
40
51
41
52
/**
42
53
* Preference for copying the messages database to the external storage.
43
54
* @author Daniele Ricci
44
55
*/
45
56
public class CopyDatabasePreference extends Preference {
57
+ private static final String TAG = Kontalk .TAG ;
58
+
59
+ public static final int REQUEST_COPY_DATABASE = Activity .RESULT_FIRST_USER + 4 ;
60
+
61
+ private static final String DBFILE_MIME = "application/x-sqlite3" ;
62
+ public static final String DBFILE_NAME = "kontalk-messages.db" ;
63
+
64
+ private Fragment mFragment ;
46
65
47
66
public CopyDatabasePreference (Context context ) {
48
67
super (context );
@@ -69,25 +88,80 @@ private void init() {
69
88
setOnPreferenceClickListener (new OnPreferenceClickListener () {
70
89
@ Override
71
90
public boolean onPreferenceClick (Preference preference ) {
72
- copyDatabase (getContext ());
91
+ requestFile (getContext ());
73
92
return true ;
74
93
}
75
94
});
76
95
}
77
96
78
- void copyDatabase (Context context ) {
79
- MessagesProvider .lockForImport (context );
97
+ public void setParentFragment (Fragment fragment ) {
98
+ mFragment = fragment ;
99
+ }
80
100
81
- InputStream dbIn = null ;
101
+ void requestFile (Context context ) {
102
+ try {
103
+ if (MediaStorage .isStorageAccessFrameworkAvailable ()) {
104
+ MediaStorage .createFile (mFragment , DBFILE_MIME , DBFILE_NAME ,
105
+ REQUEST_COPY_DATABASE );
106
+ return ;
107
+ }
108
+ }
109
+ catch (ActivityNotFoundException e ) {
110
+ Log .w (TAG , "Storage Access Framework not working properly" );
111
+ ReportingManager .logException (e );
112
+ }
113
+
114
+ // also used as a fallback if SAF is not working properly
115
+ Context ctx = getContext ();
116
+ if (ctx != null ) {
117
+ new FolderChooserDialog .Builder (ctx )
118
+ .tag (getClass ().getName ())
119
+ .initialPath (Environment .getExternalStorageDirectory ().toString ())
120
+ .show (mFragment .getParentFragmentManager ());
121
+ }
122
+ }
123
+
124
+ public static void copyDatabase (Context context , File dbOutFile ) {
82
125
OutputStream dbOut = null ;
83
126
try {
84
- File dbOutFile = new File (Environment .getExternalStorageDirectory (), "kontalk-messages.db" );
127
+ dbOut = new FileOutputStream (dbOutFile );
128
+ copyDatabase (context , dbOut , dbOut .toString ());
129
+ }
130
+ catch (IOException e ) {
131
+ Toast .makeText (context , context
132
+ .getString (R .string .msg_copy_database_failed , e .toString ()), Toast .LENGTH_LONG )
133
+ .show ();
134
+ }
135
+ finally {
136
+ DataUtils .close (dbOut );
137
+ }
138
+ }
139
+
140
+ public static void copyDatabase (Context context , Uri dbOutFile ) {
141
+ OutputStream dbOut = null ;
142
+ try {
143
+ dbOut = context .getContentResolver ().openOutputStream (dbOutFile );
144
+ copyDatabase (context , dbOut , dbOutFile .toString ());
145
+ }
146
+ catch (IOException e ) {
147
+ Toast .makeText (context , context
148
+ .getString (R .string .msg_copy_database_failed , e .toString ()), Toast .LENGTH_LONG )
149
+ .show ();
150
+ }
151
+ finally {
152
+ DataUtils .close (dbOut );
153
+ }
154
+ }
85
155
156
+ private static void copyDatabase (Context context , OutputStream dbOut , String filename ) {
157
+ MessagesProvider .lockForImport (context );
158
+
159
+ InputStream dbIn = null ;
160
+ try {
86
161
dbIn = new FileInputStream (MessagesProvider .getDatabaseUri (context ));
87
- dbOut = new FileOutputStream (dbOutFile );
88
162
DataUtils .copy (dbIn , dbOut );
89
163
Toast .makeText (context , context
90
- .getString (R .string .msg_copy_database_success , dbOutFile . toString () ), Toast .LENGTH_LONG )
164
+ .getString (R .string .msg_copy_database_success , filename ), Toast .LENGTH_LONG )
91
165
.show ();
92
166
}
93
167
catch (IOException e ) {
0 commit comments