Merge pull request #1324 from reicast/lk/abandoned

Android: Reimplement TheGamesDB w/ legacy API
This commit is contained in:
Abandoned Cart 2018-08-25 02:19:03 -04:00 committed by GitHub
commit c926f264c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 459 additions and 22 deletions

View File

@ -364,28 +364,11 @@ public class FileBrowser extends Fragment {
private void createListItem(LinearLayout list, final File game, final int index, final boolean isGame) {
final View childview = getActivity().getLayoutInflater().inflate(
R.layout.browser_fragment_item, null, false);
XMLParser xmlParser = new XMLParser(game, index, mPrefs);
xmlParser.setViewParent(getActivity(), childview, mCallback);
orig_bg = childview.getBackground();
((TextView) childview.findViewById(R.id.item_name)).setText(game.getName());
String nameLower = game.getName().toLowerCase(Locale.getDefault());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
((ImageView) childview.findViewById(R.id.item_icon)).setImageDrawable(
getResources().getDrawable(game.isDirectory() ? R.drawable.open_folder
: nameLower.endsWith(".gdi") ? R.mipmap.disk_gdi
: nameLower.endsWith(".chd") ? R.mipmap.disk_chd
: nameLower.endsWith(".cdi") ? R.mipmap.disk_cdi
: R.mipmap.disk_unknown));
} else {
((ImageView) childview.findViewById(R.id.item_icon)).setImageDrawable(
getResources().getDrawable(game.isDirectory() ? R.drawable.open_folder
: nameLower.endsWith(".gdi") ? R.drawable.gdi
: nameLower.endsWith(".chd") ? R.drawable.chd
: nameLower.endsWith(".cdi") ? R.drawable.cdi
: R.drawable.disk_unknown));
}
childview.findViewById(R.id.childview).setOnClickListener(
new OnClickListener() {
public void onClick(View view) {
@ -424,6 +407,7 @@ public class FileBrowser extends Fragment {
}
});
list.addView(childview);
xmlParser.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, game.getName());
}
private static class navigate extends AsyncTask<File, Integer, List<File>> {

View File

@ -0,0 +1,360 @@
package com.reicast.emulator;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PorterDuff;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Vibrator;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.widget.ImageView;
import android.widget.TextView;
import com.reicast.emulator.FileBrowser.OnItemSelectedListener;
import com.reicast.emulator.config.Config;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Locale;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
public class XMLParser extends AsyncTask<String, Integer, String> {
private SharedPreferences mPrefs;
private File game;
private int index;
private View childview;
private OnItemSelectedListener mCallback;
private Context mContext;
private String game_name;
private Drawable game_icon;
private String gameId;
private String game_details;
private String game_index = "http://legacy.thegamesdb.net/api/GetGamesList.php?platform=sega+dreamcast&name=";
private String game_id = "http://legacy.thegamesdb.net/api/GetGame.php?platform=sega+dreamcast&id=";
public XMLParser(File game, int index, SharedPreferences mPrefs) {
this.mPrefs = mPrefs;
this.game = game;
this.index = index;
}
public void setViewParent(Context mContext, View childview, OnItemSelectedListener mCallback) {
this.mContext = mContext;
this.childview = childview;
this.mCallback = mCallback;
initializeDefaults();
}
public void setGameID(String id) {
this.gameId = id;
}
@Override
protected String doInBackground(String... params) {
String filename = game_name = params[0];
if (isNetworkAvailable() && mPrefs.getBoolean(Config.pref_gamedetails, false)) {
String xmlUrl = "";
if (gameId != null) {
xmlUrl = game_id + gameId;
} else {
filename = filename.substring(0, filename.lastIndexOf("."));
try {
filename = URLEncoder.encode(filename, "UTF-8");
} catch (UnsupportedEncodingException e) {
filename = filename.replace(" ", "+");
}
xmlUrl = game_index + filename;
}
try {
HttpURLConnection conn = (HttpURLConnection) new URL(xmlUrl).openConnection();
conn.setRequestMethod("POST");
conn.setDoInput(true);
InputStream in = conn.getInputStream();
BufferedReader streamReader = new BufferedReader(
new InputStreamReader(in, "UTF-8"));
StringBuilder responseStrBuilder = new StringBuilder();
String inputStr;
while ((inputStr = streamReader.readLine()) != null)
responseStrBuilder.append(inputStr);
in.close();
return responseStrBuilder.toString();
} catch (UnsupportedEncodingException e) {
} catch (IOException e) {
}
}
return null;
}
@Override
protected void onPostExecute(String gameData) {
if (gameData != null) {
try {
Document doc = getDomElement(gameData);
if (doc.getElementsByTagName("Game") != null) {
Element root = (Element) doc.getElementsByTagName("Game").item(0);
if (gameId == null) {
XMLParser xmlParser = new XMLParser(game, index, mPrefs);
xmlParser.setViewParent(mContext, childview, mCallback);
xmlParser.setGameID(getValue(root, "id"));
xmlParser.execute(game_name);
} else {
game_name = getValue(root, "GameTitle");
game_details = getValue(root, "Overview");
Element images = (Element) root.getElementsByTagName("Images").item(0);
Element boxart = null;
if (images.getElementsByTagName("boxart").getLength() > 1) {
boxart = (Element) images.getElementsByTagName("boxart").item(1);
} else if (images.getElementsByTagName("boxart").getLength() == 1) {
boxart = (Element) images.getElementsByTagName("boxart").item(0);
}
if (boxart != null) {
(new decodeBitmapIcon()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
"https://cdn.thegamesdb.net/images/thumb/" + getElementValue(
boxart).replace("original/", ""));
}
}
}
} catch (Exception e) {
}
}
((TextView) childview.findViewById(R.id.item_name)).setText(game_name);
if (mPrefs.getBoolean(Config.pref_gamedetails, false)) {
childview.findViewById(R.id.childview).setOnLongClickListener(
new OnLongClickListener() {
public boolean onLongClick(View view) {
final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setCancelable(true);
builder.setTitle(mContext.getString(R.string.game_details, game_name));
builder.setMessage(game_details);
builder.setIcon(game_icon);
builder.setNegativeButton("Close",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
return;
}
});
builder.setPositiveButton("Launch",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
mCallback.onGameSelected(game != null ? Uri.fromFile(game) : Uri.EMPTY);
((Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE)).vibrate(250);
return;
}
});
builder.create().show();
return true;
}
});
}
childview.setTag(game_name);
}
private void initializeDefaults() {
game_details = mContext.getString(R.string.info_unavailable);
final String nameLower = game.getName().toLowerCase(Locale.getDefault());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
game_icon = mContext.getResources().getDrawable(
game.isDirectory() ? R.drawable.open_folder
: nameLower.endsWith(".gdi") ? R.mipmap.disk_gdi
: nameLower.endsWith(".chd") ? R.mipmap.disk_chd
: nameLower.endsWith(".cdi") ? R.mipmap.disk_cdi
: R.mipmap.disk_unknown);
} else {
game_icon = mContext.getResources().getDrawable(
game.isDirectory() ? R.drawable.open_folder
: nameLower.endsWith(".gdi") ? R.drawable.gdi
: nameLower.endsWith(".chd") ? R.drawable.chd
: nameLower.endsWith(".cdi") ? R.drawable.cdi
: R.drawable.disk_unknown);
}
((ImageView) childview.findViewById(R.id.item_icon)).setImageDrawable(game_icon);
}
public boolean isNetworkAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager) mContext
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
NetworkInfo mMobile = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
if (mMobile != null && mWifi != null) {
return mMobile.isAvailable() || mWifi.isAvailable();
} else {
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
}
public Drawable getGameIcon() {
return game_icon;
}
public String getGameTitle() {
return game_name;
}
public String getGameDetails() {
return game_details;
}
public Document getDomElement(String xml) {
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(is);
} catch (ParserConfigurationException e) {
return null;
} catch (SAXException e) {
return null;
} catch (IOException e) {
return null;
}
return doc;
}
public String getValue(Element item, String str) {
NodeList n = item.getElementsByTagName(str);
return this.getElementValue(n.item(0));
}
public final String getElementValue(Node elem) {
Node child;
if (elem != null) {
if (elem.hasChildNodes()) {
for (child = elem.getFirstChild(); child != null; child = child
.getNextSibling()) {
if (child.getNodeType() == Node.TEXT_NODE) {
return child.getNodeValue();
}
}
}
}
return "";
}
private class decodeBitmapIcon extends AsyncTask<String, Integer, Bitmap> {
@Override
protected Bitmap doInBackground(String... params) {
try {
String index = params[0].substring(params[0].lastIndexOf("/") + 1, params[0].lastIndexOf("."));
File file = new File(mContext.getExternalFilesDir(null) + "/images", index + ".png");
if (file.exists()) {
return BitmapFactory.decodeFile(file.getAbsolutePath());
} else {
URL updateURL = new URL(params[0]);
URLConnection conn1 = updateURL.openConnection();
InputStream im = conn1.getInputStream();
BufferedInputStream bis = new BufferedInputStream(im, 512);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(bis, null, options);
int heightRatio = (int) Math.ceil(options.outHeight / (float) 72);
int widthRatio = (int) Math.ceil(options.outWidth / (float) 72);
if (heightRatio > 1 || widthRatio > 1) {
if (heightRatio > widthRatio) {
options.inSampleSize = heightRatio;
} else {
options.inSampleSize = widthRatio;
}
}
options.inJustDecodeBounds = false;
bis.close();
im.close();
conn1 = updateURL.openConnection();
im = conn1.getInputStream();
bis = new BufferedInputStream(im, 512);
Bitmap bitmap = BitmapFactory.decodeStream(bis, null, options);
bis.close();
im.close();
bis = null;
im = null;
OutputStream fOut = null;
if (!file.getParentFile().exists()) {
file.getParentFile().mkdir();
}
try {
fOut = new FileOutputStream(file, false);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
} catch (Exception ex) {
ex.printStackTrace();
}
return bitmap;
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Bitmap gameImage) {
if (gameImage != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
((ImageView) childview.findViewById(R.id.item_icon)).setImageTintList(null);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
game_icon = new BitmapDrawable(mContext.getResources(), gameImage);
} else {
game_icon = new BitmapDrawable(gameImage);
}
((ImageView) childview.findViewById(R.id.item_icon)).setImageDrawable(game_icon);
}
}
}
}

View File

@ -10,6 +10,8 @@ public class Config {
public static final String pref_games = "game_directory";
public static final String pref_theme = "button_theme";
public static final String pref_gamedetails = "game_details";
public static final String pref_showfps = "show_fps";
public static final String pref_rendertype = "render_type";
public static final String pref_renderdepth = "depth_render";

View File

@ -178,6 +178,25 @@ public class OptionsFragment extends Fragment {
reios_opt.setChecked(mPrefs.getBoolean(Emulator.pref_usereios, false));
reios_opt.setOnCheckedChangeListener(reios_options);
OnCheckedChangeListener details_options = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
mPrefs.edit().putBoolean(Config.pref_gamedetails, isChecked).apply();
if (!isChecked) {
File dir = new File(getActivity().getExternalFilesDir(null), "images");
for (File file : dir.listFiles()) {
if (!file.isDirectory()) {
file.delete();
}
}
}
}
};
CompoundButton details_opt = (CompoundButton) getView().findViewById(R.id.details_option);
details_opt.setChecked(mPrefs.getBoolean(Config.pref_gamedetails, false));
details_opt.setOnCheckedChangeListener(details_options);
Button gameBrowse = (Button) getView().findViewById(R.id.browse_game_path);
final EditText editGames = (EditText) getView().findViewById(R.id.game_path);
@ -694,6 +713,7 @@ public class OptionsFragment extends Fragment {
private void resetEmuSettings() {
mPrefs.edit().remove(Emulator.pref_usereios).apply();
mPrefs.edit().remove(Config.pref_gamedetails).apply();
mPrefs.edit().remove(Emulator.pref_nativeact).apply();
mPrefs.edit().remove(Emulator.pref_dynarecopt).apply();
mPrefs.edit().remove(Emulator.pref_unstable).apply();

View File

@ -145,6 +145,41 @@
</LinearLayout>
</LinearLayout>
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:stretchColumns="*" >
<TableRow
android:layout_marginTop="10dp"
android:gravity="center_vertical" >
<TextView
android:id="@+id/details_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:gravity="center_vertical|left"
android:text="@string/select_details" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<Switch
android:id="@+id/details_option"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true" />
</LinearLayout>
</TableRow>
</TableLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -18,8 +18,8 @@
<ImageView
android:id="@+id/item_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_marginLeft="16dp"
android:layout_gravity="center"
android:tint="@color/ice_light"

View File

@ -145,6 +145,41 @@
</LinearLayout>
</LinearLayout>
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:stretchColumns="*" >
<TableRow
android:layout_marginTop="10dp"
android:gravity="center_vertical" >
<TextView
android:id="@+id/details_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:gravity="center_vertical|left"
android:text="@string/select_details" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<Checkbox
android:id="@+id/details_option"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true" />
</LinearLayout>
</TableRow>
</TableLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -34,6 +34,7 @@
<string name="experimental_opts">Experimental (May cause widespread panic)</string>
<string name="select_reios">Use reios BIOS</string>
<string name="select_bios">BIOS Region (dc_flash[X].bin)</string>
<string name="select_details">Enable Game Details</string>
<string name="select_native">Native Gamepad Mode [No OSD]</string>
<string name="select_dynarec">Dynamic Recompiler</string>
<string name="select_unstable">Unstable Optimisations</string>