Categories
discuss

When to request permissions with Facebook’s new Android SDK 3.0?

With Facebook’s new Android SDK 3.0 (that was released a few days ago), the process of authentication has changed.

So how do you request a read permission such as “friends_hometown”?

The following code is how I am trying to do it – but I’m quite sure it’s not the way you should do this:

Version 1:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Session.openActiveSession(this, true, new Session.StatusCallback() { // start Facebook login
        @Override
        public void call(Session session, SessionState state, Exception exception) { // callback for session state changes
            if (session.isOpened()) {
                List<String> permissions = new ArrayList<String>();
                permissions.add("friends_hometown");
                session.requestNewReadPermissions(new Session.NewPermissionsRequest(FBImport.this, permissions));
                Request.executeGraphPathRequestAsync(session, "me/friends/?access_token="+session.getAccessToken()+"&fields=id,name,hometown", new Request.Callback() {
                    ...
                });
            }
        }
    });
}

Version 2:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Session currentSession = Session.getActiveSession();
    if (currentSession == null || currentSession.getState().isClosed()) {
        Session session = Session.openActiveSession(this, true, fbStatusCallback); // PROBLEM: NO PERMISSIONS YET BUT CALLBACK IS EXECUTED ON OPEN
        currentSession = session;
    }
    if (currentSession != null && !currentSession.isOpened()) {
        OpenRequest openRequest = new OpenRequest(this).setCallback(fbStatusCallback); // HERE IT IS OKAY TO EXECUTE THE CALLBACK BECAUSE WE'VE GOT THE PERMISSIONS
        if (openRequest != null) {
            openRequest.setDefaultAudience(SessionDefaultAudience.FRIENDS);
            openRequest.setPermissions(Arrays.asList("friends_hometown"));
            openRequest.setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);
            currentSession.openForRead(openRequest);
        }
    }
}

What I’m doing is to request the permission as soon as the session is open – but at this point the code is already starting a Graph API request, thus the permission request comes to late …

Can’t you request a permission at the same time you initialize the session?

Answer

I recommend that you read our login tutorial here specifically in step 3. Using the login button that we provide is the most convenient method, (see authButton.setReadPermissions())

EDIT:

To set permissions without using the loginbutton is trickier since you will have to do all the session management by hand. Digging into the source code for the login button, this line of code is probably what you need. It looks like you will need to create your own Session.OpenRequest and set it’s attributes such as permissions, audience, and login behavior, then get the current session and call openForRead() on your Session.OpenRequest.

Categories
discuss

In-App Billing test: android.test.purchased already owned

I am currently testing In-App Billing for a future app, and after I successfully “bought” the test item “android.test.purchased” the first time, I now receive the response code 7 every time I try to buy it again, which means that I already own this item.

12-15 23:02:14.149: E/IabHelper(19829): In-app billing error: Unable
to buy item, Error response: 7:Item Already Owned

From what I understand, this purchase is supposed to always be possible, right? So that the developer can test his/her app?

If not, how can I “reset” its state to not owned? I am using the util package from the Google In-App Billing Sample.

Answer

It turns out that the android.test.purchased item behaves like a regular ID. It means that if you want be able to buy it again, you have to consume it somewhere in your code. I think that the Google documentation is misleading on this matter, and that they should add another static ID that you can buy endlessly for test purposes.

Categories
discuss

Why does writeObject throw java.io.NotSerializableException and how do I fix it?

I have this exception and I don’t understand why it would be thrown or, how I should handle it.

try {
    os.writeObject(element);
} catch (IOException e) {
    e.printStackTrace();
}

Where element is a TransformGroup containing some other TransformGroups an instance of the class Atom:

public class Atom extends Group implements Serializable{
    float pozX,pozY;
    Group group= new Group();   
    Color3f blue = new Color3f(new Color(255));
    Color3f black = new Color3f(new Color(0));
    Sphere AtSph=new Sphere();

    public Atom(final float WEIGHT, final int BOUNDS,final float radius,Color3f color)
    {
        AppSetting ap= new AppSetting(color, black);
        AtSph=new Sphere(radius,1,100,ap);
    }
}

The full error log:

java.io.NotSerializableException: javax.media.j3d.TransformGroup
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at cls.MolecularBuilder.addAtom(MolecularBuilder.java:511)
    at cls.MolecularBuilder$Console.HidrogenItemActionPerformed(MolecularBuilder.java:897)
    at cls.MolecularBuilder$Console$2.actionPerformed(MolecularBuilder.java:746)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    at javax.swing.AbstractButton.doClick(Unknown Source)
    at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
    at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

AppSetting (in Atom class) is just a custom class that extends Appearance.

Answer

The fields of your object have in turn their fields, some of which do not implement Serializable. In your case the offending class is TransformGroup. How to solve it?

  • if the class is yours, make it Serializable
  • if the class is 3rd party, but you don’t need it in the serialized form, mark the field as transient
  • if you need its data and it’s third party, consider other means of serialization, like JSON, XML, BSON, MessagePack, etc. where you can get 3rd party objects serialized without modifying their definitions.
Categories
discuss

What does the ic_launcher-web.png in my project root do?

Unbelievably enough, I couldn’t find an answer when Googling for this very basic question!

I noticed that since I upgraded from Eclipse Helios to Eclipse Juno and updated the Android SDK, Eclipse places a file called ic_launcher-web.png in the project root whenever I create a new Android project. The file is the same as the application icon selected in the project creation dialog, but what does it do? As mentioned, it’s in the project root, not in any of the /res/ folders. So is it included in the finished .apk file, and what is it’s purpose?

Answer

It’s for the Play Store, which accepts 512×512 high-resolution icons:

  • High Resolution Application Icon (Required):
    • Use: In various locations in Google Play.
    • Specs: 512×512, 32-bit PNG with alpha; Max size of 1024KB.

— Google Support

(A more tutorial like explanation can be found here.)

It is not used in your actual app or the launcher, so it is not packaged in the APK.

Categories
discuss

primitive-boolean To String concatenation/conversion

how does this work? I can’t seem to find an answer.

boolean bool=true;
System.out.println("the value of bool is : " + true);
//or
System.out.println("the value of bool is : " + bool);
  • What are the things that are going on behind the scene?
  • how does the boolean gets casted to the String as a boolean cannot be implicitly type casted?
  • Is Autoboxing/Unboxing involved?
  • Are methods like toString() or String.valueOf() are involved in some way?

Answer

The exact rules are spelled out in the Java Language Specification, §5.1.11. String Conversion

According to those rules, "str" + bool is equivalent to:

"str" + new Boolean(bool).toString()

That said, the compiler is permitted considerable leeway in how exactly the overall expression is evaluated. From JLS §15.18.1. String Concatenation Operator +:

An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.

For primitive types, an implementation may also optimize away the creation of a wrapper object by converting directly from a primitive type to a string.

For example, with my compiler the following:

boolean bool = true;
System.out.println("the value of bool is : " + bool);

is exactly equivalent to:

boolean bool = true;
System.out.println(new StringBuilder("the value of bool is : ").append(bool).toString());

They result in identical bytecodes:

Code:
   0: iconst_1      
   1: istore_1      
   2: getstatic     #59                 // Field java/lang/System.out:Ljava/io/PrintStream;
   5: new           #166                // class java/lang/StringBuilder
   8: dup           
   9: ldc           #168                // String the value of bool is : 
  11: invokespecial #170                // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
  14: iload_1       
  15: invokevirtual #172                // Method java/lang/StringBuilder.append:(Z)Ljava/lang/StringBuilder;
  18: invokevirtual #176                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
  21: invokevirtual #69                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
  24: return        
Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..