Android ICS 4.0 update breaking spinning wheel animation - java

My application has a spinning wheel for the initial app load. Works fine upto android 3.0 honeycomb. But in ICS 4.0 its broken. Its a simple spinning wheel animation. In ICS this wheel is spinning around a point near its circumference instead of the center point. This gives a visual impression like a wobbling wheel instead of a consistent spinning wheel. Here is the code
Layout:
<ImageView
android:id="#+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/spinner_white_48"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true"
/>
spinner_animation.xml
<rotate
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:duration="1200">
</rotate>
Java File (Activity)
Animation rotateSpinner = AnimationUtils.loadAnimation(this,R.anim.spinner_animation);
rotateSpinner.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
});
findViewById(R.id.spinner).startAnimation(rotateSpinner);
NOTE: The app wont even start on 4.0.2(Samsung Galaxy). But shows this distorted animation in 4.0.3 app app works fine(Nexus S).
Any help is appreciated. Thanks in advance

If by "wobbling" you mean that it appears to be revolving around something other than its center point, then this is a known bug.

Until there is a better fix, you can use:
RotateAnimation rotation;
if(Integer.parseInt(Build.VERSION.SDK) >=15){
rotation = new RotateAnimation(0f,360f,Animation.RELATIVE_TO_SELF,0.25f,Animation.RELATIVE_TO_SELF,0.25f);
}else{
rotation = new RotateAnimation(0f,360f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
}

Check the layout settings. I have a feeling if you just drop the same view in a simple LinearLayout, it will work OK again. It appears you're in a RelativeLayout and I have a feeling the layout_centerHorizontal or layout_alignParentTop are giving you grief.

You should to add in your manifest this:
<supports-screens android:resizeable="true"
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:anyDensity="true"/>

Related

How to include Java jar to C# Xamarin project (Picasso example), problem with ImageView android:src field

I am doing a java to c# transition, and need help.
in Visual Studio 2019 Pro, Android 9.0 (Pie), I am doing this example:
https://learn.microsoft.com/en-us/xamarin/android/platform/binding-java-library/binding-a-jar
The goal is later to convert my java libs to c# for my big project.
I follow the instructions to the letter, and when I come to the part where I need to create an ImageView, there is the problem. Once I create the ImageView, it has an android:src field, something like this (auto generated):
android:src="#drawable/icon"
The problem here, is when I remove that field, in the VS designer, the ImageView disappears and it does not matter if I have the c# code or not, even when I set the srec to:""
Bellow is literally all the code in MainActivity:
using Android.App;
using Android.OS;
using Android.Support.V7.App;
using Android.Runtime;
using Android.Widget;
using Com.Squareup.Picasso;
namespace App3
{
[Activity(Label = "#string/app_name", Theme = "#style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
/***********************************************************************/
/**Picasso Code**/
ImageView imageView = FindViewById<ImageView>(Resource.Id.imageView1);
// Use the Picasso jar library to load and display this image:
Picasso.With(this)
.Load("http://i.imgur.com/DvpvklR.jpg")
.Into(imageView);
/**End Ff Picasso Code**/
/***********************************************************************/
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
XML Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="25px"
android:minHeight="25px">
<ImageView
android:src="#drawable/icon" <!-- this line -->
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/imageView1" />
</LinearLayout>
The app does nothing, and in the emulator, the ImageView is empty.
And there is no error, or anything.
If you need anything more, please let me know.
I hope you can help me, if not, thank you for your time.
Edit 1:
It seems, the problem lies in the C# code.
If I add the android:src field, it still does not show up on the emulator, but when I remove the code (the Picasso code) than the image(drawable/icon) shows. Still no error!!
try this
<ImageView
android:src="#drawable/icon" <!-- this line -->
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minWidth="50px"
android:minHeight="50px"
android:id="#+id/imageView1" />

Invalid drawable tag vector - appcompat-v7:24.1.1

OK I've read most of available answer on similar questions but nothing fixed my problem
gradle classpath 'com.android.tools.build:gradle:2.1.2'
android {
defaultConfig {
minSdkVersion 16
targetSdkVersion 24
vectorDrawables.useSupportLibrary = true
}
}
dependencies {
compile 'com.android.support:recyclerview-v7:24.1.1'
compile 'com.android.support:appcompat-v7:24.1.1'
compile 'com.android.support:cardview-v7:24.1.1'
compile 'com.android.support:support-v4:24.1.1'
compile 'com.android.support:design:24.1.1'
}
activity.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/ScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ViewItem"
tools:ignore="MissingPrefix">
...
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:layout_gravity="center_vertical"
android:layout_marginBottom="10dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="10dp"
android:foregroundGravity="center_vertical|center|center_horizontal"
app:srcCompat="#drawable/ic_car" />
...
</ScrollView>
vector ic_car.xml
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#5c5c5c"
android:pathData="M18.92 6.01C18.72 5.42 18.16 5 17.5 5h-11c-.66 0-1.21 .42 -1.42 1.01L3 12v8c0
.55 .45 1 1 1h1c.55 0 1-.45 1-1v-1h12v1c0 .55 .45 1 1 1h1c.55 0 1-.45
1-1v-8l-2.08-5.99zM6.5 16c-.83 0-1.5-.67-1.5-1.5S5.67 13 6.5 13s1.5 .67 1.5
1.5S7.33 16 6.5 16zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5 .67 1.5
1.5-.67 1.5-1.5 1.5zM5 11l1.5-4.5h11L19 11H5z" />
<path android:pathData="M0 0h24v24H0z" />
</vector>
my activity class extends AppCompatActivity and all android:src tags are changed to app:srcCompat but still I see Invalid drawable tag vector error on the minSdkVersion which is set to 16.
In my case, the crash happened due to using Resources.getDrawable(int) to get the vector drawable on pre-lollipop devices. I was trying to create a drawable to pass into
ImageView.setImageDrawable(Drawable).
Google Blog Post for Android Support Library 23.2:
As of Android Support Library 23.3.0, support vector drawables can
only be loaded via app:srcCompat or setImageResource().
Solution: Use VectorDrawableCompat.create(Resources, int, Theme) to create the drawable.
You can also use ImageView.setImageResource(int) however this will read/decode the bitmap on the UI thread.
Truth is, looking at your code, it should work in any version of the library, as you are using only the srcCompat attribute.
One issue I suspect, is that your vector is in a drawable-21 folder, while in the regular Drawable folder you have single file that references these Drawables. This was a method done in early versions of the library, but does not work anymore due to changes below. Just move the actual vector file to the Drawable folder.
We have had sometimes similar issues that were solved by changing the ImageView to an AppCompatImageView. Even though the library is supposed to do this automatically, it seems that sometimes it doesn't.
It is still possible that the code is breaking if your vector is part of a compound image, for example a layered image. Or it's breaking somewhere else for which you have not posted the code, for example if you are setting a vector as the leftImage on an ImageButton. These functionalities have been removed in 23.3, as #Zeke has answered. Nonetheless, it was returned in 23.4, made usable by adding the following to your activity
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
They still warn you it can cause memory leaks. See https://medium.com/#chrisbanes/appcompat-v23-2-age-of-the-vectors-91cbafa87c88#.s48hqaw1u, though for minimal use it shouldn't be an issue.
A simple workaround would be to create the Drawable and set it in code. Something like this;
Drawable icon = AppCompatDrawableManager.get().getDrawable(context, resVectorID);
// Set it for example as a left image of button
button.setCompoundDrawablesWithIntrinsicBounds( icon, null, null, null );
I have not tested this, and have no ideas if this causes memory issues or not. Would love it if someone can follow up.
Problem got solved itself after updating to Android studio 2.2
I did like this:
public static final Drawable getMyDrawable(Context context, int id) {
final int version = Build.VERSION.SDK_INT;
if (version >= 21) {
return ContextCompat.getDrawable(context, id);
} else {
return VectorDrawableCompat.create(context.getResources(), id, context.getTheme());
}
}

Bettering the Generic SeekBar Example

This code and minor variations thereof exist in many forums on the net. When I launch it on my Samsung Galaxy Tab 2 (Android 4.1.1), the bar appears, the thumb can be moved, the position is reported, etc. All good, EXCEPT, the thumb never disappears. Mine manifests as a little blue circle, which I can slide along a bar, but it leaves a trail of "thumbs" behind it: one at each of the possible integer locations in the range of the seekbar.
Is the code incomplete? Is there something we have to add to manually redraw the component?
import android.app.Activity;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.TextView;
public class FullscreenActivity
extends Activity
implements SeekBar.OnSeekBarChangeListener {
SeekBar seekBar;
TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fullscreen);
seekBar=(SeekBar)findViewById(R.id.seekbar);
textView=(TextView)findViewById(R.id.textview);
seekBar.setOnSeekBarChangeListener(this);
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// Notify that the progress level has changed.
textView.setText(textView.getText()+"\n"+"SeekBar now at the value of:"+progress);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// placeholder
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// placeholder
}
}
Here's the layout:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/FrameLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<SeekBar
android:id="#+id/seekbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="75dp"
android:max="31"
android:progress="15" />
<TextView
android:id="#+id/textview"
android:layout_width="fill_parent"
android:layout_height="270dp"
android:layout_marginTop="150dp"
android:scrollbarStyle="insideOverlay"
android:scrollbars="vertical" />
</FrameLayout>
Screenshot of the effect:
Update The effect is the same on a ZTE-BLADE running Android 2.2. Of course teh default graphic is different (the gray / orange seekbar with a more square "thumb") but the thumbs remain behind at all the points I've scrolled through.
The residual garbage clears if I change the screen orientation, which makes me think it just needs a redraw. Can anyone help?
So, I copied and pasted my example code line-at-a-time into a new project, running it as I went, hoping to find the line which failed.
Got the whole thing pasted in and it worked perfectly. No problems in the seekbar.
On comparing the projects, the only difference was that the AndroidManifest.XML file contained the line
android:theme="#style/FullscreenTheme"
in the activity section. So, I went back to my original (faulty) project and took this line out. Now the project works fine.
I have my answer: the code is complete and there's nothing we need to add to make it redraw.
I still don't understand why this line had that effect and now I have a horrible white background when I wanted black.

Android ime actionGo doesn't work on certain devices

ime actionGo simply won't work on certain devices, like the HTC Evo 4G. It works on Motorola Atrix and Droid X.
Here is the code:
<EditText
android:id="#+id/password"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_centerHorizontal="true"
android:hint="#string/password_hint"
android:password="true"
android:inputType="textPassword"
android:autoText="false"
android:imeOptions="actionGo"/>
TextView.OnEditorActionListener listener = new TextView.OnEditorActionListener()
{
public boolean onEditorAction(TextView exampleView, int actionId, KeyEvent event)
{
if(actionId == EditorInfo.IME_ACTION_GO)
{
loginValidation();
}
return true;
}};
password.setOnEditorActionListener(listener);
This seems to be a bug. Different manufacturers make a customized keyboard for their phone which may not completely behave as the android standard keyboard. This issue has been raised before. Most people overcome this issue by either overiding the onKey event or using a TextWatcher class. A bug has been filed about this
http://code.google.com/p/android/issues/detail?id=2882
I ran into this recently and if you're not worried about the user being able to add lines via the keyboard this worked for getting the "Go" button to show up:
android:singleLine="true"

How to create map tiles from OpenStreetMap offline, display it on Android?

What I want is to display a simple offline map using OpenStreetMap. I cannot find in the web the right tools to create map tiles and use it to display a map in Android. I have downloaded different resources but it seems that I don't have any idea where to start. I want to integrate images from OpenStreetMap using JOSM but i don't know if I can use it on Android.
Can I use Mapnik? Your help will a great thank you.
I'm currently developing (my first) Android application using the OpenStreetMap (OSM) API, so while I can't help you with the JSOM, I can try to help with the OSM part:
Assuming that you want to create a new activity in your android application that simply displays a OSM map, you might start with something like this:
package example.stackoverflow.osmdroid;
import android.app.Activity;
import android.os.Bundle;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
public class YourMap extends Activity {
// The MapView variable:
private MapView m_mapView;
// Default map zoom level:
private int MAP_DEFAULT_ZOOM = 15;
// Default map Latitude:
private double MAP_DEFAULT_LATITUDE = 38.535350;
// Default map Longitude:
private double MAP_DEFAULT_LONGITUDE = -121.753807;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Specify the XML layout to use:
setContentView(R.layout.osm_map);
// Find the MapView controller in that layout:
m_mapView = (MapView) findViewById(R.id.mapview);
// Setup the mapView controller:
m_mapView.setBuiltInZoomControls(true);
m_mapView.setMultiTouchControls(true);
m_mapView.setClickable(true);
m_mapView.setUseDataConnection(false);
m_mapView.getController().setZoom(MAP_DEFAULT_ZOOM);
m_mapView.getController().setCenter(
new GeoPoint(MAP_DEFAULT_LATITUDE, MAP_DEFAULT_LONGITUDE));
m_mapView.setTileSource(TileSourceFactory.MAPNIK);
} // end onCreate()
} // end class YourMap
Where your osm_map.xml layout may look something like this:
<?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">
<org.osmdroid.views.MapView
android:id="#+id/mapview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:enabled="true"
android:clickable="true"
/>
</RelativeLayout>
As for the actual map tiles, there is a really cool program called Mobile Atlas Creator, which allows you to generate the necessary map tiles for the offline Android map implemented above.
Once you have the application installed, and you want to create a new atlas, you'll be asked to select your "desired altas format." When this pops up, select "Osmdroid zip."
Once everything loads, select a region on the map that you would like to create tiles for, select the zoom levels you want tiles for, and hit the "Add Selection" button in the column on the left, followed by "Create Atlas."
Oh, and depending on the source, you may need to check the "Create/Adjust Map tiles" checkbox to force the tiles to be exported as PNGs -- does anyone know if it's possible to use JPG with OSM?
Once the ZIP has been generated, I renamed it to "Mapnik.zip" and moved it to a newly created folder called "tiles" in my Eclipse Android project workspace. In order to get it working, I also had to open the zip file, and rename the top level folder from something like "Google Earth" (depending on the map source you used), to "Mapnik," in order for the tile to display in my Android application.
In order to actually load the tiles onto your phone, however, you'll need to use the ADB tool from the terminal. In your ADB tool directory, you'll want to run something like this (each line is a new command):
./adb shell rm -r /sdcard/osmdroid/
./adb shell mkdir /sdcard/osmdroi/
./adb push ~/path/to/your/mapnik.zip /sdcard/osmdroid
Depending on the size of the map and the speed of the phone's memory bus, this last step may take a several minutes to an hour to complete. Once done, your map should work -- I hope!
As I mentioned, this is the first time I've used the OSM API, so I'm by no means an expert on it, and I can only comment on what worked for me.
Hope this will help you get started!
EDIT:
I didn't have a chance to actually run the code that I wrote up yesterday, so I didn't catch a few of the errors. I just created a new project in Eclipse, dumped my code in there, fixed a few things and got it up and running. All changes that I made are reflected in the code above! I forgot several of the basic import statements, and I forgot to add permissions to the manifest.xml file.
The last few lines of my manifest.xml now look like this:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
And you also might want to add this to the manifest, although certainly not critical:
<supports-screens
android:anyDensity="true"
android:resizeable="false"
android:largeScreens="true"
android:normalScreens="true"
/>
Add this right after the <uses-sdk ... /> part.
Furthermore, be sure to import the following two JAR libraries:
osmdroid-android-3.0.3.jar // Or whatever version you're using...
and
slf4j-android-1.5.8.jar // Or whatever the latest version is...
Without this last JAR, my code kept crashing until I remembered to include it.
Make sure to modify the default coordinates so that they point to a location that you actually have map tiles for, otherwise you're not going to see much of anything, aside from a white canvas.
Sorry for not running the code on my end first!
Here is a step by step solution:
In brief:
1- You must download map tiles using Mobile Atlas Creator. I have explained the steps HERE
2- Move the resulting zip-file to /mnt/sdcard/osmdroid/ on your device.
3- Adding osmdroid-android-XXX.jar and slf4j-android-1.5.8.jar into build path your project
4- Adding MapView: You can add a MapView to your xml layout
<org.osmdroid.views.MapView
android:id="#+id/mapview"
android:layout_width="match_parent"
android:layout_height="match_parent"
tilesource="Mapnik"
/>
Or create a MapView programmatically:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
mResourceProxy = new ResourceProxyImpl(inflater.getContext().getApplicationContext());
mMapView = new MapView(inflater.getContext(), 256, mResourceProxy);
return mMapView;
}
Don't forget to add these permissions to your Manifest:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
This is a good Sample Project.
Hope it Helps ;)
Important
As #Scai mentioned: recently Open Street Map announced that this tool is not good and had some problems:
This tool results in heavy traffic for the OSM tile servers and is likely to be blocked.
Please don't use it.
Alternatively to map tiles you can also use vector data for your offline map, for example mapsforge or the Mapbox Android SDK. For more information consult the OSM wiki about offline OSM and Android libraries.

Categories