Skip to content

Commit f2ceac9

Browse files
committed
Add missing FileReaderPreference
1 parent 430af75 commit f2ceac9

File tree

1 file changed

+177
-0
lines changed

1 file changed

+177
-0
lines changed
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
package com.wmods.wppenhacer.preference;
2+
3+
import android.Manifest;
4+
import android.app.Activity;
5+
import android.content.Context;
6+
import android.content.Intent;
7+
import android.content.pm.PackageManager;
8+
import android.net.Uri;
9+
import android.os.Build;
10+
import android.os.Environment;
11+
import android.util.AttributeSet;
12+
import android.widget.Toast;
13+
14+
import androidx.annotation.NonNull;
15+
import androidx.annotation.Nullable;
16+
import androidx.annotation.RequiresApi;
17+
import androidx.core.content.ContextCompat;
18+
import androidx.preference.Preference;
19+
import androidx.preference.PreferenceManager;
20+
21+
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
22+
import com.wmods.wppenhacer.R;
23+
import com.wmods.wppenhacer.utils.FilePicker;
24+
import com.wmods.wppenhacer.utils.RealPathUtil;
25+
26+
import org.w3c.dom.Document;
27+
import org.xml.sax.SAXException;
28+
29+
import java.io.File;
30+
import java.io.FileInputStream;
31+
import java.io.IOException;
32+
import java.io.InputStream;
33+
import java.io.StringWriter;
34+
35+
import javax.xml.parsers.DocumentBuilder;
36+
import javax.xml.parsers.DocumentBuilderFactory;
37+
import javax.xml.parsers.ParserConfigurationException;
38+
import javax.xml.transform.Transformer;
39+
import javax.xml.transform.TransformerException;
40+
import javax.xml.transform.TransformerFactory;
41+
import javax.xml.transform.dom.DOMSource;
42+
import javax.xml.transform.stream.StreamResult;
43+
44+
public class FileReaderPreference extends Preference implements Preference.OnPreferenceClickListener, FilePicker.OnFilePickedListener, FilePicker.OnUriPickedListener {
45+
46+
private static final String[] XML_MIME_TYPE = {"text/xml", "application/xml"};
47+
private String xmlContent;
48+
private String filePath;
49+
50+
public FileReaderPreference(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
51+
super(context, attrs, defStyleAttr, defStyleRes);
52+
init(context, attrs);
53+
}
54+
55+
public FileReaderPreference(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
56+
super(context, attrs, defStyleAttr);
57+
init(context, attrs);
58+
}
59+
60+
public FileReaderPreference(@NonNull Context context, @Nullable AttributeSet attrs) {
61+
super(context, attrs);
62+
init(context, attrs);
63+
}
64+
65+
@RequiresApi(api = Build.VERSION_CODES.R)
66+
private void showAlertPermission() {
67+
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getContext());
68+
builder.setTitle(R.string.storage_permission);
69+
builder.setMessage(R.string.permission_storage);
70+
builder.setPositiveButton(R.string.allow, (dialog, which) -> {
71+
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
72+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
73+
intent.setData(Uri.fromParts("package", getContext().getPackageName(), null));
74+
getContext().startActivity(intent);
75+
});
76+
builder.setNegativeButton(R.string.deny, (dialog, which) -> dialog.dismiss());
77+
builder.show();
78+
}
79+
80+
@Override
81+
public boolean onPreferenceClick(@NonNull Preference preference) {
82+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
83+
showAlertPermission();
84+
return true;
85+
}
86+
87+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
88+
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED) {
89+
((Activity) getContext()).requestPermissions(new String[]{Manifest.permission.READ_MEDIA_IMAGES}, 1);
90+
return true;
91+
}
92+
} else if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
93+
((Activity) getContext()).requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
94+
return true;
95+
}
96+
97+
FilePicker.setOnFilePickedListener(this);
98+
FilePicker.setOnUriPickedListener(this);
99+
FilePicker.fileCapture.launch(XML_MIME_TYPE);
100+
return true;
101+
}
102+
103+
@Override
104+
public void onFilePicked(File file) {
105+
if (!file.canRead()) {
106+
Toast.makeText(this.getContext(), R.string.unable_to_read_this_file, Toast.LENGTH_SHORT).show();
107+
return;
108+
}
109+
110+
processXmlFile(file);
111+
}
112+
113+
@Override
114+
public void onUriPicked(Uri uri) {
115+
try {
116+
String realPath = RealPathUtil.getRealFilePath(getContext(), uri);
117+
if (realPath != null) {
118+
File file = new File(realPath);
119+
processXmlFile(file);
120+
} else {
121+
InputStream inputStream = getContext().getContentResolver().openInputStream(uri);
122+
if (inputStream != null) {
123+
processXmlStream(inputStream, uri.getLastPathSegment());
124+
}
125+
}
126+
} catch (Exception e) {
127+
Toast.makeText(getContext(), "Error processing XML file: " + e.getMessage(), Toast.LENGTH_SHORT).show();
128+
}
129+
}
130+
131+
private void processXmlFile(File file) {
132+
try (FileInputStream fis = new FileInputStream(file)) {
133+
processXmlStream(fis, file.getAbsolutePath());
134+
} catch (Exception e) {
135+
Toast.makeText(getContext(), "Error reading XML file: " + e.getMessage(), Toast.LENGTH_SHORT).show();
136+
}
137+
}
138+
139+
private void processXmlStream(InputStream inputStream, String filePath) throws ParserConfigurationException, IOException, SAXException, TransformerException {
140+
// Parse XML document
141+
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
142+
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
143+
Document doc = dBuilder.parse(inputStream);
144+
doc.getDocumentElement().normalize();
145+
146+
// Convert document to string
147+
TransformerFactory transformerFactory = TransformerFactory.newInstance();
148+
Transformer transformer = transformerFactory.newTransformer();
149+
DOMSource source = new DOMSource(doc);
150+
StringWriter writer = new StringWriter();
151+
StreamResult result = new StreamResult(writer);
152+
transformer.transform(source, result);
153+
154+
this.xmlContent = writer.toString();
155+
this.filePath = filePath;
156+
157+
// Save the XML content in the preference
158+
getSharedPreferences().edit()
159+
.putString(getKey(), xmlContent)
160+
.apply();
161+
162+
// Display file path in summary
163+
setSummary(filePath);
164+
Toast.makeText(getContext(), "XML file loaded successfully", Toast.LENGTH_SHORT).show();
165+
}
166+
167+
private void init(Context context, AttributeSet attrs) {
168+
setOnPreferenceClickListener(this);
169+
170+
// Get saved values if they exist
171+
String savedXml = PreferenceManager.getDefaultSharedPreferences(context).getString(this.getKey(), null);
172+
if (savedXml != null) {
173+
this.xmlContent = savedXml;
174+
setSummary(this.filePath != null ? this.filePath : "XML content loaded");
175+
}
176+
}
177+
}

0 commit comments

Comments
 (0)