I implemented a JSON interface for getting model data over http in one of my android projects.
this works so far and I would like to write some tests. I created a test project as suggested in the android documentation. for testing the JSON interface I need some test data which I would like to put in a file.
my research showed up that it's best to put these files in the assets folder of the android test project. to access files in the assets folder one should extend the test class by InstrumentationTestCase. then it should be possible to access the files by calling getAssets().open() on a resources object. so I came up with the following code:
public class ModelTest extends InstrumentationTestCase {
public void testModel() throws Exception {
String fileName = "models.json";
Resources res = getInstrumentation().getContext().getResources();
InputStream in = res.getAssets().open(fileName);
...
}
}
unfortunately I'm getting an "no such file or directory (2)" error when trying to access "models.json" file. (/assets/models.json)
when getting a list of the available files by
String[] list = res.getAssets().list("");
"models.json" is listed in there.
I'm running these tests on Android 4.2.2 api level 17.
public static String readFileFromAssets(String fileName, Context c) {
try {
InputStream is = c.getAssets().open(fileName);
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
String text = new String(buffer);
return text;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Then use the following code:
JSONObject json = new JSONObject(Util.readFileFromAssets("abc.txt", getApplicationContext()));
please use below code:
AssetManager assetManager = getResources().getAssets();
InputStream inputStream = null;
try {
inputStream = assetManager.open("foo.txt");
if ( inputStream != null)
Log.d(TAG, "It worked!");
} catch (IOException e) {
e.printStackTrace();
}
Related
I have a simple .txt file with just a couple lines in right now, each line has a word then a comma then another word, representing a very simplistic username , password bank. For some reason though I cant get the File to open to read from it.
Here is my code that I'm using....
try {
final String PATH = "src\\main\\assets\\passwords.txt";
Log.w("myApp", "passed");
List<String> user_password = FileUtils.readLines(new File(PATH));
Log.w("myApp", "passed2");
#SuppressWarnings("unchecked") List<Credentials> credentials = (List<Credentials>) CollectionUtils.collect(user_password, new Transformer() {
#Override
public Object transform(Object input) {
String cred = (String) input;
String parsed[] = cred.split(",");
Log.w("myApp", parsed[0]);
return new Credentials(parsed[0], parsed[1]);
//return credential;
}
});
user = (Credentials) CollectionUtils.find(credentials, new Predicate() {
#Override
public boolean evaluate(Object object) {
Credentials c = (Credentials) object;
return c.getUserName().equals(userName);
}
});
} catch (IOException e) {
System.out.print(e);
Log.w("MyApp", "failed");
}
I've tried putting the passwords.txt file in different places but that doesn't seem to work either.
You're referencing wrong to file in assets folder. It has to be smth like:
file:///android_asset/myfoldername/myfilename
in your particular case it's file:///android_asset/passwords.txt, though you have to keep in mind that it's always read only file
final String PATH = "src\\main\\assets\\passwords.txt";
That's not going to work. Android is not Windows, and an Android device is not your Windows development PC.
First, \ is the Windows path separator. On OS X, Linux, and Android, the path separator is /.
Second, src\main\assets\passwords.txt is a file in your project. It is not a file on the filesystem of the Android device.
To access assets, use AssetManager to open an InputStream(). You can get an AssetManager by calling getAssets() on any handy Context, such as your activity. Then, for your asset, call open("passwords.txt") on the AssetManager to get the InputStream, that you can then use to read in the data.
Thanks to #CommonsWare I was able to achieve what I was trying to do by using InputStream and then also IOUtils to read everything into the List.
try {
InputStream iS = this.getAssets().open("passwords.txt");
List<String> user_password = IOUtils.readLines(iS);
#SuppressWarnings("unchecked") List<Credentials> credentials = (List<Credentials>) CollectionUtils.collect(user_password, new Transformer() {
#Override
public Object transform(Object input) {
String cred = (String) input;
String parsed[] = cred.split(",");
return new Credentials(parsed[0], parsed[1]);
}
});
user = (Credentials) CollectionUtils.find(credentials, new Predicate() {
#Override
public boolean evaluate(Object object) {
Credentials c = (Credentials) object;
return c.getUserName().equals(userName);
}
});
}catch (IOException e){
System.out.print(e);
}
JUnitTest/Mockito/PowerMockito :: Trying to access dataSet json file from res/raw file in android, But getting "InvocationTargetException"
InputStream in = this.getClass().getClassLoader().getResourceAsStream("resource.json");
try {
Reader reader = new InputStreamReader(in, "UTF-8");
ConfigModel result = new Gson().fromJson(reader, ConfigModel.class);
} catch (IOException e) {
e.printStackTrace();
}
EDIT: updated version.
If you using Android instrumentation test then you can get the context and you can do something like this,
#Test
public void someTest() {
// Context of the app under test.
// In this case put your resource in your app's assets folder src/main/assets
Context appContext = InstrumentationRegistry.getTargetContext();
/ **
* Context of the test app.
* In this case put your resource in your test app's assets folder src/androidTests/assets
* Context appContext = InstrumentationRegistry.getContext();
**/
InputStream in = null;
try {
in = appContext.getAssets().open("resource.json");
} catch (IOException e) {
e.printStackTrace();
}
}
If you do not want to go into Android way of testing, simple way is to have your resource.json under src/test/resources folder and then your above code would work. Something like this.
#Test
public void test() {
ClassLoader classLoader = this.getClass().getClassLoader();
InputStream res = classLoader.getResourceAsStream("testFlags.json");
}
I did some testing around these and I can say they are working fine. Let me know how it goes.
I am basically trying to read a long list of numbers(doubles)from a text file and save them into an array. I have these lines of code but it doesn't work when I load into my android smartphone. The readfile() does work completely when I use debug mode to check if my code reads the ExamScore, it does read and store the values as expected in my laptop. When it loads into smartphone, it just doesn't work. I save my ExamScore.txt in the root directory of android studio, for example, Users->AndroidStudioProjects->Project A. The main concern I have is that:
How do I know if this ExamScore.txt is saved into my smartphone as well when I build the app? Do I have to save the text file into my smartphone separately or something?The error I get is
java.io.FileNotFoundException: ExamScore.txt: open failed: ENOENT (No such file or directory)
static double[] readfile() throws FileNotFoundException{
Scanner scorefile = new Scanner(new File("ExamScore.txt"));
int count = -1;
double[] score = new double[8641];
while (scorefile.hasNext()) {
count = count + 1;
score[count] = Double.parseDouble(scorefile.nextLine());
}
scorefile.close();
return score;
}
In my main code,
double []score=readfile();
I save my ExamScore.txt in the root directory of android studio, for example, Users->AndroidStudioProjects->Project A... How do I know if this ExamScore.txt is saved into my smartphone as well when I build the app?
It isn't.
You need to create an assets folder.
Refer: Where do I place the 'assets' folder in Android Studio?
And you would use getAssets() to read from that folder.
public class MainActivity extends Activity {
private double[] readfile() throws FileNotFoundException{
InputStream fileStream = getAssets().open("ExamScore.txt");
// TODO: read an InputStream
}
}
Note: that is a read-only location of your app.
Or you can use the internal SD card.
How do I read the file content from the Internal storage - Android App
EDIT With refactored code in other answer
public static List<Double> readScore(Context context, String filename) {
List<Double> scores = new ArrayList<>();
AssetManager mgr = context.getAssets();
try (
BufferedReader reader = new BufferedReader(
new InputStreamReader(mgr.open(fileName)));
) {
String mLine;
while ((mLine = reader.readLine()) != null) {
scores.add(Double.parseDouble(mLine));
}
} catch (NumberFormatException e) {
Log.e("ERROR: readScore", e.getMessage());
}
return scores;
}
And then
List<Double> scores = readScore(MainActivity.this, "score.txt");
For those who are wondering, this is my solution! Thank you all for your help!!!! The issue I had was I didn't write it in the main activity but wrote the code in other java file. After writing this in the main activity file and putting my text file inside the assets folder. The issue is resolved :
public static LinkedList<Double> score=new LinkedList<Double>();
public void readScore() throws java.io.IOException {
BufferedReader reader = new BufferedReader(
new InputStreamReader(getAssets().open("score.txt")));
String mLine;
while ((mLine = reader.readLine()) != null) {
score.add(Double.parseDouble(mLine));
}
reader.close();
}
Here I try to use getClassLoader().getResources() to get my .model file, however it returns null. I'm not sure where goes wrong!
And when I try to print out the urls, it gives me java.lang.TwoEnumerationsInOne#5fd1900, what does this means?
public Activity(MainActivity activity) {
MainActivity activity = new MainActivity();
try {
// Open stream to read trained model from file
InputStream is = null;
// this .model file is save under my /project/app/src/main/res/
Enumeration<URL> urls = Activity.class.getClassLoader().getResources("file.model");
// System.out.println("url:"+urls);
if (urls.hasMoreElements()) {
URL element = urls.nextElement();
is = element.openStream();
}
// deserialize the model
classifier = (J48) SerializationHelper.read(is);
is.close();
} catch (Exception e) {
e.printStackTrace();
}
}
In Android, resources put under src/main/res are not visible in the class path and can only be accessed via the android resources API. Try to put the file into src/main/resources.
I have a simple .txt file with just a couple lines in right now, each line has a word then a comma then another word, representing a very simplistic username , password bank. For some reason though I cant get the File to open to read from it.
Here is my code that I'm using....
try {
final String PATH = "src\\main\\assets\\passwords.txt";
Log.w("myApp", "passed");
List<String> user_password = FileUtils.readLines(new File(PATH));
Log.w("myApp", "passed2");
#SuppressWarnings("unchecked") List<Credentials> credentials = (List<Credentials>) CollectionUtils.collect(user_password, new Transformer() {
#Override
public Object transform(Object input) {
String cred = (String) input;
String parsed[] = cred.split(",");
Log.w("myApp", parsed[0]);
return new Credentials(parsed[0], parsed[1]);
//return credential;
}
});
user = (Credentials) CollectionUtils.find(credentials, new Predicate() {
#Override
public boolean evaluate(Object object) {
Credentials c = (Credentials) object;
return c.getUserName().equals(userName);
}
});
} catch (IOException e) {
System.out.print(e);
Log.w("MyApp", "failed");
}
I've tried putting the passwords.txt file in different places but that doesn't seem to work either.
You're referencing wrong to file in assets folder. It has to be smth like:
file:///android_asset/myfoldername/myfilename
in your particular case it's file:///android_asset/passwords.txt, though you have to keep in mind that it's always read only file
final String PATH = "src\\main\\assets\\passwords.txt";
That's not going to work. Android is not Windows, and an Android device is not your Windows development PC.
First, \ is the Windows path separator. On OS X, Linux, and Android, the path separator is /.
Second, src\main\assets\passwords.txt is a file in your project. It is not a file on the filesystem of the Android device.
To access assets, use AssetManager to open an InputStream(). You can get an AssetManager by calling getAssets() on any handy Context, such as your activity. Then, for your asset, call open("passwords.txt") on the AssetManager to get the InputStream, that you can then use to read in the data.
Thanks to #CommonsWare I was able to achieve what I was trying to do by using InputStream and then also IOUtils to read everything into the List.
try {
InputStream iS = this.getAssets().open("passwords.txt");
List<String> user_password = IOUtils.readLines(iS);
#SuppressWarnings("unchecked") List<Credentials> credentials = (List<Credentials>) CollectionUtils.collect(user_password, new Transformer() {
#Override
public Object transform(Object input) {
String cred = (String) input;
String parsed[] = cred.split(",");
return new Credentials(parsed[0], parsed[1]);
}
});
user = (Credentials) CollectionUtils.find(credentials, new Predicate() {
#Override
public boolean evaluate(Object object) {
Credentials c = (Credentials) object;
return c.getUserName().equals(userName);
}
});
}catch (IOException e){
System.out.print(e);
}