Categories
discuss

How to calculate the size of a file in Android

I am looking to find the size of a file in Android. I originally expected it to be as simple as a size() method in File, or something along those lines. But I haven’t been able to find anything. Any help would be greatly appreciated.

Thanks

Answer

Use file.length()

http://download.oracle.com/javase/6/docs/api/java/io/File.html#length%28%29

The length, in bytes, of the file
denoted by this abstract pathname, or
0L if the file does not exist. Some
operating systems may return 0L for
pathnames denoting system-dependent
entities such as devices or pipes.

Categories
discuss

SystemClock.sleep() vs. Thread.sleep() while waiting for a semaphore loop

In order to synchronize/queue access to a shared resource, I am about to use a Semaphore, aided by a wait loop.

In order not to run into CPU pegging, I would like to sleep() a little bit inside that while loop.

I searched the http://developer.android.com reference and found two such sleep() functions and I am confused as to which one fits which scenario:

  1. Thread.sleep()
  2. SystemClock.sleep()

Which one better suits the case I described and why?

Answer

First of all, do you really need a wait loop? You can typically solve your problems using proper notifications, i.e. having an Object, calling wait() and notify() on it or other means (like a blocking queue, or Semaphore.acquire() in your case).

That said, if you really want a polling loop (which you really shouldn’t do unless you have to), I’d stick with Thread.sleep(). There’s not much of a difference, as the documentation says, except that you have the option to interrupt a Thread.sleep(). Don’t rid yourself the option to do so.

Note that in case of Thread.sleep(), you’re going to have to catch that exception – if you’re extremely lazy, you’ll probably stick with SystemClock.sleep().

Categories
discuss

google maps marker as link api v3

how to add links to the markers to open new pages with target=”_self”, i found some examples but i dont know how to use it in my code, do help me pls

<script type="text/javascript">   

            var mapa; // obiekt globalny

            function dodajMarker(opcjeMarkera)
            {
                opcjeMarkera.map = mapa;
                var marker = new google.maps.Marker(opcjeMarkera);
            }

            function mapaStart()  
            {  
                var wspolrzedne = new google.maps.LatLng(58.699776,16.984863);
                var opcjeMapy = {
                    zoom: 6,
                    center: wspolrzedne,
                    mapTypeId: google.maps.MapTypeId.TERRAIN,
                    disableDefaultUI: true,
                    navigationControl: true, // kontrolka nawigacji
    navigationControlOptions:
    {
        style: google.maps.NavigationControlStyle.SMALL 
    }
                };
                mapa = new google.maps.Map(document.getElementById("mapka"), opcjeMapy);

                // wspólne cechy ikon
                var rozmiar = new google.maps.Size(32,32);
                var rozmiar_cien = new google.maps.Size(59,32);
                var punkt_startowy = new google.maps.Point(0,0);
                var punkt_zaczepienia = new google.maps.Point(16,16);

                // ikonki
                var ikona1 = new google.maps.MarkerImage("markers/marker1.png", rozmiar, punkt_startowy, punkt_zaczepienia);
                var ikona2 = new google.maps.MarkerImage("markers/marker2.png", rozmiar, punkt_startowy, punkt_zaczepienia);
                var ikona3 = new google.maps.MarkerImage("markers/marker3.png", rozmiar, punkt_startowy, punkt_zaczepienia);
                var ikona4 = new google.maps.MarkerImage("markers/marker4.png", rozmiar, punkt_startowy, punkt_zaczepienia);
                var ikona5 = new google.maps.MarkerImage("markers/marker5.png", rozmiar, punkt_startowy, punkt_zaczepienia);
                var ikona6 = new google.maps.MarkerImage("markers/marker6.png", rozmiar, punkt_startowy, punkt_zaczepienia);


                var cien1 = new google.maps.MarkerImage("http://www.google.com/intl/en_ALL/mapfiles/shadow50.png", rozmiar_cien, punkt_startowy, punkt_zaczepienia);

                dodajMarker({position: new google.maps.LatLng(58.203148,16.601637), icon: ikona1, shadow: cien1});
                dodajMarker({position: new google.maps.LatLng(58.3902,16.7202),  icon: ikona2, shadow: cien1});
                dodajMarker({position: new google.maps.LatLng(58.566667,15.166667),  icon: ikona3, shadow: cien1});
                dodajMarker({position: new google.maps.LatLng(58.488553,16.928773), icon: ikona4, shadow: cien1 });
                dodajMarker({position: new google.maps.LatLng(57.899804,16.408064),  icon: ikona5, shadow: cien1});
                dodajMarker({position: new google.maps.LatLng(57.951087,16.55972),  icon: ikona6, shadow: cien1});
                }



        </script> 

does the first marker should look like this ?? where to put url ??

function dodajMarker({position: new google.maps.LatLng(58.203148,16.601637), icon: ikona1, shadow: cien1})
                {
                    opcjeMarkera.map = mapa;
                    var marker = new google.maps.Marker({position: new google.maps.LatLng(58.203148,16.601637), icon: ikona1, shadow: cien1});
                    google.maps.event.addListener(marker, 'click', function() {
                        window.location.href = marker.url;
                    });

                }

this is my code and it dosent work

<script type="text/javascript">   
        <!-- 
            var mapa; // obiekt globalny

            function dodajMarker(opcjeMarkera)
            {
                opcjeMarkera.map = mapa;
                var marker = new google.maps.Marker(opcjeMarkera);
            }

            function mapaStart()  
            {  
                var wspolrzedne = new google.maps.LatLng(58.699776,16.984863);
                var opcjeMapy = {
                    zoom: 6,
                    center: wspolrzedne,
                    mapTypeId: google.maps.MapTypeId.TERRAIN,
                    disableDefaultUI: true,
                    navigationControl: true, // kontrolka nawigacji
    navigationControlOptions:
    {
        style: google.maps.NavigationControlStyle.SMALL 
    }
                };
                mapa = new google.maps.Map(document.getElementById("mapka"), opcjeMapy);

                // wspólne cechy ikon
                var rozmiar = new google.maps.Size(32,32);
                var rozmiar_cien = new google.maps.Size(59,32);
                var punkt_startowy = new google.maps.Point(0,0);
                var punkt_zaczepienia = new google.maps.Point(16,16);

                // ikonki
                var ikona1 = new google.maps.MarkerImage("markers/marker1.png", rozmiar, punkt_startowy, punkt_zaczepienia);
                var ikona2 = new google.maps.MarkerImage("markers/marker2.png", rozmiar, punkt_startowy, punkt_zaczepienia);
                var ikona3 = new google.maps.MarkerImage("markers/marker3.png", rozmiar, punkt_startowy, punkt_zaczepienia);
                var ikona4 = new google.maps.MarkerImage("markers/marker4.png", rozmiar, punkt_startowy, punkt_zaczepienia);
                var ikona5 = new google.maps.MarkerImage("markers/marker5.png", rozmiar, punkt_startowy, punkt_zaczepienia);
                var ikona6 = new google.maps.MarkerImage("markers/marker6.png", rozmiar, punkt_startowy, punkt_zaczepienia);


                var cien1 = new google.maps.MarkerImage("http://www.google.com/intl/en_ALL/mapfiles/shadow50.png", rozmiar_cien, punkt_startowy, punkt_zaczepienia);

                dodajMarker({position: new google.maps.LatLng(58.203148,16.601637), icon: ikona1, shadow: cien1, url:'http://www.google.com'});
                dodajMarker({position: new google.maps.LatLng(58.3902,16.7202),  icon: ikona2, shadow: cien1, url:'http://www.google.com'});
                dodajMarker({position: new google.maps.LatLng(58.566667,15.166667),  icon: ikona3, shadow: cien1, url:'http://www.google.com'});
                dodajMarker({position: new google.maps.LatLng(58.488553,16.928773), icon: ikona4, shadow: cien1, url:'http://www.google.com' });
                dodajMarker({position: new google.maps.LatLng(57.899804,16.408064),  icon: ikona5, shadow: cien1, url:'http://www.google.com'});
                dodajMarker({position: new google.maps.LatLng(57.951087,16.55972),  icon: ikona6, shadow: cien1, url:'http://www.google.com'});
                }
        -->
        </script>

Answer

You could do something like this.

var marker = new google.maps.Marker({
  url: 'http://www.google.com/',
  map: map
});

google.maps.event.addListener(marker, 'click', function() {
  window.location.href = marker.url;
});

Code untested… just thinking out loud!

To fit it in with your existing code…

        function dodajMarker(opcjeMarkera)
        {
            opcjeMarkera.map = mapa;
            var marker = new google.maps.Marker(opcjeMarkera);
            google.maps.event.addListener(marker, 'click', function() {
                window.location.href = marker.url;
            });

        }

The main thing to note is the marker variable is referenced again in the addListener function.

dodajMarker({position: new google.maps.LatLng(57.951087,16.55972),  icon: ikona6, shadow: cien1, url:'http://www.google.com'});
Categories
discuss

org.hibernate.LazyInitializationException: How to properly use Hibernate’s lazy loading feature

I got some trouble loading a list of objects from my database using Hibernate and lazy=true mode. Hope that someone can help me out here.

I have a simple class here called UserAccount which looks like this:

public class UserAccount {
    long id;
    String username;
    List<MailAccount> mailAccounts = new Vector<MailAccount>();

    public UserAccount(){
        super();
    }

    public long getId(){
        return id;
    }

    public void setId(long id){
        this.id = id;
    }

    public String getUsername(){
        return username;
    }

    public void setUsername(String username){
        this.username = username;
    }

    public List<MailAccount> getMailAccounts() {
        if (mailAccounts == null) {
            mailAccounts = new Vector<MailAccount>();
        }
        return mailAccounts;
    }

    public void setMailAccounts(List<MailAccount> mailAccounts) {
        this.mailAccounts = mailAccounts;
    }
}

I am mapping this class in Hibernate via the following mapping file:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="test.account.UserAccount" table="USERACCOUNT">

        <id name="id" type="long" access="field">
            <column name="USER_ACCOUNT_ID" />
            <generator class="native" />
        </id>

        <property name="username" />

        <bag name="mailAccounts" table="MAILACCOUNTS" lazy="true" inverse="true" cascade="all">
            <key column="USER_ACCOUNT_ID"></key>
            <one-to-many class="test.account.MailAccount" />
        </bag>

    </class>
</hibernate-mapping>

As you can see, lazy is set to “true” in the bag mapping element.

Saving the data to the database works fine:

Loading also works by calling loadUserAccount(String username) (see code below):

public class HibernateController implements DatabaseController {
    private Session                 session         = null;
    private final SessionFactory    sessionFactory  = buildSessionFactory();

    public HibernateController() {
        super();
    }

    private SessionFactory buildSessionFactory() {
        try {
            return new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public UserAccount loadUserAccount(String username) throws FailedDatabaseOperationException {
        UserAccount account = null;
        Session session = null;
        Transaction transaction = null;
        try {
            session = getSession();
            transaction = session.beginTransaction();
            Query query = session.createQuery("FROM UserAccount WHERE username = :uname").setParameter("uname", username));
            account = (UserAccount) query.uniqueResult();
            transaction.commit();
        } catch (Exception e) {
            transaction.rollback();
            throw new FailedDatabaseOperationException(e);
        } finally {
            if (session.isOpen()) {
                // session.close();
            }
        }

        return account;
    }

    private Session getSession() {
        if (session == null){
            session = getSessionFactory().getCurrentSession();
        }
        return session;
    }
}

The problem is just: When I access elements within the list “mailAccounts”, I get the following exception:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: test.account.UserAccount.mailAccounts, no session or session was closed

I assume the reason for this exception is that the session got closed (don’t know why and how) and thus Hibernate cannot load the list. As you can see, I even removed the session.close() call from the loadUserAccount() method but the session still seems to be either get closed or replaced by another instance. If I set lazy=false, then everything works smoothly but this is not what I wanted because I need the feature of loading data “on demand” due to performance issues.

So, if I can’t be sure that my session is still valid after the method loadUserAccount(String username) terminated, what’s the point of having that feature and how do I work around that?

Thanks for your help!

Ps: I am a Hibernate beginner so please excuse my noobishness.

Update: Here is my hibernate config.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.password">foo</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mytable</property>
        <property name="hibernate.connection.username">user</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>

        <!-- Auto create tables -->
<!--        <property name="hbm2ddl.auto">create</property>-->

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <!-- Mappings -->
        <mapping resource="test/account/SmampiAccount.hbm.xml"/>
        <mapping resource="test/account/MailAccount.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

Answer

Lazy Loading working or not has nothing to do with transaction boundaries. It only requires that the Session be open.

However, when the session is open depends on how you’ve actually set up the SessionFactory, which you did not tell us! There is config going on behind what SessionFactory.getCurrentSession() actually does! If you’re letting it go with the default version of ThreadLocalSessionContext and not doing anything to manage the life cycle, it does indeed actually default to closing the session when you commit. (Hence the common conception that broadening transaction boundaries is the ‘fix’ for a lazy load exception.)

If you manage you own session life cycle with sessionFactory.openSession() and session.close() you will be able to lazy load fine within the session life cycle, outside transaction boundaries. Alternately you can provide a subclass of ThreadLocalSessionContext that manages the session life-cycle with the boundaries you desire. There are also readily available alternatives such as the OpenSessionInView filter that can be used in web applications to bind the session life-cycle to the web request life cycle.

edit: You can also of course just initialize the list inside the transaction if that works for you. I just think that leads to really clunky APIs when you need either a new method signature of some kind of ‘flag’ parameter for each level of hydration of your entity. dao.getUser() dao.getUserWithMailAccounts() dao.getUserWIthMailAccountsAndHistoricalIds() and so on.

edit 2: You may find this helpful for different approaches to how long the session stays open/the relationship between session scope and transaction scope. (particularly the idea of session-per-request-with-detached-objects vs session-per-conversation.)

It depends on your requirements and architecture just how big a conversation actually is.

Categories
discuss

Android detecting if an application entered the background

I’m trying to implement some automatic logout code for my Application on Android.

I need to detect if all the activities belonging to an Application have entered the background as opposed to working with onPause() and onResume() for each individual activity. iOS has a helpful applicationDidEnterBackground: method that I could utilize, but I’m unable to find a similar function in Android’s Application class.

One approach seems to be to have an AtomicInteger counter and increment it once an activity becomes visible and decrement it when it’s finished or onStop() gets called. So if the counter becomes zero, I can start a service that runs in the background and handles the logout. Is this how it’s usually done?

Answer

You really don’t want to log out the user when the “application” goes in the background, any more than you log out the user of a Web app when the user switches to another tab or minimizes their browser window for a moment. If you were to do either of those things in a Web app, your users would consider your Web app to be an epic fail. Similarly, if the user gets a phone call with a wrong number, or the alarm clock goes off, they’ll be rather irritated with you if they have to immediately go back in and sign in when they were just using your app 5 seconds ago. Here, by “irritated”, I mean one-star ratings on the Market and nasty comments.

A Web app automatic log out is based upon inactivity, using a server session cookie.

Similarly, when I build a secured Android app, I’ll be implementing an inactivity-based mechanism, perhaps something like this:

Step #1: Create a Session class with a static singleton instance. The Session object holds the last-accessed timestamp.

Step #2: In each activity’s onResume(), see if the Session singleton exists. If not, it’s a brand-new process, so if this isn’t the authentication activity, immediately do a startActivity() to bring up the authentication activity.

Step #3: Back in each activity’s onResume(), if the Session object exists, call something like extend(). This would return a boolean, true indicating the session is still good (and the timestamp has been updated to now), false otherwise. If it returns false, do the same stuff as if the Session object were null.

Step #4: Your authentication activity, upon success, sets up the singleton Session object with the current timestamp.

Step #5: Your Session class’ extend() method is where you make the determination if the session is too old.

No matter how the user gets into your application, if the session is too old (or it’s a brand-new process), they are forced to authenticate. Yet, if the user briefly is interrupted — where you and/or the user can define “briefly” — they don’t have to re-authenticate.

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..