AndroidLocator.java 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. package com.jme3.asset.plugins;
  2. import android.content.res.AssetFileDescriptor;
  3. import android.content.res.Resources;
  4. import com.jme3.asset.*;
  5. import com.jme3.system.android.JmeAndroidSystem;
  6. import java.io.IOException;
  7. import java.io.InputStream;
  8. import java.util.logging.Logger;
  9. public class AndroidLocator implements AssetLocator {
  10. private static final Logger logger = Logger.getLogger(AndroidLocator.class.getName());
  11. private String rootPath = "";
  12. public AndroidLocator() {
  13. }
  14. @Override
  15. public void setRootPath(String rootPath) {
  16. this.rootPath = rootPath;
  17. }
  18. @Override
  19. public AssetInfo locate(AssetManager manager, AssetKey key) {
  20. String assetPath = rootPath + key.getName();
  21. // Fix path issues
  22. if (assetPath.startsWith("/")) {
  23. // Remove leading /
  24. assetPath = assetPath.substring(1);
  25. }
  26. assetPath = assetPath.replace("//", "/");
  27. // Not making this a property and storing for future use in case the view stored in JmeAndroidSystem
  28. // is replaced due to device orientation change. Not sure it is necessary to do this yet, but am for now.
  29. android.content.res.Resources androidResources = JmeAndroidSystem.getView().getContext().getResources();
  30. String androidPackageName = JmeAndroidSystem.getView().getContext().getPackageName();
  31. // logger.log(Level.INFO, "Asset Key: {0}", key);
  32. // logger.log(Level.INFO, "Asset Name: {0}", key.getName());
  33. // logger.log(Level.INFO, "Asset Path: {0}", assetPath);
  34. // logger.log(Level.INFO, "Asset Extension: {0}", key.getExtension());
  35. // logger.log(Level.INFO, "Asset Key Class: {0}", key.getClass().getName());
  36. // logger.log(Level.INFO, "androidPackageName: {0}", androidPackageName);
  37. // logger.log(Level.INFO, "Resource Name: {0}", getResourceName(assetPath));
  38. // check the assets directory for the asset using assetPath
  39. try {
  40. InputStream in = androidResources.getAssets().open(assetPath);
  41. if (in != null){
  42. return new AndroidAssetInfo(manager, key, assetPath, in, 0);
  43. }
  44. } catch (IOException ex) {
  45. // allow to fall through to the other checks in the resources directories.
  46. // logger.log(Level.INFO, "Resource[{0}] not found in assets directory.", assetPath);
  47. }
  48. // if not found in the assets directory, check the drawable and mipmap directories (only valid for images)
  49. String resourceName = getResourceName(assetPath);
  50. int resourceId = androidResources.getIdentifier(resourceName, "drawable", androidPackageName);
  51. // logger.log(Level.INFO, "drawable resourceId: {0}", resourceId);
  52. if (resourceId == 0) { // drawable resource not found, check mipmap resource type
  53. resourceId = androidResources.getIdentifier(resourceName, "mipmap", androidPackageName);
  54. // logger.log(Level.INFO, "mipmap resourceId: {0}", resourceId);
  55. }
  56. if (resourceId == 0) { // not found in resource directories, return null;
  57. return null;
  58. }
  59. // try to open a stream with the resourceId returned by Android
  60. try {
  61. InputStream in = androidResources.openRawResource(resourceId);
  62. if (in != null){
  63. // logger.log(Level.INFO, "Creating new AndroidResourceInfo.");
  64. return new AndroidAssetInfo(manager, key, assetPath, in, resourceId);
  65. }
  66. } catch (Resources.NotFoundException ex) {
  67. // input stream failed to open, return null
  68. return null;
  69. }
  70. return null;
  71. }
  72. public class AndroidAssetInfo extends AssetInfo {
  73. private InputStream in;
  74. private final String assetPath;
  75. private int resourceId;
  76. AndroidAssetInfo(AssetManager assetManager, AssetKey<?> key, String assetPath, InputStream in, int resourceId) {
  77. super(assetManager, key);
  78. this.assetPath = assetPath;
  79. this.in = in;
  80. this.resourceId = resourceId;
  81. }
  82. @Override
  83. public InputStream openStream() {
  84. if (in != null){
  85. // Reuse the already existing stream (only once)
  86. InputStream in2 = in;
  87. in = null;
  88. return in2;
  89. }else{
  90. // Create a new stream for subsequent invocations.
  91. android.content.res.Resources androidResources = JmeAndroidSystem.getView().getContext().getResources();
  92. if (resourceId == 0) {
  93. try {
  94. return androidResources.getAssets().open(assetPath);
  95. } catch (IOException ex) {
  96. throw new AssetLoadException("Failed to open asset " + assetPath, ex);
  97. }
  98. } else {
  99. try {
  100. return androidResources.openRawResource(resourceId);
  101. } catch (Resources.NotFoundException ex) {
  102. throw new AssetLoadException("Failed to open asset " + assetPath, ex);
  103. }
  104. }
  105. }
  106. }
  107. public AssetFileDescriptor openFileDescriptor() {
  108. android.content.res.Resources androidResources = JmeAndroidSystem.getView().getContext().getResources();
  109. if (resourceId == 0) {
  110. try {
  111. return androidResources.getAssets().openFd(assetPath);
  112. } catch (IOException ex) {
  113. throw new AssetLoadException("Failed to open asset " + assetPath, ex);
  114. }
  115. } else {
  116. try {
  117. return androidResources.openRawResourceFd(resourceId);
  118. } catch (Resources.NotFoundException ex) {
  119. throw new AssetLoadException("Failed to open asset " + assetPath, ex);
  120. }
  121. }
  122. }
  123. }
  124. private String getResourceName(String name) {
  125. int idx = name.lastIndexOf('.');
  126. if (idx <= 0 || idx == name.length() - 1) {
  127. return name;
  128. } else {
  129. return name.substring(0, idx).toLowerCase();
  130. }
  131. }
  132. }