Android Basic Coding Try Catch Show Toast not working? - android

I'm building a real simple Android app and a lot is going wrong.
I can't even get a decent Try Catch Everything running. And since the machine I got is hugely underpowered I'm testing directly on my android device but that's not really working.
The application seems to crash after doing a basic action even using a generic try catch. What am I doing wrong here.
Why is the try catch not catching anything?
This is my Main.xml (a textview and another control are snipped out)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ImageButton
android:id="#+id/ib"
android:layout_width="300dip"
android:layout_height="50dip"
android:text="Hello World, MyActivity"
android:scaleType="fitXY"
android:onClick="onButtonClicked"
/>
This is my simple code (and the Image isn't even showing)
public void onButtonClicked(View v) {
try {
String strFilePath = "/mnt/sdcard/somefile.jpg";
if (strFilePath.length() > 0) {
File file = new File(strFilePath);
if (file.exists()) {
ShowToast(strFilePath + "Bestaat");
ImageButton image = (ImageButton) findViewById(R.id.ib);
Bitmap bMap = BitmapFactory.decodeFile(strFilePath);
image.setImageBitmap(bMap);
ShowToast( "Done");
} else {
ShowToast(strFilePath + "Bestaat NIET");
}
} else {
ShowToast(strFilePath + "strFilePath.length() =0");
}
} catch (Exception e) {
HandleError(e);
}
}
Solution
The files where over 3Mb in size. The ImageButton won't show pictures that 'big' and simply do nothing.
The application probably threw some random out of memory exceptions loading the images taking down the entire app.
Reading a logcat was enough to debug this 'problem'
Some code that does work (kindly borrowed from other SO questions)
ImageButton image = (ImageButton) findViewById(R.id.ib);
Bitmap bMap = BitmapFactory.decodeFile(strFilePath);
Bitmap bSized = getResizedBitmap(bMap,150,150);
image.setImageBitmap(bSized);
And
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth)
{
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}

Either you don't have an ImageButton with that id, or the image you are trying to load is to big to fit in the reduced application memory.

I have tested your code snippets..
First of all, the ImageButton will not show the android:text part because that attribute belongs to Button..
With just the LinearLayout and the ImageButton in main.xml in the res/layout folder and this code it works fine:
public class Main extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void onButtonClicked(View v) {
try {
String strFilePath = "/mnt/sdcard/somefile.png";
if (strFilePath.length() > 0) {
File file = new File(strFilePath);
if (file.exists()) {
//ShowToast(strFilePath + "Bestaat");
ImageButton image = (ImageButton) findViewById(R.id.ib);
Bitmap bMap = BitmapFactory.decodeFile(strFilePath);
image.setImageBitmap(bMap);
//ShowToast( "Done");
} else {
//ShowToast(strFilePath + "Bestaat NIET");
}
} else {
//ShowToast(strFilePath + "strFilePath.length() =0");
}
} catch (Exception e) {
//HandleError(e);
e.printStackTrace();
}
}
}
So either the file is to big as K-Ballo suggested or something is wrong with your ShowToast or HandleError methods.

Related

Out of Memory Error in middle of the app, using BitmapFactory option

Application is working till showing image kite then its stopped by giving error OutOfMemory.
How to resolve this problem in simple way.
I have 25 images not too large, decoding them through BitmapFactory showing in imageview, want to clear memory of imageview every time before showing the new image on button onClick().
how to do this? how i can use recycle option or array adapter in my app....please anyone help me out of this problem.
MyActivity.java
picasso coding
Picasso.with(image.getContext())
.load(imageIds[currentIndex])
.transform(new BitmapTransform(MAX_WIDTH, MAX_HEIGHT))
.skipMemoryCache()
.resize(size, size)
.centerInside()
.into(image);
public class BitmapTransform implements Transformation {
int maxWidth;
int maxHeight;
public BitmapTransform(int maxWidth, int maxHeight) {
this.maxWidth = maxWidth;
this.maxHeight = maxHeight;
}
#Override
public Bitmap transform(Bitmap source) {
int targetWidth, targetHeight;
double aspectRatio;
if (source.getWidth() > source.getHeight()) {
targetWidth = maxWidth;
aspectRatio = (double) source.getHeight() / (double) source.getWidth();
targetHeight = (int) (targetWidth * aspectRatio);
} else {
targetHeight = maxHeight;
aspectRatio = (double) source.getWidth() / (double) source.getHeight();
targetWidth = (int) (targetHeight * aspectRatio);
}
Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
if (result != source) {
source.recycle();
}
return result;
}
#Override
public String key() {
return maxWidth + "x" + maxHeight;
}
};
#Override
public void onDestroy(){
super.onDestroy();
if (mp!=null)
mp.release();
finish();
}
}
When it comes to showing images dynamically I am using Picasso library. It handles in single line of code loading scaled images, caching, loading errors etc.
Picasso.with(context).load(R.drawable.landing_screen).fit().centerInside().into(imageView1);
You can also read Google Developers chapter about Displaying Bitmaps Efficiently if you really need to do it yourself.
Definitely, you should move decoding bitmap to the background thread. You can use for that AsyncTask.
Often, working with even a few images and BitmapFactory you will run into OOME problems like this. You can try to do extensive memory management (like recycling bitmaps) and you should. You will run out of memory or have performance problems.
But even with proper memory management, you will get OOME problems without enabling additional heap memory size:
How to increase heap size of an android application?
try
{
if (currentBitmap != null)
{
currentBitmap = null;
}
System.gc();
} catch (RuntimeException e) {
} catch (Exception e) {
}
Bitmap currentBitmap = BitmapFactory.decodeResource(getResources(),R.id.someimage,options);
Jut Null bitmap before use it.
Does this work?
Create class variable Bitmap currentBitmap
At the end of the onClick() function set currentBitmap to equal scaledBitmap
At the beginning of the onClick() function add this code:
if(currentBitmap != null)
currentBitmap.recycle();
I have no time to test this right now, so let me know if it works!

Android : Issue with memory for large Bitmap objects

Lots been said, written, vented out ;) on this already, I know. But my question is a bit different. I realize that there is issue with using large bitmap objects in Android. In my Android App, I need to use large bitmaps in various places. cannot help it. I tried various things listed in stackoverflow. One that I want to try but not able to is to avoid using ARBG_8888. The App crashes exactly at that line many times. I have an ImageView where I load an initial large bitmap. Then the user can make some markings in the bitmap and then I need to save the whole image (i.e. the original bitmap + the user's markings). Am trying this with this code I got from stackoverflow:
public static Bitmap loadBitmapFromView(Context context, View view) {
Log.d(logtag, "loadBitmapFromView");
Bitmap bitmap;
BitmapFactory.Options options = new BitmapFactory.Options();
// These help in saving/recycling the bitmap memory
options.inPurgeable = true;
options.inInputShareable = true;
Bitmap dummy = null;
try {
dummy = BitmapFactory.decodeStream(context.getAssets().open("icon_add.png"), new Rect(-1,-1,-1,-1), options);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bitmap = Bitmap.createBitmap(view.getLayoutParams().width,
view.getLayoutParams().height, Bitmap.Config.ARGB_8888);
// bitmap = Bitmap.createScaledBitmap( dummy, view.getLayoutParams().width,
// view.getLayoutParams().height, false);
Canvas c = new Canvas(bitmap);
view.layout(0, 0, view.getLayoutParams().width, view.getLayoutParams().height);
view.draw(c);
Log.d(logtag, "loadBitmapFromView: width:" + view.getLayoutParams().width);
c = null;
return bitmap;
}
How do I avoid using ARGB_8888 in the above code? Can someone please help?
I removed it from many other places in the code, but, in the above snippet, am left in vain.
I tried using an initial dummy object (you can see the object 'dummy' in the above code) to create a scaled bitmap object ( with createScaledBitmap() which necessarily asks for a source bitmap ) and then tried to load the canvas, but the generated image is having only the dummy object (icon_add.png) and not the one from the imageview.
you can show image in device specific height width....then you don't get out of memory for imagesize.
this is code:
#SuppressLint("NewApi")
public static int getDeviceWidth(Activity activity) {
int deviceWidth = 0;
Point size = new Point();
WindowManager windowManager = activity.getWindowManager();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
windowManager.getDefaultDisplay().getSize(size);
deviceWidth = size.x;
} else {
Display display = windowManager.getDefaultDisplay();
deviceWidth = display.getWidth();
}
return deviceWidth;
}
#SuppressLint("NewApi")
public static int getDeviceHeight(Activity activity) {
int deviceHeight = 0;
Point size = new Point();
WindowManager windowManager = activity.getWindowManager();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
windowManager.getDefaultDisplay().getSize(size);
deviceHeight = size.y;
} else {
Display display = windowManager.getDefaultDisplay();
deviceHeight = display.getHeight();
}
return deviceHeight;
}
you can use device height and width..and set this image in imageview..
ImageView image = new ImageView(viewHomeScreen);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.FILL_PARENT,
FrameLayout.LayoutParams.FILL_PARENT);
params.height = getDeviceHeight(activity);
params.width = getDevicewidth(activity);
FrameLayout framelayout = new FrameLayout(viewHomeScreen);
framelayout.addView(image, 0, params);
i hope if you use device specific height and width then your image memory issue will be solved.

Android: How can I overlay this level on the background?

I am trying to draw a level on top of a background, but I am unsure how to do it. I am able to draw each of the pieces separately, but am completely lost on how to draw both on the screen. I believe I may have to draw the background with a different method, but I don't know of such a method.
Here is my code thus far:
public class DisplayMap extends Activity {
ImageView mapView;
String FILENAME = "World.tmx";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
setContentView(new TileBackground(this));
}
public void loadWorld(String path) {
ImageView mapView;
// Start the parser, get back TMX data object
TileMapData t = TMXLoader.readTMX(FILENAME, this);
mapView = (ImageView) findViewById(R.id.MapImage);
// Create a Bitmap from the tilemap data
Bitmap mapImage = TMXLoader.createBitmap(t, this, 0, t.layers.size());
// Set the imageview to show the map, if we have one
if (mapImage != null) {
mapView.setImageBitmap(mapImage);
}
// Map loading problem, inform the user.
else {
Toast errorMessage = Toast.makeText(getApplicationContext(),
"Map could not be loaded", Toast.LENGTH_LONG);
errorMessage.show();
}
}
class TileBackground extends View {
Bitmap bg;
public TileBackground(Context context) {
super(context);
try {
AssetManager assetManager = context.getAssets();
InputStream inputStream;
inputStream = assetManager.open("Background.png");
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_4444;
bg = BitmapFactory.decodeStream(inputStream, null, options);
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onDraw(Canvas canvas) {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
int iWidth = bg.getWidth();
int iHeight = bg.getHeight();
for (int x = 0; x < width; x += iWidth) {
for (int y = 0; y < height; y += iHeight)
canvas.drawBitmap(bg, x, y, null);
}
loadWorld(FILENAME);
invalidate();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<com.seanheiss.shovelshovel.DisplayMap.TileBackground
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/TileBackground" />
<ImageView
android:id="#+id/MapImage"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
By commenting one setContentView and not the other I can draw one piece, but I can't figure out how to draw both. I've heard of something called ViewFlipper, but am unsure if I should use that or not; I don't know how it works.
Thank you very much to anyone that can help me!
You should add your custom view (TileBackground) to your activity_main.xml layout file. That should allow it to be drawn properly when you use setContentView on activity_main. You'll probably want it as the first element under a RelativeLayout parent so that it gets drawn in the background.
In your case, you should have as your first element of the RelativeLayout:
<com.YOUR_PACKAGE.TileBackground
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/TileBackground" />

Listview scroll is really slow after loading images in the listview

Let me explain what I am doing first before I get into everything
basically I give the user an option to choose an image from the SD card, store the Uri of selected image in my database and have that as the avatar for the list item but the more list items with an avatar there are the slower the scrolling of the list is
I load the list with a Loader
#Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
return new CursorLoader(getActivity(),BowlersDB.CONTENT_URI,
new String[] {BowlersDB.ID,BowlersDB.FIRST_NAME,BowlersDB.LAST_NAME,BowlersDB.PHOTO_URI},null,null,BowlersDB.LAST_NAME + " COLLATE LOCALIZED ASC");
}
I have a custom adapter that adjusts the image size sets the textviews etc.
#Override
public void bindView(final View view,final Context context,final Cursor cursor){
final int id = cursor.getInt(0);;
final QuickContactBadge image = (QuickContactBadge)view.findViewById(R.id.quickContactBadge1);
image.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
if(!fromGame){
bowlerID = id;
Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i,1);
}
}
});
String uri = cursor.getString(3);
if(uri != null){
InputStream input=null;
try {
input = getActivity().getContentResolver().openInputStream(Uri.parse(cursor.getString(3)));
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
Bitmap og = BitmapFactory.decodeStream(input,null,options);
int height = options.outHeight;
int width = options.outWidth;
BitmapFactory.decodeResource(getResources(), R.drawable.ic_contact_picture, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
float scaledHeight = ((float)imageHeight)/height;
float scaledWidth = ((float)imageWidth)/width;
Matrix matrix = new Matrix();
matrix.postScale(scaledWidth, scaledHeight);
final Bitmap resized = Bitmap.createBitmap(og, 0, 0, width, height, matrix, true);
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
image.setImageBitmap(resized);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}else{
image.setImageResource(R.drawable.ic_contact_picture);
}
TextView first = (TextView)view.findViewById(R.id.bListTextView);
TextView last = (TextView)view.findViewById(R.id.bListTextView2);
first.setText(cursor.getString(1));
last.setText(cursor.getString(2));
}
}
Now I know its probably the sizing of the image that is causing it to be so slow but when I put that section of code in a separate thread and that had no effect but I thought a LoaderManager loads everything in the background anyway
here is my row xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="60dp"
android:id="#+id/names_layout"
android:background="#drawable/list_item_state">
<QuickContactBadge
android:id="#+id/quickContactBadge1"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:src="#drawable/ic_contact_picture"
style="?android:attr/quickContactBadgeStyleWindowLarge" />
<TextView
android:id="#+id/bListTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/quickContactBadge1"
android:background="#drawable/list_item_state"
android:paddingLeft="20dp"
android:paddingTop="2dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="20dp"
android:textColor="?android:attr/textColorPrimary" />
<TextView
android:id="#+id/bListTextView2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/quickContactBadge1"
android:layout_below="#+id/bListTextView"
android:paddingLeft="20dp"
android:background="#drawable/list_item_state"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="15dp"
android:textColor="?android:attr/textColorSecondary"
android:layout_alignBottom="#+id/quickContactBadge1"/>
</RelativeLayout>
the Quick Contact Badge holds the image and I have a default image set for if there is no image set.
So how can I fix this?
An example of what I am trying to do would be the google music app where the album list has all those album avatars and there is no problem scrolling, they appear on a as needed basis it seems but obviously its a bit different since the images are probably downloaded from the server
You can lazyLoad the images for the list view. here is a complete example:
http://codehenge.net/blog/2011/06/android-development-tutorial-asynchronous-lazy-loading-and-caching-of-listview-images/
You are streaming the image in the bindView thread, which generally is not a good idea. I usually do downloading and building bitmaps in an asyncTask - or rather, in a RoboAsyncTask. I pass the ImageView along with the image URL, so the image is set after the downloading or bitmapcreation is done, in the onSuccess() of the asynctask. What you see on the screen is images appearing shortly after the other content. You can also pass a placeholder resource to the async task, to display while the downloading is being done.
In your activity or fragment:
mediaManager.setImage(imageUrl, imageView, R.drawable.placeholder_image);
in MediaManager:
#Override
public void setImage(String imageUrl, ImageView imageView, int placeholderResource) {
new SetImageTask(context, imageUrl, imageView, placeholderResource).execute();
}
#Override
public Bitmap getImage(String imageUrl) throws IllegalStateException, IOException, SQLException {
// put your code to fetch image here....
}
In SetImageTask (extends RoboAsyncTask):
#Override
public void onPreExecute() {
imageView.setImageResource(placeholderResource);
}
#Override
public Bitmap call() throws Exception {
return mediaManager.getImage(imageUrl);
}
#Override
public void onSuccess(Bitmap bitmap) {
imageView.setImageBitmap(bitmap);
}

Android : Scrolling and No scrolling wallpaper issue

I'm little confused about setting up wallpaper,
In my galaxy s if i set wallapaper through code then it's not scrolling by default but If galary sets the wallpaper then its scrolling
Avoid a wallpaper to stretch across 5 screens
It depends on Home luncher app but how can i manage scrolling enabled disabled in my code
// the content of our screen.
setContentView(R.layout.wallpaper_2);
final WallpaperManager wallpaperManager = WallpaperManager
.getInstance(this);
final Drawable wallpaperDrawable = wallpaperManager.getDrawable();
final ImageView imageView = (ImageView) findViewById(R.id.imageview);
imageView.setDrawingCacheEnabled(true);
imageView.setImageDrawable(wallpaperDrawable);
Button randomize = (Button) findViewById(R.id.randomize);
randomize.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
int mColor = (int) Math.floor(Math.random() * mColors.length);
wallpaperDrawable.setColorFilter(mColors[mColor],
PorterDuff.Mode.MULTIPLY);
imageView.setImageDrawable(wallpaperDrawable);
imageView.invalidate();
}
});
Button setWallpaper = (Button) findViewById(R.id.setwallpaper);
setWallpaper.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
try {
wallpaperManager.setBitmap(imageView.getDrawingCache());
finish();
} catch (IOException e) {
e.printStackTrace();
}
}
});
wallpaperwizardrii application support scrolling and not scrolling features, It means it is possible at place but after investing so much time i failed to get solution.
I tried to set wallpaperManager.setWallpaperOffsetSteps(xStep, yStep); but can not get result of it
Am I missing any api which i am not aware
Help me Thanks in advance...
EDIT:I am setting one wallpaper in my phone from below code its result is ok because im having ICS in my phone but in emulator its stretched.
WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.dashboard);
Bitmap useThisBitmap = Bitmap.createScaledBitmap(bitmap,
wallpaperManager.getDesiredMinimumWidth(),
wallpaperManager.getDesiredMinimumHeight(), true);
bitmap.recycle();
try {
wallpaperManager.setBitmap(useThisBitmap);
} catch (IOException e) {
e.printStackTrace();
}
Log.e("", "Width : " + wallpaperManager.getDesiredMinimumWidth());
Log.e("", "Height : " + wallpaperManager.getDesiredMinimumHeight());
Is there any relation with offset??

Categories

Resources