2010-12-29 4 views
19

Nehmen Sie Zugriff auf Kontakte in Android android.jar für Versionen 1.6 hat People.CONTENT_URI für den Aufruf von Kontakten im Zusammenhang mit Informationen, während in späteren Versionen müssen wir API-Unterstützung für RawContacts.CONTENT_URI haben.Wie unterstützt man mehrere Android-Version in Ihrem Code?

Das gleiche gilt für den Zugriff auf Kalender zum Beispiel, da seine URI in Android 2.2 geändert wird.

Gibt es eine bewährte Methode zum Verwalten aller verschiedenen Änderungen ohne Hinzufügen zusätzlicher Anwendungen oder Build für jede Version der Änderungen?

Antwort

3

Ganz ehrlich, es ist ein Schmerz.

Ich isoliere normalerweise Teile des Codes, die unterschiedlich sind, und verwende abstrakte Klassen. Also technisch verschiedene Versionen für verschiedene Betriebssysteme erstellen.

Aber es gibt andere Möglichkeiten. Die beste, die ich gesehen habe, beinhaltet Reflexion.

+0

ja, das ist näher an das spezifische Problem Zugriff auf Kontakte. Vielleicht muss ähnlicher Code für zusätzliche Daten erstellt werden, die Änderungen an der uri über Versionen wie Kalender – dhaval

0

Best Practice (wenn auch nicht für Android, aber für J2ME) mein Wissen ist Vorverarbeitung C/C++ gestylten Aussagen zu verwenden, wie:

//#if S40 
    ... 
//#else 
    ... 
//#endif 

einige Unterstützung der IDE diese Art von Vorverarbeitung, z.B. Netbeans. Nach meinem Wissen hat Eclipse einige Plugins, um auch die Vorverarbeitung zu ermöglichen. Ich weiß nicht wirklich, ob sie auf Android-Entwicklung anwendbar sind. Versuchen Sie, sich selbst zu googeln.

+0

Und wie lösen wir für mehrere android.jar Aufnahme? – dhaval

+0

Netbeans unterstützt Einschlüsse von mehreren Gläsern je nach Konfigurationsschlüssel - der tatsächlich als Präprozessor #define verwendet wird. Es gibt schlechte Nachrichten: Netbeans unterstützt Android nicht :) Auf der anderen Seite gibt es Android-Plugin für Netbeans namens Nbandroid - es war in der tiefen Beta (vor 1/2 Jahr - wahrscheinlich hat sich sth geändert) – barmaley

1

Es gibt einen schönen Artikel über android.com darüber: http://developer.android.com/resources/articles/backward-compatibility.html

Persönlich würde ich die Wrapper-Klasse oder Wrapperbibliothek Lösung vorschlagen. Aber in kleinen Fällen sollte die Reflexion in Ordnung sein (und für den Fall, dass die Leistung kein Problem für Sie ist).

Wenn Sie weitere Informationen benötigen, fragen Sie in Kommentaren.

+0

halten Leider ist der Link nicht erreichbar :) Ist es dieser: http://developer.android.com/training/search/backward- compat.html? –

8

Es gibt viele Ressourcen, die Sie verwenden können, um mehrere Versionen von Android zu unterstützen.

  1. Lesen Sie diesen Blog-Post here und dann dieses here lesen, sie helfen Ihnen API-Ebene Version Unterstützung Fragen.
  2. Lesen this Blog-Post auf mehrere Bildschirm-Unterstützung, vor allem, wie die Asset-Hierarchie in Res Ordner geparst. Dies wird Ihnen helfen zu verstehen und zu gestalten, wie zu tun Asset-Ordner-Struktur zu unterstützen verschiedene Bildschirmgröße/Dichten und Android-Versionen.
  3. Schließlich schreiben Sie Ihre eigenen benutzerdefinierten Ameisen bauen Skripte, so dass Sie mit alle Versionen von Android kompilieren können.
2
  • Wenn Sie wirklich nicht, die neuen functionnalities brauchen, und haben wirklich alte Android-Versionen zu unterstützen, es fällt. Erstellen Sie Ihre App für die älteste Version, und kümmern Sie sich nicht um solche Dinge.
  • Im anderen Fall können Sie die Version mit Build erkennen und Reflektion verwenden, um die benötigten Klassen zu laden.Ein Beispiel dafür kann in den source code of the K9Mail app
1

This is a great article gefunden werden, wenn Sie Reflexion in Android zu tun haben (um mehr API-Ebene zu unterstützen).

Und wenn Sie verschiedene Ressourcen für verschiedene API-Ebenen haben müssen, this is the reference to use (siehe Abschnitt "Plattform Version (API-Ebene)").

+0

Große Antwort. Das war genau das, wonach ich gesucht habe. –

1

Wenn auf Eclipse, von ADT Version 17 Sie mit einigen Version Code auszuführen einfach wie beschrieben in Lint API Check angeben können. Das Codewort ist @TargetAPI (XX)

Hoffe, dass es

13

Für mein Geld hilft, ist eine sehr gute Antwort auf http://android-developers.blogspot.co.uk/2010/07/how-to-have-your-cupcake-and-eat-it-too.html. Allerdings ist das Beispiel dort ein wenig komplizierter als nötig, daher ist hier ein Beispiel, wie man damit beim Erstellen von Benachrichtigungen umgehen kann. Der Grund, warum dies funktioniert, ist eine Konsequenz davon, wie Java-Engines Klassen interpretieren: Sie sehen sie nur bei Bedarf an. Wenn Sie also versionsspezifischen Code in einer Klasse einbinden und nur erstellen, wenn Sie diese Version verwenden, funktioniert alles ...

Es gibt, soweit ich kann sagen, zwei Generationen von Ansätzen zur Benachrichtigung zu schaffen und eine Namensänderung auf dem Weg in den zweiten. Also gibt es drei Möglichkeiten, es zu tun. Für jede Art und Weise wird eine Klasse mit dem Benachrichtigungserzeugungs erstellen darin:

Der erste Ansatz (verwendet durch zu Lebkuchen):

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; 
} 
} 

Der zweite Ansatz, um Honeycomb 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(); 
} 
} 

Die zweite Generation, mit der Namensänderung, Jellybean (weiter, so weit ...):

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(); 
} 
} 

Dann brauchen Sie nur zu wählen, welche Klasse im Fluge zu instanziiert:

// 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); 

hoffe, das hilft!

+0

Ausgezeichnete Antwort. Danke vielmals – anon

Verwandte Themen