How to extends ResourceProxy interface in osmdroid? - java

yea, i know, another thread about changing icons in osmdroid.
But there isn't any good explanation available !
I made lot of research and it is a frequently asked topic. Why not make a clear answer at this point for all user who need to specify their own resources ?
All stuff available is to "Have a look at ResourceProxy.java" or "Pass the bitmap to constructor". No way, it doesn't work for me, I don't even know how a simple interface could find my drawable in my res folder ! I tried to pass some .PNG files with the same names as osmdroid (like "person.png") but when I run the app I have still the default resource.
Can someone explain clearly how to write "our own ResourceProxy" step by step ? Not brievely like that because I followed the steps and didn't manage to success.
I know that
osmdroid was fixed recently in github but the .aar is older than the fix. Here you can find the
Resource Proxy class.

When you create in an instance of the MapView, you need to pass in a reference to a implementation of "ResourceProxy". By default, it loads the "DefaultResourceProxyImpl". To override, create a new class that extends DefaultResourceProxyImpl and then you can override getBitmap and getDrawable. There is actually is an example that overrides the DefaultResourceProxyImpl here:
https://github.com/osmdroid/osmdroid/blob/master/OpenStreetMapViewer/src/main/java/org/osmdroid/ResourceProxyImpl.java
Just for you, I'm working on including such an example with the osmdroid example app. It's going to look something like this
public class CustomResourceProxy extends DefaultResourceProxyImpl {
private final Context mContext;
public CustomResourceProxy(Context pContext) {
super(pContext);
mContext = pContext;
}
#Override
public Bitmap getBitmap(final bitmap pResId) {
switch (pResId){
case person:
//your image goes here!!!
return BitmapFactory.decodeResource(mContext.getResources(),org.osmdroid.example.R.drawable.sfgpuci);
}
return super.getBitmap(pResId);
}
#Override
public Drawable getDrawable(final bitmap pResId) {
switch (pResId){
case person:
//your image goes here!!!
return mContext.getResources().getDrawable(org.osmdroid.example.R.drawable.sfgpuci);
}
return super.getDrawable(pResId);
}
}
Edit: done
See https://github.com/osmdroid/osmdroid/blob/master/OpenStreetMapViewer/src/main/java/org/osmdroid/CustomResourceProxy.java
Edit: Edit:
Wiki updated, see
https://github.com/osmdroid/osmdroid/wiki/How-to-use-the-osmdroid-library

Related

Can two exported classes in different packages interact without making their members public?

I stumbled across this issue while working on a library and have been trying to find a solution for hours now. I'm not sure if this is even possible or not. I have a module, com.gui, which contains a package called com.gui.components, com.gui.constraints and com.gui.animation. I want to implement text-based components and set up a package called com.gui.text.
I have a Font class inside of that package (com.gui.text) which should be public so the user can pass it into one of the text components. However, I'm struggling with how I transfer data like the texture id over to the text component without making the variable public (or implement a public getter). I messed around with not exporting the text package and extending the Font class inside of the text component class but this seemed like a suboptimal solution and I don't really like the feel of it.
Here is the hierarchy of my project visually:
src/com.gui
--component -> exported
----UITextComponent
--text
----mesh
------Texture
----font -> exported
------Font // contains a Texture object which should stay invisible to the user
--XXX // other packages
Am I missing anything obvious here or is this impossible to do currently?
If you want to go crazy you can do the following (this is not recommended)
in your Font class have a method like this:
public class Font {
private String textureId;
...
public void setTextureId(Texture texture) throws Exception {
if (texture == null) return;
Field field = texture.getClass().getDeclaredField("textureId");
if (field == null) return;
field.setAccessible(true);
textureId = String.valueof(texture.get(font));
}
}
Again this is not the recommended way but it is a way to get what you want with the layout you have. Also you'd have to add some more validation checks.

How to correctly implement stfalcon's chatkit

I'm trying to implement a chat app using stfalcon's ChatKit library. I've followed the docs in their repo, but there are things I'm not sure I'm getting right.
First, I created a new activity called DialogsListActivity, and copied the xml in the activity's xml file.
From here I first copied the xml part to the activity's xml file.
Next comes the adapter setup. I copied the given code after the OnCreate method, including the last line (dialogsListView.setAdapter(dialogsListAdapter);) as the last line in OnCreate. The whole activity now looks like this:
ListView dialogsListView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dialogs_list);
dialogsListView.setAdapter(dialogsListAdapter);
}
DialogsListAdapter dialogsListAdapter = new DialogsListAdapter<>(dialogs, new ImageLoader() {
#Override
public void loadImage(ImageView imageView, String url) {
//If you using another library - write here your way to load image
Picasso.with(DialogsListActivity.this).load(url).into(imageView);
}
});
}
Questions:
is this the right place to put the adapter in?
is it ok to put set the dialogsListView as an attribute and defining it inside OnCreate()?
the dialogs from new DialogsListAdapter gets a Cannot resolve symbol 'dialogs' message.
the new ImageLoader() from same place gets a Class 'Anonymous class derived from ImageLoader' must either be declared abstract or implement abstract method 'loadImage(ImageView, String, Object)' in 'ImageLoader'
What am I missing there?
For the IDialog and IUser implementation I created the classes DefaultDialog and Author, and copied the given code. As I expected, the 'symbols' returned by the methods 'cannot be defined'. Where should they be defined and how?
Next in the tutorial is the Data management section which I think would set those values.
I already downloaded the sample project and tried to look inside, but I cannot find the public class DefaultDialog that implements IDialog or anything similar. Plus, I got pretty lost trying to understand the library from that sample project.
Any help would be much appreciated.
Thanks in advance.

can I use static layout (native UI) in react native's native android implementation?

I am writing a react native application and I want to use some of the static layouts (for Android) I have from my old application.
I looked at https://facebook.github.io/react-native/docs/native-components-ios.html and wrote a few classes (MyViewManager.java and MyView.java).
I want to be able to use the static layouts I have for MyView.java.
I went through the facebook's react native code on github.
I could not find an appropriate method like setContentView(R.layout.myview). I was wondering if anybody tried this and this will work.
Can someone please help me with this problem?
You can try out something like
The layout inflater will inflate given xml file and put it as a child of this(second argument in inflate), which is MyLayoutView.
See the definition of inflate and change arguments as per customization required.
public class MyManyViewsManager extends ViewGroupManager<MyLayoutView> {
}
class MyLayoutView extends FrameLayout {
init() {
rootItem = (ViewGroup) LayoutInflater.from(getContext()).inflate(R.layout.xmlfilename, this, true);
}
}

Generic classes in my application

I've created a few minor apps for Android while learning. Being a PHP developer, it's a challenge to get used to it.
I'm especially wondering how I could define a couple of "general" functions in a separate class. Eg I have a function that checks if network connection is available, and if not, shows a dialog saying that the user should enable it. Currently, that function exists in several of my activities. Of course that seems strange - I suppose it would be more logical to define it once and include it in the activites where needed.
I tried putting it in a new class, and included that class in the original activity. But that failed since eg getBaseContext() is not accepted anymore.
I'm wondering how to go ahead. What should I be Google-ing for ? What is this mechanism called?
You need to create class with static methods. Like this
public class HelperUtils {
public static void checkNetworkConnection(Context ctx) {...}
}
Then you can call it from any place like this:
HelperUtils.checkNetworkConnection(this.getContext());
Assuming current class has Context.
You should read books on general OOP concepts where different type of methods are explained.
You can for example create a class - let's call it NetworkUtils. In this class you can create static method boolean isNetworkConnectionAvailable() and return true if is available and false otherwise. In this class you can create another static method void showNoConnectionDialog(Activity activity) - and in this method you create dialog starting with
public static void showNoConnectionDialog(Activity activity) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
//setting message, listener etc. and finally
builder.create().show();
}
In your activity, where you want to check and handle network connection you should call:
if (!NetworkUtils.isConnectionAvailable(getApplicationContext())) {
NetworkUtils.showNoConnectionDialog(YourActivityClassName.this)
}
I guess this should work.

Android: Parcelable.writeToParcel and Parcelable.Creator.createFromParcel are never called

I'm totally new to posting questions on here, however I have been reading a lot on here for years. Normally I always am able to find my answers by thoroughly searching the web, but this time I am at a loss...
After having spent yet another day of trying to figure out why this is not working I decided to ask for help, hoping you guys can give me a few pointers, or better, a solution.
The problem:
In an Android game I have come to the point where I have to make the application remember its state when a user e.g. presses the HOME-screen button. After some searches I realised that in order to make my classes initialize back to their appropriate states after re-opening the application I had to support the Parcelable interface to pass them with the Bundle.
In my onStop and onStart functions I respectively save and restore the game state to and from a Bundle, however when I call the putParcelable and getParcelable functions on the Bundle the object's writeToParcel and createFromParcel functions are never called.
Fearing that this may have been due to the relative complexity of the game I figured I had best create a very simple application to try to get it to work.
Based on many Parcelable examples I have seen online, this became my class:
public class ParcelableTest implements Parcelable {
int id;
public ParcelableTest(int newID)
{
id = newID;
}
private ParcelableTest(Parcel in) {
readFromParcel(in);
}
public void writeToParcel(Parcel out, int arg1) {
writeToParcel(out);
}
public void writeToParcel(Parcel out) {
Log.v("ParcelableTest","Writing to parcel");
out.writeInt(id);
}
public void readFromParcel(Parcel in) {
id = in.readInt();
}
public int describeContents() {
return 0;
}
public static final Parcelable.Creator<ParcelableTest> CREATOR = new
Parcelable.Creator<ParcelableTest>() {
public ParcelableTest createFromParcel(Parcel in) {
Log.v("ParcelableTest","Creating from parcel");
return new ParcelableTest(in);
}
public ParcelableTest[] newArray(int size) {
return new ParcelableTest[size];
}
};
}
And from my Main activity I would call the following functions to save / restore the data:
public Bundle saveToBundle(Bundle savedState)
{
savedState.putParcelable("Test1",mTest1);
savedState.putParcelable("Test2",mTest2);
return savedState;
}
public void restoreFromBundle(Bundle savedState)
{
mTest1 = savedState.getParcelable("Test1");
mTest2 = savedState.getParcelable("Test2");
}
But for some reason neither of the functions (with the putParcelable and getParcelable functions) will result in the appropriate Parcelable calls in my test class.
The strangest thing is that it does somehow read the correct values (I have tried with more variables in the class), but my debugging and my log shows that tha application never gets to writeToParcel and createFromParcel.
What am I missing here?
Any help / thoughts would be appreciated.
Apparently the Android Bundle class does not adhere to the parcelable protocol that instead is followed during IPC marshalling.
Instead, it seems like the Bundle implementation just writes and reads the Parcelable object into its own internal map by means of reflection. From a test we did, it seems that the Bundle writes/reads every field defined in your Parcelable-derived class, just because you have declared those fields.
Technically, the documentation doesn't say that writeToParcel or createFromParcel are called from onSaveInstance. As a matter of fact, if you check the savedState in your code you are going to find that it is exactly the same object instance in both the save and the restore cases; it makes sense to avoid serialize-deserialize if you can. OTOH, the documentation doesn't say either that serialization is not done. The conclusion should be that you shouldn't depend on either case, just assume that you get the correct bundle.
Also, you may want to check http://developer.android.com/guide/topics/resources/runtime-changes.html
I confirm what superjos said.
On the saveToBundle event, Android bundle just stores the class's members per reflection and doesn't call the Parcelable functions.
I have lost one day on this problem! sad....
This is really bad .... This means you potentially stores a huge amount of data for nothing using this way.

Categories

Resources