WP8 - Integrating Marketplace (Store) review with default 5 star - windows-phone-8

I've Implemented MarketplaceReviewTask into my Windows Phone 8 app.
(I know i can add Rate-My-App code which is pre-built library, but i wanted my own button for navigating user to the review page on store).
private void btnRageMe_Click(object sender, RoutedEventArgs e)
{
MarketplaceReviewTask oRateTask = new MarketplaceReviewTask();
oRateTask.Show();
}
When i've integrated "Rate-My-App" library into my app then the review page have default 5 stars selected.
now, when I'm integrating MarketplaceReviewTask then I can't find option to set default 5 star selected on the review page at the time of navigating there.
Any kind of help appreciated.

OK, I have just tried this with an app which I haven't rated before and I know it used Rate-My-App to bug me to rate it.
I selected 'Rate with 5 stars', the Store opened, and the 5 stars were NOT preselected.
I've also looked at the source code for the Rate-My-App quickly and found nothing that's setting the stars value.
My guess is that you already reviewed the app with 5 stars before, so when you opened the review task, it preselected the number of stars which was already submitted before, giving you the impression that it was predefined from inside the app.

Related

StoreContext.GetAppLicenseAsync().AddOnLicenses sometimes returns an empty list when the user has a license

I have an XBOX only app in the Microsoft Store that has been up for a while. The app has an add-on.
I use a very simple code to get the list of licenses in order to check if the user has add-on.
See below.
StoreAppLicense appLicense = await StoreContext.GetAppLicenseAsync();
var licenses = appLicense.AddOnLicenses.Select(item=> item.Value).ToList();
//Here I just save this in my log to see what is in the list
LogInfo("licenses: " + string.Join(',', licenses.Select(l => l.SkuStoreId).ToArray()));
Ok, so most of the time this code works fine. But there can be instances where the StoreAppLicense returns an empty list, even when the user HAS the license.
This has been a problem that has happened sometimes since I published the add-on, but was always fixed by reinstalling the app. Lately, even after a reinstall; the issue reappears.
What is worst, this even happened to me two days ago. I reinstalled the app and it worked fine; but after restarting the app it happened again. Then after some hours when I came back home it "solved itself".
I also have the suspicion that sometimes the StoreContext.GetAppLicenseAsync() method never returns and that causes the app to "hang".
Needless to say, customers get upset at me and give me bad reviews for something that is beyond my control.
What should I do in this situation? Can you even trust the StoreContext library?
Has someone seen this happening before?

App Widget getting hijacked by Google Sound Search?

So I'm seeing some bizarre behavior in an appwidget that I wrote.
The widget itself is quite simple - it reads a few values from persistent storage and then displays them as text. Nothing fancy in the layout - just a FrameLayout root element with some Linear Layout and TextView children.
The widget has a simple configuration activity associated with it.
The bizarre behavior is that the widget will initially show "Problem Loading Widget" after the user closes the configuration activity, and then after a few seconds it shows a "Google Sound Search" button (and clicking on the button actually does launch Google Sound Search). Then, after a few more seconds, it finally shows the expected display.
I am away from my code right now, so I'll have to wait until tonight to post code snippets. However, in the meantime, can anyone provide some insight into how such a thing could happen? Has anyone else ever experienced this? How could another widget "hijack" mine?
Thanks,
-Ron
Here are some screenshots:
There are a couple of issues with your widget and there are answers to all of them (although you didn't post any code so some of my statements are based on assumptions):
"Problem loading widget": this is the default view Android uses before the widget is initialized and the layout updated. Simply add the following line to your widget xml configuration (to show a loading message instead of the problem message):
android:initialLayout="#layout/my_cool_widget_loading_message"
If the widget shows the wrong layout then you probably have an issue in the widget's onReceive method. onReceive is called for all the widgets no matter whether the broadcast is for that specific widget. Android's AppWidgetProvider filters the broadcasts by appwidget Id and dispatches to the other methods (like onUpdate).
See also: https://developer.android.com/reference/android/appwidget/AppWidgetProvider.html#onReceive(android.content.Context, android.content.Intent).
If you override onReceive (which I assume you do), you need to call through to super.onReceive(Context, Intent) to make sure your other methods don't get calls meant for other widgets.
Now for the configuration of the widget. If you follow the Google documentation then it will all work nicely. The only improvement I'd do is what my other answer that you reference suggests (https://stackoverflow.com/a/14991479/534471). This will NOT send out two broadcasts. The setResult()/finish() part does only terminate the config Activity and let Android know whether to actually add the widget or not (depending on whether the result is RESULT_CANCELED or RESULT_OK.
From your own answer I can see why your code wouldn't work. The code is:
Intent intent = new Intent();
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {mAppWidgetId});
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, intent);
sendBroadcast(intent);
finish();
First of all there's no need to add the appWidgetId twice, use the AppWidgetManager.EXTRA_APPWIDGET_IDS version and you're good. Second you're using the same Intent to return as a result for the Activity. AFAIK it's not documented what happens when you do set an action on that Intent but my experience with Android widgets is that you need to stick exactly to the documentation or you'll end up having strange issues (like the ones you encounter). So please use two different Intents.
Activity result:
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
Broadcast:
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, this, MyWidget.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {mAppWidgetId});
sendBroadcast(intent);
ok, so I figured it out. Posting here in case anyone else runs into this. I think that the Android Developer docs are a little misleading here.
The problem was that in my configuration Activity, I had this code at the end:
Intent intent = new Intent();
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {mAppWidgetId});
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, intent);
sendBroadcast(intent);
finish();
Providing an intent with the extra EXTRA_APPWIDGET_ID is recommended by the documentation provided by google.
However, that same document says that you have to update the widget's view by creating a RemoteView and calling AppWidgetManager.updateAppWidget() like so:
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.example_appwidget);
appWidgetManager.updateAppWidget(mAppWidgetId, views);
I didn't like the idea of placing the presentation logic in both the configuration activity and the widget class, so I instead decided to broadcast an intent at the end of the configuration activity to tell the widget to redraw itself. That's why I have setResult() AND sendBroadcast() at the end of the activity. The documentation further states that the onUpdate() callback will not be called when using a configuration activity. So this seemed neccessary. I added the ACTION_APPWIDGET_UPDATE and the EXTRA_APPWIDGET_IDS to the intent so that it would trigger the onUpdate() method. This practice was recommended by this SO answer (albeit without being included in the activity result intent - but I tried separating the two and it had no effect).
Now I'm not certain exactly how the "Google Sound Search" widget got in there, nor do I fully understand the mechanics of how the intents interacted to produce the observed results. However, as soon as I replaced my code above with the code stated in the docs, the widget was updated properly.
Intent resultIntent = new Intent();
resultIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultIntent);
finish();
This seems to contradict the documentation's statement that the configuration activity must update the widget's view. Simply providing the configuration activity result as below triggers the onUpdate() method in the widget, thus allowing the widget to redraw itself. I confirmed the behavior on an emulator running API 23 and also on a Samsung device running Samsung's android flavor.

Windows Phone Custom URI

in my windows phone 8 application i am using custom uri association to launch another application through my phone.
i.e
await Windows.System.Launcher.LaunchUriAsync(new Uri("sixtag:"));
but my app is not able to get certified for store because of this. the testing team tells that you app terminates unexpectedly while executing this.
now, i don't know how to deal with this.
is there any way to throw exception if the app which i am launching is not installed on phone ?
or i should try something else so my task gets accomplished and app gets certified for store as well.
You do not need to wrap your launch in try/catch or check for success as described in the other answers. As soon as you call LaunchUriAsync, the platform takes over and will automatically handle the possibility of no app being installed by asking the user if she wishes to search in the store.
A couple of things to double-check:
1) Ensure that you can successfully back into your app following the navigation to sixtag.
2) Ensure that your call to LaunchUriAsync is the direct result of a user action (eg. tapping a button)
try
{
await Windows.System.Launcher.LaunchUriAsync(new Uri("sixtag:"));
}
catch
{
MessageBox.Show("please install Sixtag from the app store","AppMissing", MessageBoxButton.OK);
}
you can perhaps display another button and on clicking directly navigate to the app store. See if this solves your problem. Do vote it up if it does :)
You are needed to handle that as shown here . Also Read out Remarks given there.

WindowsPhone 8 (A jump to another application )FindPackagesForCurrentPublisher

string ProductId = "{23e1505b-9383-4ed4-9195-da23a3442820}";
IEnumerable<Package> app = Windows.Phone.Management.Deployment.InstallationManager.FindPackagesForCurrentPublisher();
app.First().Launch(ProductId);
this another app
WMAppManifest.xml(App xmlns="" ProductID="{23e1505b-9383-4ed4-9195-da23a3442820}"
Title="#TitleStrings\AppResLib.dll,-100" RuntimeType="Silverlight" Version="3.5.1.17"
Genre="apps.normal" Author="Tencent WeChat Limited" Description="Wed Feb 20 17:37:10 2013,
ChannelID 70" Publisher="Tencent WeChat Limited" IsBeta="false">)
When I trigger the event, it did not Launch (ProductId) I debugged, who can tell me. Did not run this step. How to jump to another application which used this method... thank you
Launch() doesn't take the product ID of the app you want to launch. Instead, it takes a query string that will passed along to the app you're launching, usually with a page reference.
What's probably happening is that the first app in app is actually the current app--the one that's making the call. It doesn't make any sense for an app to launch itself from within the app, so nothing happens.
Instead of calling First(), you should instead filter app so you can select the one that has a matching product ID. Look into Package.ID for details on how to do this.

How to capture unique user sessions in Webmatrix / Razor / ASP.NET Web Pages?

I need to log unique user sessions in Webmatrix / Razor / ASP.NET Web Pages. Does _appstart fire just when the app spins up the first time in IIS or does it fire once per unique user hit? If just once, how do I capture unique user sessions & settings?
UPDATE: I wasn't sure if the Global.asax events were fired under Razor / ASP.NET WebPages. I tested it out and the Session_Start event fires just fine. Question resolved.
void Session_Start(object sender, EventArgs e)
{
// Code that runs when a new session is started
Dictionary<DateTime, String> d = new Dictionary<DateTime, String>();
Application.Lock();
if (Application["d"] != null)
{
d = (Dictionary<DateTime, String>)Application["d"];
}
d.Add(DateTime.Now, HttpContext.Current.Session.SessionID);
Application["d"] = d;
Application.UnLock();
}
To directly answer your question, _AppStart runs when the first user hits your site. Future users to the site do NOT cause _AppStart to run. There is no specific page or place to put code that runs for each unique user.
What you want to do is take a look at the ASP.Net Session object. In your page, you can store and retrieve data from Session like so:
#{
// Retrieve
var someSetting = Session["SomeSetting"]
// Store
Session["SomeSetting"] = someSetting;
}
ASP.Net will take care of making sure that the setting is stored per-browser-instance using Session Cookies. Note that if you're in a Web Farm environment, you'll need something more robust, but when you're talking about a single server, this should be fine.
If you want some more info, here's the official documentation for ASP.Net Session State: http://msdn.microsoft.com/en-us/library/ms178581.aspx
You have asked about logging "unique user sessions", which is a little confusing. All sessions are unique, but not all sessions belong to unique visitors. Returning visitors will start new sessions. If you want to keep a count of sessions, you can hook into the Session_Start event in Global.asax. If you want to count unique visitors, use cookies. Set them when a user visits if one hasn't already got a cookie. Ensure that their expiry is some time well into the future. If the visitor hasn't got a tracking cookie for your site, they must be new (or they might have deleted their cookie...)