I have some new questions in today's citymaps development.
In the Android studio,if I develop the code for citymap, there are always no logs showing but for others that does not happen. Why?
According to the citymaps official website, to create a map instance with CitymapsMapFragment, but in the sample project which citymaps provides, it uses SupportCitymapsMpaFragment ,What is the difference between them?
When the map is loading complete, is it automatically positioning to the current position or some other default position? Where is it?
If I open the GPS location,I can locate to the current position and show a blue arrow quickly, but too much power consumption,are there any other location way like network or base station location?
Code follows:
CitymapsMapFragment fragment = (CitymapsMapFragment)fragmentManager.findFragmentById(R.id.map);
if (fragment != null) {
fragment.setMapViewListener(this);
}
I did not find the fragment have the method setMapViewListener but setMapViewReadyListener,does it right?
Other code:
CitymapsMapView mapView = new CitymapsMapView(this, options, this);
When I add animate in additional methods like this:
mapView.setMapPosition(position, 300, new MapViewAnimationListener() {
#Override
public void onAnimationEnd(boolean completed) {
Log.d("SomeApp", "Move Complete!");
}
});
the project fails and exits,I tried to surround the code with try-catch block to catch exception for purpose, but nothing shows in logcat view. Why?
I am developer on the Citymaps project. I will do my best to answer all your questions
1) If you are not receiving log statements, this is likely an issue with your own application, IDE, or device configuration. In our own application, which uses the Citymaps SDK, we have no issues with logging.
2) Prior to using the Citymaps SDK, it is highly advisable that you familiarize yourself with fragments, but the short version is that SupportCitymapsMapFragment extends from the Fragment class in the v4 support library.
3) It is up to you to set the default position the map.
4) If you create a class which implements from the LocationSource interface, and then call mapView.setLocationSource, you can modify the behaviors of the map's location services. For an example, have a look at CitymapsLocationSource.java, which is the default implementation for this interface used by the SDK.
As for the exception you are having, you have not provided nearly enough information. Please show a stack trace, and I may be able to help.
Thank you for using our SDK, feel free to post again with any more questions.
Related
I managed to get Paging library 3.0.0-alpha02 working with RxJava2 in a Kotlin app, following the Paging 3 documentation.
However I had a problem when I ported the paging code to a Java app, in that the data is being retrieved by page, but the page retrieval keeps happening in the background even when I don't scroll the recyclerview. In other words, after loading page 1, it then loads page 2, 3, 4, etc, and keeps going.
I'm setting up the paging in the viewmodel:
public Observable<PagingData<Item>> loadItems()
{
PagingConfig config = new PagingConfig(...);
Pager<Integer, Message> pager = new Pager<Integer, Item>(config, null, null,
() -> new MyPagingSource());
return PagingRx.getObservable(pager)
}
Then subscribe in the activity/fragment:
disposable = viewModel.loadItems()
.subscribe( pagingData -> {
getAdapter().submitData(getLifecycle(), pagingData);
});
In the Java app, I'm subscribing in a fragment instead of and an activity, but otherwise the code is the same as the Kotlin app.
I realize that the paging library 3 uses coroutines and flow internally, so I added this dependency but it didn't make any difference.
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-rx2:1.3.7'
Edit:
The Kotlin demo app is on GitHub and has a RxJava as well as a Flow version (based on the Android samples). It does paging on the Telephony content provider to get SMS inbox messages.
PagingSource.load is automatically triggered based on PagingConfig.prefetchDistance as items are bound to RecyclerView. This means that even if you don't scroll, Paging will try to fulfill items based on visible viewport.
Terminating load behaves the same regardless of what language you're using, but it is based on prev/nextKey being null for LoadResult.Page in PagingSource and endOfPaginationReached in RemoteMediator.
If you believe that this is an issue with the library, I'd encourage you to file an issue here: https://issuetracker.google.com/issues/new?component=413106&template=1096385 with an attached repro, and I'd be happy to take a look!
Otherwise if you could attach your PagingSource implementation, that would help as there isn't much information to go on with what you've posted so far.
It turns out that Paging 3.0 with RxJava does work properly, when it is being used in an activity. I have the problem because I had the recyclerview, adapter, etc in a fragment. Not sure why this is, possibly due to differences in the lifecycle?
I'm using the Java botbuilder to build a microsoft teams bot. I want to add Cards to my bot (e.g. to embed links, quick replies, and images).
In the above link it says: suggested actions are not supported in Microsoft Teams: if you want buttons to appear on a Teams bot message, use a card.
However, I can find no documentation on how to add a 'card' to the Activity schema.
I tried:
1. Using suggested actions
I tried adding my List<CardAction> to the SuggestedActions
field in Activity but they were not rendered by microsoft teams
(as expected, the documentation says this is not supported).
2. Using Attachments
I suspect it could be done using attachments, but can only find
documentation for the C#/JS versions (e.g.
https://learn.microsoft.com/en-us/azure/bot-service/nodejs/bot-builder-nodejs-send-rich-cards?view=azure-bot-service-3.0).
So I want to know how to add 'a card' to Activity schema so it can be rendered by my bot.
The BotFramework Java SDK is still in preview, so there isn't a lot of documentation I can point you towards. However, here is an example of adding a HeroCard to a reply.
Activity reply = new Activity()
.withType(ActivityTypes.MESSAGE)
.withRecipient(activity.from())
.withFrom(activity.recipient())
.withAttachments(Arrays.asList(
new Attachment()
.withContentType("application/vnd.microsoft.card.hero")
.withContent(new HeroCard()
.withTitle("Hero Card")
.withSubtitle("BotFramework")
.withButtons(Arrays.asList(new CardAction()
.withValue("https://learn.microsoft.com/en-us/azure/bot-service/")
.withTitle("Get started")
.withType(ActionTypes.OPEN_URL)
))
.withImages(Collections.singletonList(new CardImage()
.withUrl("https://sec.ch9.ms/ch9/7ff5/e07cfef0-aa3b-40bb-9baa-7c9ef8ff7ff5/buildreactionbotframework_960.jpg"))))
));
You can also take a look at the SDK Attachment Tests for more examples.
Hope this helps!
I must've gone through ever Stack Overflow question based on the Google Calendar so far with no luck what so ever. I've been trying this for hours now and got little to no results at all.
I'm a pretty new programmer with Java and Android, with quite little experience out of the field as it is. Basically the main problem I am having is with viewing another user's Google Calendar which is set to public.
At the moment, from the Google tutorials and other sites I've managed to get the calendar showing, which is pretty simple enough. It'll just load up and show the current user's calendar. Which can literally be done with (with a simple button in the layout).
public void onClick(View view) {
// A date-time specified in milliseconds since the epoch.
long startMillis = System.currentTimeMillis();
Uri.Builder builder = CalendarContract.CONTENT_URI.buildUpon();
builder.appendPath("time");
ContentUris.appendId(builder, startMillis);
Intent intent = new Intent(Intent.ACTION_VIEW).setData(builder.build());
startActivity(intent);
}
Obviously this doesn't pass in any user data for the public account or anything, I've been reading through the Calendar Provider Developer guides within the Google tutorials. I've tried to set up the account details thing, but it just never works. I've tried to do it as a Sync Adapter, but honestly I just know I'm not doing it right. I don't know if I really even need to use a Sync Adapter as all I want to do is literally see the events, not modify anything or update anything.
I am using API 14+ and want to user the Calendar Provider etc. It looks simple enough but I've been bashing my head against this for a few days and put a lot of hours into it and seemingly nothing I do works. At least I've got some sort of calendar opening but it's not what I want.
Is it all just down to the sync adapter? If so how will I be able to call a calendar? Another question similar had
private static Uri buildCalUri() {
return CalendarContract.Calendars.CONTENT_URI
.buildUpon()
.appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
.appendQueryParameter(Calendars.ACCOUNT_NAME, ACCOUNT_NAME)
.appendQueryParameter(Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL)
.build();
}
I'm hoping this is something similar to what I need but I'm very unsure. In the developer tutorial ACCOUNT_TYPE_LOCAL was important if the account wasn't on the device
Any help will be greatly appreciated!
If you are looking to integrate the public Google Calendar (www.google.com/calendar) with your Android Application, you have to use the Google Calendar API.
The easiest method would be download the Google Calendar Client Library from here and then use the API Reference here. In the Client Library Page, you want to download "Google APIs Client Library for Java (rc)" package to integrate into your Android App.
You will first need to go to API Console to create an App with Calendar API Access .
If you do not want to use the native library, you can even do it using REST API (use HTTP GET & POST Commands), example App here
Hope this helps.
For anybody that has followed the Android Developer API example, but still can't find how to add a public calendar. Try out
CalendarListEntry gracieCal = new CalendarListEntry();
gracieCal.setId("your-public-calendar-id");
mService.calendarList().insert(gracieCal);
Events events = mService.events().list(gracieCal.getId())
.setMaxResults(10)
.setTimeMin(new DateTime(System.currentTimeMillis()))
.setOrderBy("startTime")
.setSingleEvents(true)
.execute();
List<Event> items = events.getItems();
'mService' is the com.google.api.services.calendar.Calendar instance that you should have already created. (see the api tutorials mentioned by the other answer)
'your-public-calendar-id' can be found in the settings for your public google calendar.
This is my first post here, so I hope I'll explain my problem clear enough:
I'm extending the FragmentActivity class to create a HeatMapActivity. In this activity I use a GoogleMap object, which I obtain as follows:
// Try to obtain the map from the SupportMapFragment.
map = ((SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.heatmap)).getMap();
Now, after doing a null-Check etc., I'm adding a TileOverlay in the setUpMap() method, as shown below:
// Configure and add overlay
tileProvider = new HeatMapTileProvider(map);
map.addTileOverlay(new TileOverlayOptions()
.tileProvider(tileProvider));
Ok, so far no problem at all. I implemented the TileProvider interface to provide the tiles for the HeatMap overlay.
I want to use the Projection object for converting latitude/longuitude to and from pixels on the screen. The Projection object should be returned by the getProjection() method of the GoogleMap class.
So now here's the problem: If I use the following code in the HeatMapActivity class, everything is fine:
System.err.println("Test1: " + map.getProjection().fromScreenLocation(new Point(50, 50)));
But if I forward the GoogleMap object to the TileProvider, respectively to the renderer I use, the code is not working anymore:
public byte[] render(int x, int y, int zoom, GoogleMap map) {
...
System.err.println("Test2: " + map);
System.err.println("Test3: " + map.getProjection().fromScreenLocation(new Point(50, 50)));
...
}
I definitely know, that the map parameter is not null (see Test 2), but the code just seems to block when I call getProjection(). There is no error coming up and if I don't use the Projection object, everything else is working fine. I don't have any clue, why I should not be allowed to call getProjection() from another class than the activity...
I am using the ADT bundle for Windows (version x86_64-20130729), Android SDK version from 8 to 17, testing on Android 2.3.5 at the moment. The map is displayed, the needed libraries are included and the permissions are set in the android manifest.
Any ideas? Any help or hints are appreciated.
Seb
The issue here is that getTile (and your render method) are called outside UI thread.
This will cause exception, which you won't see, because it is probably silently handled by the code calling getTile. This is really bad it doesn't crash, so someone could post an issue on gmaps api issues.
Try to wrap call to getProjection in try-catch to see it.
Because you should not interact with GoogleMap outside of main thread, you will have to find another way to achieve, what you want to achieve...
Anyway, I can imagine no good reason for a need to call getProjection in getTile. Maybe another question describing your real problem?
Take accessing contacts in android
android.jar for versions 1.6 has People.CONTENT_URI for invoking contacts related info whereas in later versions we need to have api support for RawContacts.CONTENT_URI.
Same thing is true for accessing calendar for instance as its URI is changed in android 2.2.
Is there a best practice to manage all different changes without adding additional application or build separately for each version of changes?
For my money, a very good answer is at http://android-developers.blogspot.co.uk/2010/07/how-to-have-your-cupcake-and-eat-it-too.html. However, the example there is a little more complicated than need be, so based on that, here is an example of how to cope with it when building notifications. The underlying reason this works is a consequence of how java engines interpret classes: it only looks at them when needed, so if you wrap version specific code up in a class and only create it when you know you are using that version, it all works ...
There are, as far as I can tell, two generations of approaches to creating notification, and a naming change along the way in the second. So that gives three ways to do it. For each way, create a class with the notification generation in it:
The first approach (used through to Gingerbread):
public class MyNotificationBuilderToGingerBread {
Notification notification = null;
MyNotificationBuilderToGingerBread(Context myContext, int icon, String ticker, String title, String info, Long timeStamp, PendingIntent pendingIntent, int flags) {
notification = new Notification(R.drawable.ic_sb, ticker, timeStamp);
notification.setLatestEventInfo(myContext, title, info, pendingIntent);
notification.flags |= flags;
}
Notification get() {
return notification;
}
}
The second approach, Honeycomb to IceCreamSandwich:
public class MyNotificationBuilderHoneyCombToIceCreamSandwich {
Notification.Builder mb = null;
MyNotificationBuilderHoneyCombToIceCreamSandwich(Context myContext, int icon, String ticker, String title, String info, Long timeStamp, PendingIntent pendingIntent, boolean onGoing) {
mb = new Notification.Builder(myContext);
mb.setSmallIcon(icon);
mb.setContentIntent(pendingIntent);
mb.setContentTitle(title);
mb.setContentText(info);
mb.setWhen(timeStamp);
if (ticker != null) mb.setTicker(ticker);
mb.setOngoing(onGoing);
}
Notification get() {
return mb.getNotification();
}
}
The second generation, with the name change, Jellybean (onwards, so far ...):
public class MyNotificationBuilderJellyBean {
Notification.Builder mb = null;
MyNotificationBuilderJellyBean(Context myContext, int icon, String ticker, String title, String info, Long timeStamp, PendingIntent pendingIntent, boolean onGoing) {
mb = new Notification.Builder(myContext);
mb.setSmallIcon(icon);
mb.setContentIntent(pendingIntent);
mb.setContentTitle(title);
mb.setContentText(info);
mb.setWhen(timeStamp);
if (ticker != null) mb.setTicker(ticker);
mb.setOngoing(onGoing);
}
Notification get() {
return mb.build();
}
}
Then, you just need to pick which class to instantiate on the fly:
// System information
private final int sdkVersion = Build.VERSION.SDK_INT;
// If you want to go really old:
// (actually, there is a question about how this issue should be handled
// systematically. Suggestions welcome.)
// final int sdkVersion = Integer.parseInt(Build.VERSION.SDK);
// This is for a permanent notification. Change the final argument (flags or boolean) if it isn't meant ot be
// For meaning of other variable, see notification documentation on the android website.
if (sdkVersion < Build.VERSION_CODES.HONEYCOMB) {
MyNotificationBuilderToGingerBread mnb = new MyNotificationBuilderToGingerBread(myContext, R.drawable.notification_icon, ticketText, title, infoText, timeStampMillis, pendingIntentForTapOnFullNotitifcation, Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR);
notification = mnb.get();
}
else if (sdkVersion < Build.VERSION_CODES.JELLY_BEAN) {
MyNotificationBuilderHoneyCombToIceCreamSandwich mnb = new MyNotificationBuilderHoneyCombToIceCreamSandwich(myContext, R.drawable.notification_icon, ticketText, title, infoText, timeStampMillis, pendingIntentForTapOnFullNotitifcation, true);
notification = mnb.get();
}
else {
MyNotificationBuilderJellyBean mnb = new MyNotificationBuilderJellyBean(myContext, R.drawable.notification_icon, ticketText, title, infoText, timeStampMillis, pendingIntentForTapOnFullNotitifcation, true);
notification = mnb.get();
}
// Send the notification.
notificationManager.notify(idForNotificationManager, notification);
Hope this helps!
There are many resources for you to utilize to help support multiple versions of android.
Read this blog post here and
then read this one here, they
will help you address API level
version support issues.
Read this blog post on multiple
screen support, especially how the
asset hierarchy in parsed in res
folder. This will help you
understand and design how to do
asset folder structure to support
different screen size/densities and
android versions.
Lastly write your own custom ant build
scripts so that you can compile with
all versions of android.
Quite Honestly, it's a pain.
I usually, just isolate parts of code that are different and access them using abstract classes. So technically creating different version for different OS.
But there are other ways. The best one i've seen involves using reflection.
If you don't really need the new functionnalities, and really have to support old Android versions, drop it. Build your app for the oldest version, and don't bother with this kind of thing.
In the other case, you can detect the version using Build, and use reflection to load the classes you need. An example of that can be found in the source code of the K9Mail app
There's a nice article on android.com about it:
http://developer.android.com/resources/articles/backward-compatibility.html
Personally I would suggest the wrapper class or wrapper library solution. But in small cases the reflection should be fine (and in case performance is not a problem for you).
If you need more info, ask in comments.
This is a great article for when you have to do reflection in Android (to support multiple API levels).
And when you have to have different resources for different API Levels, this is the reference to use (see the section on "Platform Version (API level)").
If on Eclipse, from ADT version 17 you can specify code to run with some version simply as described in Lint API Check.
The code word is #TargetAPI(XX)
Hope it helps
Best practice (though not for Android, but for J2ME) to my knowledge is to use preprocessing C/C++ styled statements, like:
//#if S40
...
//#else
...
//#endif
Some IDE's support these kind of preprocessing, e.g. Netbeans. To my knowledge Eclipse has some plugins to enable preprocessing also. I don't really know are they applicable to Android development. Try to google yourself.