I get
Caused by: android.content.res.Resources$NotFoundException: Resource ID #0x7f060000
when I try to load a bitmap from a resource in my res/drawable folder (even intelliJ auto-complete finds them) like so:
public Sprite(int resource, int numberOfFrames){
BitmapRegionDecoder spriteSheet = null;
try {
InputStream is = Resources.getSystem().openRawResource(+resource);
spriteSheet = BitmapRegionDecoder.newInstance(is, false);
} catch (IOException ioexc){
ioexc.printStackTrace();
}
timer = 0;
this.numberOfFrames = numberOfFrames;
frames = new Bitmap[numberOfFrames];
for (int i = 0; i < numberOfFrames; i++) {
frames[i] = spriteSheet.decodeRegion(new Rect(i*32, 0, (i*32)+32, 32), null);
}
and I pass the resource only 2 times:
public class PlayerSprite extends Sprite {
private boolean isHitting;
private int timer;
public PlayerSprite() {
super(R.drawable.player_sprite_sheet, 3);
timer = 0;
}
//...more core...//
}
and here:
sprite = new Sprite(R.drawable.ball_sprite, 7);
Here you can see my directory
Resources.getSystem() is the problem in your case. It returns a global shared Resources object but not the one of the application. You should use Context.getResource() instead, which returns
a resources instance for the application's package
here you can find the documentation for Context.getResource() and for Resources.getSystem()
Related
I want to make a rolling dice app with short rolling animations consisting of images. I have created 100 JPG images for each of 20 possible results (the dice is d20). The thing is that I cannot know exact filenames of the needed files after the throw, as it is random. So I cannot use setImageResource, as I need exact filename for it.
I decided to try using assets, as I can choose .getString there instead of exact filename (all JPGs are named in format d20+result number+number of animation frame). The app works seemingly fine, but pictures on the screen do not change until all is over, and then only last image of animation appears and in smaller format that it should be.
Could anyone point on my mistake?
Here is the code:
import android.content.res.AssetManager;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import java.io.IOException;
import java.io.InputStream;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public Random random = new Random();
public void Throw(View view) throws InterruptedException {
ImageView dice = findViewById(R.id.imageD20);
dice.setImageResource(R.drawable.d2002030);
int result = random.nextInt(19); // throwing dice...
long startTime = 0;
long delayTime = 0;
String fileNameStr = new String();
for (int i = 0; i<=100; i++) { // animation
fileNameStr = getResources().getString(R.string.fileName, result, i + 1);
InputStream img = null;
AssetManager mngr = this.getAssets();
try {
InputStream ims = getAssets().open(fileNameStr);
Drawable image = Drawable.createFromStream(ims, null);
dice.setImageDrawable(image);
}
catch(IOException ex) {
ex.printStackTrace();
}
startTime = System.currentTimeMillis();
delayTime = startTime+10;
while(System.currentTimeMillis() < delayTime);
}
}
}
And resources (from where I get filename string):
<resources>
<string name="app_name">D20dice</string>
<string name="fileName">""d20%1$02d%2$03d".jpg"</string>
</resources>
I found out how to make it without assets, just with regular resources through getResources().getIdentifier(). With it I can find resource ID with string variable. There is a new code for Throw hereunder:
public void Throw(View view) throws InterruptedException {
ImageView dice = findViewById(R.id.imageD20);
dice.setImageResource(R.drawable.d2002030);
int result = random.nextInt(19); // throwing dice...
long startTime = 0;
long delayTime = 0;
String fileNameStr = new String();
int resID;
for (int i = 0; i<=100; i++) { // animation
fileNameStr = getResources().getString(R.string.fileName, result, i + 1);
resID = getResources().getIdentifier(fileNameStr , "drawable", getPackageName());
dice.setImageResource(resID);
dice.invalidate();
startTime = System.currentTimeMillis();
delayTime = startTime+10;
while(System.currentTimeMillis() < delayTime);
}
}
But still the same, it shows only first and last picture (but last picture at least in the proper size now).
I`ve tried AnimationDrawable: now for the first throw I see the first and the last frame only again, and on the second throw application crashes. Here is this code:
public void Throw(View view) throws InterruptedException {
ImageView dice = findViewById(R.id.imageD20);
dice.setImageResource(R.drawable.d2002030);
int result = random.nextInt(19); // throwing dice...
String fileNameStr = new String();
Drawable frame;
AnimationDrawable diceAnimation = new AnimationDrawable();
diceAnimation.setOneShot(true);
int resID;
for (int i = 0; i<=100; i++) { // animation
fileNameStr = getResources().getString(R.string.fileName, result, i + 1);
resID = getResources().getIdentifier(fileNameStr , "drawable", getPackageName());
frame = getResources().getDrawable(resID);
diceAnimation.addFrame(frame, 200);
}
dice.setBackground(diceAnimation);
diceAnimation.start();
}
The problem probably was in that I initially set the background with setImageResource, and then loaded animation into the background (setBackground (diceAnimation)). But even after the problem had been solved, animation was played after a long delay before the start. it seems, that for AnimationDrawble 100 frames 320x240 is too much. I finally solved the problem by transforming all the animations into GIF and outputting them via the connected android-gif-drawable: https://github.com/koral--/android-gif-drawable
I am able to successfully take the screenshot one of the page of my application JainLibrary using below code. I am using junit and appium.
public String Screenshotpath = "Mention the folder Location";
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File(Screenshotpath+"Any name".jpg"));
Now I want to compare the screenshot with a reference image so that I can move forward with the test case.
A simple solution would be to compare each pixel with the reference screenshoot:
// save the baseline screenshot
driver.get("https://www.google.co.uk/intl/en/about/");
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File("c:\\temp\\screenshot.png"));
// take another screenshot and compare it to the baseline
driver.get("https://www.google.co.uk/intl/en/about/");
byte[] pngBytes = ((TakesScreenshot)driver).getScreenshotAs(OutputType.BYTES);
if (IsPngEquals(new File("c:\\temp\\screenshot.png"), pngBytes)) {
System.out.println("equals");
} else {
System.out.println("not equals");
}
public static boolean IsPngEquals(File pngFile, byte[] pngBytes) throws IOException {
BufferedImage imageA = ImageIO.read(pngFile);
ByteArrayInputStream inStreamB = new ByteArrayInputStream(pngBytes);
BufferedImage imageB = ImageIO.read(inStreamB);
inStreamB.close();
DataBufferByte dataBufferA = (DataBufferByte)imageA.getRaster().getDataBuffer();
DataBufferByte dataBufferB = (DataBufferByte)imageB.getRaster().getDataBuffer();
if (dataBufferA.getNumBanks() != dataBufferB.getNumBanks()) {
return false;
}
for (int bank = 0; bank < dataBufferA.getNumBanks(); bank++) {
if (!Arrays.equals(dataBufferA.getData(bank), dataBufferB.getData(bank))) {
return false;
}
}
return true;
}
Note that you need to save the reference screenshot as a PNG. A JPEG format will alter the pixels.
I am able to successfully take the screenshot one of the page of my application JainLibrary using below code. I am using junit and appium.
public String Screenshotpath = "Mention the folder Location";
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File(Screenshotpath+"Any name".jpg"));
Now I want to compare the screenshot with a reference image so that I can move forward with the test case.
A simple solution would be to compare each pixel with the reference screenshoot:
// save the baseline screenshot
driver.get("https://www.google.co.uk/intl/en/about/");
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File("c:\\temp\\screenshot.png"));
// take another screenshot and compare it to the baseline
driver.get("https://www.google.co.uk/intl/en/about/");
byte[] pngBytes = ((TakesScreenshot)driver).getScreenshotAs(OutputType.BYTES);
if (IsPngEquals(new File("c:\\temp\\screenshot.png"), pngBytes)) {
System.out.println("equals");
} else {
System.out.println("not equals");
}
public static boolean IsPngEquals(File pngFile, byte[] pngBytes) throws IOException {
BufferedImage imageA = ImageIO.read(pngFile);
ByteArrayInputStream inStreamB = new ByteArrayInputStream(pngBytes);
BufferedImage imageB = ImageIO.read(inStreamB);
inStreamB.close();
DataBufferByte dataBufferA = (DataBufferByte)imageA.getRaster().getDataBuffer();
DataBufferByte dataBufferB = (DataBufferByte)imageB.getRaster().getDataBuffer();
if (dataBufferA.getNumBanks() != dataBufferB.getNumBanks()) {
return false;
}
for (int bank = 0; bank < dataBufferA.getNumBanks(); bank++) {
if (!Arrays.equals(dataBufferA.getData(bank), dataBufferB.getData(bank))) {
return false;
}
}
return true;
}
Note that you need to save the reference screenshot as a PNG. A JPEG format will alter the pixels.
Hello I'm having problem reading random files on Eclipse, Android programming...
At assets folders I have a folder called "fytyra" and there are jpg pictures with mumbers like 1.jpg 2.jpg...
I tried to debug the app, list was null always.. ???
//Gets a random number from 0 to 431,.. I think it is !
private int nasiqim (){
int i = 0;
Random nasiqimi = new Random();
i=nasiqimi.nextInt(431);
return i;
}
//This need to fill list with integers and to not repeat the same number...
private void listaEFotove(){
int nse=-1,i=0,numriRandom;
while (nse<0){
numriRandom = nasiqim();
nse = Arrays.binarySearch(numrat, numriRandom);
if (nse <0 ){
numrat[i] = numriRandom;
i++;
}
if (i == 11)break;
}
}
This is to fill imageView with photos...
private void merrFytyrat(){
int fotoNr=0;
String emri;
listaEFotove();
for (int i=0; i<11;i++){
fotoNr=numrat[i];
if (i==0){
try
{
emri = Integer.toString(fotoNr);
// get input stream
InputStream ims = getAssets().open( "fytyra/" + emri +".jpg");
// load image as Drawable
Drawable d = Drawable.createFromStream(ims, null);
// set image to ImageView
i11.setImageDrawable(d);
}
catch(IOException ex)
{
return;
};
}
else if (i==1){ ... Continues until 12...
I got the answer, thank you greenapps, for trying to help mee...
My mistake was on declaration of array... so my new code is this :
int[] numrat = new int[12];
it was like this :
int[] numrat = null;
another mistake was on the getAssets, like greenapps told me
getAssets().open( "/fytyra/" + emri +".jpg");
now thanks to him i changed that code to :
getAssets().open( "fytyra/" + emri +".jpg");
No everything works perfect,.,
This site is the best, Thank you...
I'm currently trying to start a thread which fetches a drawable from its resources and posts it after a set amount of time. Then fetches the next drawable from resources and does the same thing all over.
final ImageView zImageView = (ImageView) findViewById(R.id.zzz_animation_view);
new Thread(new Runnable() {
public void run() {
for(int i = 1; i<=510; i++)
{
final Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.z_animation0001); // how do I increment this recourse to z_animation0002, 0003, ..., 0510 ?
zImageView.postDelayed(new Runnable() {
public void run() {
zImageView.setImageBitmap(bitmap);
}
},200);
}
}
}).start();
Firstly. Is this a proper way of approaching the problem? The drawables are too large for me to use animation-list and as such my goal is to load the images one at a time to ensure that I have enough memory. Secondly how do I solve the problem of iterating over my resources?
You can get resource id by its name using Resources.getIdentifier :
final int current = 5;
final String pattern = "z_animation%04d";
final String name = String.format(pattern, current);
final int id = getResources().getIdentifier(name, "drawable", getPackageName());
final Bitmap bitmap = BitmapFactory.decodeResource(getResources(), id);
Also, here you can find my answer for the same question with code sample that does exactly what you want.
I would put the images in the assets folder and load them from there as described here: https://xjaphx.wordpress.com/2011/10/02/store-and-use-files-in-assets/
In the assets folder you can just add a number to the file name.