Xamarin In App Billing Component Not Connecting To Google Play - xamarin.android

I have went through the Xamarin IAB 'tutorial' on it's Component page. I installed the component and Google Play Billing Lib into my app, published my apk to Google Play Dev Console in Alpha and added products on the Dev Console to the app. However, when I try to test the app on a phone, anytime I click on any of the purchase buttons nothing happens. The buttons themselves worked fine I have tested them by pushing other notifications, changing colors, etc. They work with everything else, but when it comes to purchasing nothing happens, no pop-ups, no buffering or attempt to connection, literally nothing. I think my app never connects to Google Play, and I have no idea why.
My Main Activity
private InAppBillingServiceConnection _serviceConnection;
private string publicKey = "my public key";
private IList<Product> _products;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Establish Connection to Google Play Store
_serviceConnection = new InAppBillingServiceConnection(this, publicKey);
_serviceConnection.OnConnected += async () =>
{
// Load available products and any purchases
await RequestProducts();
};
// Attempt to connect to the service
_serviceConnection.Connect();
IAPHelper.Instance.Initalize(_products, _serviceConnection);
var g = new Game1();
SetContentView(g.Services.GetService<View>());
g.Run();
}
// Request a list of available products that the user can purchase by providing alist of
protected async Task RequestProducts()
{
_products = await _serviceConnection.BillingHandler.QueryInventoryAsync(new List<string>{
ReservedTestProductIDs.Purchased,
ReservedTestProductIDs.Canceled,
ReservedTestProductIDs.Refunded,
ReservedTestProductIDs.Unavailable
}, ItemType.Product);
// Were any products returned?
if (_products == null)
{
// No, abort
return;
}
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
My Helper Method
private IList<Product> _products;
private InAppBillingServiceConnection _serviceConnection;
public void Initalize(IList<Product> _products, InAppBillingServiceConnection _serviceConnection)
{
this._products = _products;
this._serviceConnection = _serviceConnection;
}
// Called when a product is clicked to buy
public bool ProductPurchasing(string id)
{
Product _selectedProduct = null;
try
{
for (int i = 0; i < _products.Count; i++)
{
if (id == _products[i].ProductId)
{
_selectedProduct = _products[i];
break;
}
}
_serviceConnection.BillingHandler.BuyProduct(_selectedProduct);
return true;
}
catch (Exception ex)
{
return false;
}
}

Related

Launching the application from an url in the browser for BlackBerry?

I am developing one application where i will launch a url in the browser from which i will launch my application.
Suppose if i will click google.com, and press enter, it will launch my application. For that i tried with the HttpFilterRegistry API.
For reference i am using the HTTPFilterDemo application. But currently while launching the app, i am getting the NullPointerException.
I wrote the below code i the openFilter Method:
public Connection openFilter(String name, int mode, boolean timeouts) throws IOException {
Logger.out("Protocol", "it is inside the openFilter method");
_url = name.substring(2);
_requestHeaders = new HttpHeaders();
_responseHeaders = new HttpHeaders();
_responseHeaders.setProperty(HttpProtocolConstants.HEADER_CONTENT_TYPE, "text/html");
Logger.out("Protocol", "here it is come ::::44444444");
final int modHandle = CodeModuleManager.getModuleHandle("AppLaunchBrowser");
Logger.out("Protocol", "here is the module handle:::" + modHandle);
final ApplicationDescriptor[] apDes = CodeModuleManager.getApplicationDescriptors(modHandle);
final ApplicationDescriptor appDescriptor = new ApplicationDescriptor(apDes[0], new String[] {});
Logger.out("Protocol", "here is the app descriptor:::" + appDescriptor);
try {
final int appCode = ApplicationManager.getApplicationManager().runApplication(appDescriptor, true);
Logger.out("Protocol", "here is the app code:::" + appCode);
} catch (ApplicationManagerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// }
return this;
}
And in the application class i am creating alternative entry point and using like below:
public class AppLaunch extends UiApplication{
public static void main(String args[])
{
Logger.out("AppLaunch", args+"length of the arguments::::" +args.length);
if((args != null) && (args.length > 0) && (args[0].equals("background")))
{
Logger.out("AppLaunch", "in the alternate entry point");
// Logger.out("AppLaunch", args+"length of the arguments::::" +args.length);
HttpFilterRegistry.registerFilter("www.google.co.in", "com.innominds.ca", false);
}
else
{
Logger.out("AppLaunch", "Inside the Applaunch");
AppLaunch theApp = new AppLaunch();
theApp.requestForeground();
Logger.out("AppLaunch", "created the app launch object");
theApp.enterEventDispatcher();
// Logger.out("AppLaunch", "in the alternate entry point");
// HttpFilterRegistry.registerFilter("www.google.co.in", "com.innominds.ca", false);
}
}
public AppLaunch()
{
checkPermissions();
showTestScreen();
}
private void checkPermissions()
{
ApplicationPermissionsManager apm = ApplicationPermissionsManager.getInstance();
ApplicationPermissions original = apm.getApplicationPermissions();
if(original.getPermission(ApplicationPermissions.PERMISSION_BROWSER_FILTER) == ApplicationPermissions.VALUE_ALLOW)
{
// All of the necessary permissions are currently available
return;
}
ApplicationPermissions permRequest = new ApplicationPermissions();
permRequest.addPermission(ApplicationPermissions.PERMISSION_BROWSER_FILTER);
boolean acceptance = ApplicationPermissionsManager.getInstance().invokePermissionsRequest(permRequest);
if(acceptance)
{
// User has accepted all of the permissions
return;
}
else
{
}
}
private void showTestScreen()
{
UiApplication.getUiApplication().pushScreen(new AppLaunchScreen());
}
}
Finally i was able to resolve this issue. Actually NPE is coming in some other callback methods because i was implementing the FilterBaseInterface.

previous instance still active error in blackberry

I created app which user can start from menu and from icon. I do not use GlobalEventListener in my app, just register ApplicationMenuitem. And now I am getting error: previous instance still active when launch my app.
Steps to reproduce not so trivial:
launch app from icon
do not close it, just switch to another app
launch app from icon again
I founded article in blackberry's forum about it , but I can't find solution where I should remove my ApplicationMenuItem: it added on phone boot and should show all the time.
My code:
public class Jingu extends UiApplication {
public static void main(String[] args) {
ApplicationManager app = ApplicationManager.getApplicationManager();
boolean keepGoing = true;
while (keepGoing) {
if (app.inStartup()) {
try {
Thread.sleep(1000);
} catch (Exception e) {}
} else {
keepGoing = false;
}
}
Jingu theApp = new Jingu();
theApp.initMenuItem();
theApp.showMainScreen();
theApp.enterEventDispatcher();
}
public Jingu() {
}
public void showMainScreen() {
showScreen(new JinguMainScreen(this));
}
public void initMenuItem() {
// Create menu item
Object o = RuntimeStore.getRuntimeStore().get(JinguMenuItem.MY_MENU_ID);
// register only if not done already.
if (o == null) {
new JinguMenuItem(this).registerInstance();
}
}
public void showScreen(Screen aScreen) {
synchronized (Application.getEventLock()) {
try {
UiApplication.getUiApplication().popScreen(aScreen);
} catch (Exception e) {
}
UiApplication.getUiApplication().pushScreen(aScreen);
}
}
}
public class JinguMenuItem extends ApplicationMenuItem {
public static final long MY_MENU_ID = 0xb9739d5240d5943dL;
private final Jingu jingu;
public JinguMenuItem(Jingu jingu) {
super(0x350100);
this.jingu = jingu;
}
public void registerInstance() {
Object menuItem = RuntimeStore.getRuntimeStore().remove(MY_MENU_ID);
if (menuItem == null) {
ApplicationMenuItemRepository amir = ApplicationMenuItemRepository.getInstance();
amir.addMenuItem(ApplicationMenuItemRepository.MENUITEM_SYSTEM, this);
RuntimeStore.getRuntimeStore().put(MY_MENU_ID, this);
}
}
public Object run(Object context) {
jingu.setDefaultFont(Font.getDefault());
jingu.setMainApp(false);
jingu.setBbmEditField(null);
jingu.showMainScreen();
return context;
}
public String toString() {
return "My Menu";
}
}
plz advice where I should delete ApplicationMenuItem in my app?
my regards,
Vadim
If you are registering an ApplicationMenuItem from your application, as a user I would consider it bad style for your application to remove and exit, even if RIM provided a way to do this. You may want to separate your application into two parts. One provides the minimal support for responding to the ApplicationMenuItem selection, that starts automatically and runs in the background. The other has all the rest and can run and exit as needed.
My solution for this situation is:
create alternative entry point and run it on app load
register menu in it
do not use runtimeStore

Twitter Follow Link

How do I create a link that will automatically make a user follow a certain Twitter user if they're logged in or send them to Twitter to login first if they're not? I had found how to do this about month or 2 ago but can't find it again. I think it was something basic like a link or a form post to something like twitter.com/[user]/follow.
I've looked at the API, but I'd need the user to authenticate themselves on my site, and I don't want to deal with that. I just want them to authenticate directly on Twitter and not worry about it. The way I had found was nice and simple and I just want to find that again.
Use Twitter's web intents.
While you can use the follow button, you can also send users directly to the Intent URL, like so:
https://twitter.com/intent/user?screen_name=NASA
how to use twitter api in my android application to implement follow button only
Android
http://code.google.com/p/android-hackathon-in-fukuoka/source/browse/trunk/sodefuri/src/jp/jagfukuoka/sodefuri/TimeLineActivity.java?spec=svn167&r=167
Code Snip: (I have converted chines string into standard English)
public class TimeLineActivity extends ListActivity {
private TwitterPreferenceManager tpm = new TwitterPreferenceManager(this);
private static final int FOLLOW = 1;
private static final CharSequence FOLLOW_LABEL = "Follow";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// timeline Obtaining process
String screenName = getIntent().getStringExtra("screen_name");
List<String> list = this.getTimeLine(screenName);
setListAdapter(new ArrayAdapter<String>(this, R.layout.timeline_item,list));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, FOLLOW, 0, FOLLOW_LABEL);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case FOLLOW:
ConfigurationBuilder builder = new ConfigurationBuilder();
Configuration conf = builder.setOAuthAccessToken(tpm.getAccessToken())
.setOAuthAccessTokenSecret(tpm.getAccessTokenSercret())
.setOAuthConsumerKey(TwitterPreferenceManager.CONSUMER_KEY)
.setOAuthConsumerSecret(TwitterPreferenceManager.CONSUMER_SERCRET)
.setDebugEnabled(true)
.build();
Twitter twitter = new TwitterFactory(conf).getInstance();
try {
String screen_name = getIntent().getStringExtra("screen_name");
twitter.createFriendship(screen_name);
Toast.makeText(getApplicationContext(), "Was to follow.", Toast.LENGTH_LONG).show();
} catch (TwitterException e) {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
/**
* Get the time line for the specified user
*
* #param screenName
* #return
*/
private List<String> getTimeLine(String screenName) {
List<String> result = new ArrayList<String>();
Twitter twitter = new TwitterFactory().getInstance();
ResponseList<Status> userTimeline;
try {
userTimeline = twitter.getUserTimeline(screenName);
for (Status status : userTimeline) {
result.add(status.getText());
}
} catch (TwitterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
}
iPhone
http://www.chrismaddern.com/twitter-follow-button-for-ios-iphone-code/
Here is the way, How todo
The FollowMeButton can be created in Interface Builder by adding a UIButton and changing it's class to FollowMeButton or in code using the custom initialiser:
[self.view addSubview:[[FollowMeButton alloc] initWithTwitterAccount:#"chrismaddern" atOrigin:CGPointMake(205, 248) isSmallButton:YES]];
Two size modes are available controlled by setting isSmallButton in the initialiser or by later change the isSmall property of the object.

Create an application which will lock another application event

Actually I want to make an application which will getGlobalEvent and control that event through another custom application. Is there any way to do so. Can i get global event from a particular application? Its like an application which will lock custom application in your blackberry, if you add following application in that locking app list and put password to access then when u try to open that application, it will ask for a password which u set in the locking app.
Common advices
this should be background application
in timer thread check current foreground application
use custom global modal dialog to request password
if password was wrong close app by simulating back key press or move app to background
Checking Application
Have to say, there can be several processes within one application so we will perform check based on module name:
private String getModuleNameByProcessId(int id) {
String result = null;
ApplicationManager appMan = ApplicationManager.getApplicationManager();
ApplicationDescriptor appDes[] = appMan.getVisibleApplications();
for (int i = 0; i < appDes.length; i++) {
if (appMan.getProcessId(appDes[i]) == id) {
result = appDes[i].getModuleName();
break;
}
}
return result;
}
Move application to Background?
Yep, there's no requestBackground() in ApplicationManager... so what you can do is requestForeground() on the next best app which is not on foreground, and this will move active app to background! You can even bring up Home Screen with requestForegroundForConsole():
protected int switchForegroundModule() {
int id = -1;
ApplicationManager appMan = ApplicationManager.getApplicationManager();
ApplicationDescriptor appDes[] = appMan.getVisibleApplications();
for (int i = 0; i < appDes.length; i++) {
if (!appDes[i].getModuleName().equalsIgnoreCase(STR_MODULE_NAME)) {
id = appMan.getProcessId(appDes[i]);
appMan.requestForeground(id);
// give a time to foreground application
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
}
return id;
}
Global Dialog
Just to input password you can extend Dialog, it will be easier to consume result:
class PaswordDialog extends Dialog {
private BasicEditField mPwdField = new BasicEditField();
public PaswordDialog() {
super(Dialog.D_OK_CANCEL, "Enter password", Dialog.CANCEL, null,
Dialog.FIELD_HCENTER);
add(mPwdField);
}
public String getPassword() {
return mPwdField.getText();
}
}
And password check will look like:
private boolean checkPassword() {
boolean result = false;
final PaswordDialog pwdDlg = new PaswordDialog();
invokeAndWait(new Runnable() {
public void run() {
Ui.getUiEngine().pushGlobalScreen(pwdDlg, 0,
UiEngine.GLOBAL_MODAL);
}
});
result = ((Dialog.OK == pwdDlg.getSelectedValue()) && pwdDlg
.getPassword().equalsIgnoreCase(STR_PASSWORD));
return result;
}
Put this all together
Sample to block Adress Book App:
public class LockMainApp extends Application {
private static final String STR_MODULE_NAME = "net_rim_bb_addressbook_app";
private static final String STR_PASSWORD = "12345";
int mFGProcessId = -1;
public LockMainApp() {
Timer timer = new Timer();
timer.schedule(mCheckForeground, 1000, 1000);
}
public static void main(String[] args) {
LockMainApp app = new LockMainApp();
app.enterEventDispatcher();
}
TimerTask mCheckForeground = new TimerTask() {
public void run() {
int id = ApplicationManager
.getApplicationManager().getForegroundProcessId();
if (id != mFGProcessId) {
mFGProcessId= id;
String moduleName = getModuleNameByProcessId(mFGProcessId);
if (moduleName.equalsIgnoreCase(STR_MODULE_NAME)) {
if (!checkPassword())
mFGProcessId = switchForegroundModule();
}
}
};
};
}

BlackBerry - Simulate a KeyPress event

I have a BlackBerry application that needs to take pictures from the camera and send them to a server. In order to do this i invoke the native camera application and listen to the filesystem. Once an image is captured and saved as a new jpeg file i get notified, resume foreground control and go about my business. The problem starts occurring after the first time this cycle is completed because now when i decide to call the camera application again it is already opened, and now the user is seeing a thumbnail of the last picture that was taken and several buttons allowing him to manipulate/manage it. naturally what i want the user to see is a preview of what the camera is "seeing" before he snaps another photo as he did before.
I have thought of various ways to solve this including killing the camera app each time (I understand this cannot be done programatically?), sending CameraArguments when invoking the app (which appears to be useless), and now i was thinking a solution could be as simple generating a "Back" key event before switching back to my app which would theoretically dismiss the annoying edit screen. Could this really be done? and if not is there any other possible solution you may think of?
A kind of hack...
start Camera App
in TimerTask check if Camera App started and if it need to be closed (some flag)
if yes, invoke it(so it will became active) and push ESC keypress event injection to close it
Take a look at this:
class Scr extends MainScreen {
boolean killCameraApp = false;
final String mCameraModuleName = "net_rim_bb_camera";
final CameraArguments args = new CameraArguments();
public Scr() {
super();
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
if (isCameraRunning() && killCameraApp) {
getApplication().invokeAndWait(callCamera);
getApplication().invokeAndWait(killCamera);
}
}
}, 0, 100);
}
Runnable callCamera = new Runnable() {
public void run() {
callCamera();
}
};
Runnable killCamera = new Runnable() {
public void run() {
injectKey(Characters.ESCAPE);
killCameraApp = false;
}
};
private boolean isCameraRunning() {
boolean result = false;
ApplicationManager appMan =
ApplicationManager.getApplicationManager();
ApplicationDescriptor[] appDes = appMan.getVisibleApplications();
for (int i = 0; i < appDes.length; i++) {
result = mCameraModuleName.equalsIgnoreCase(appDes[i]
.getModuleName());
if (result)
break;
}
return result;
}
private void callCamera() {
Invoke.invokeApplication(Invoke.APP_TYPE_CAMERA,
new CameraArguments());
}
private void injectKey(char key) {
KeyEvent inject = new KeyEvent(KeyEvent.KEY_DOWN, key, 0);
inject.post();
}
protected void makeMenu(Menu menu, int instance) {
menu.add(new MenuItem("start camera", 0, 0) {
public void run() {
callCamera();
killCameraApp = false;
}
});
menu.add(new MenuItem("kill app", 0, 0) {
public void run() {
killCameraApp = true;
}
});
super.makeMenu(menu, instance);
}
}
EDIT: Don't forget to set permissions for device release:
Options => Advanced Options => Applications => [Your Application] =>Edit Default permissions =>Interactions =>key stroke Injection

Resources