Android:如何根据API版本编写代码?

9
在Android中,我可以轻松获取SDK的版本(Build.VERSION.SDK),但是只有在平台版本高于1.6(>Build.VERSION_CODES.DONUT)时才需要使用LabeledIntent。
我认为反射是必要的(我已经阅读了这个链接,但对于一个类或者对我来说并不清晰)。
以下是代码,但它给我一个异常,因为在我的Android 1.6中,即使未应用条件,编译器也会验证包是否存在:
 Intent theIntent=....;
      if(Integer.parseInt(Build.VERSION.SDK) > Build.VERSION_CODES.DONUT)
   {    
 try{
             Intent intentChooser = Intent.createChooser(intent,"Choose between these programs");
              Parcelable[] parcelable = new Parcelable[1];
              parcelable[0] = new android.content.pm.LabeledIntent(theIntent, "", "Texto plano", 0);
               intentChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, parcelable); 
  activity.startActivity(intentChooser);
   }
   catch(Exception e)
   {
    activity.startActivity(theIntent);
   }

  } else
  {
   activity.startActivity(intentMedicamento);
  }

我如何解决它,一些正确答案的笔记

@Commonsware指导我如何做到这一点。我们创建了一个桥接类,这样根据API LEVEL,您可以实例化使用一个API LEVEL或另一个API LEVEL的另一个类。 唯一一个初学者可能会忘记的细节是,您必须使用最新的SDK编译您的应用程序,以便引用。

public abstract class LabeledIntentBridge {
 public abstract Intent BuildLabeledIntent(String URL, Intent theintent);

 public static final LabeledIntentBridge INSTANCE=buildBridge();

 private static LabeledIntentBridge buildBridge() {
  int sdk=new Integer(Build.VERSION.SDK).intValue();

  if (sdk<5) {
   return(new LabeledIntentOld());
  }

  return(new LabeledIntentNew());
 }
}

因此,在LabeledIntentNew中,我包含了所有代码,这些代码仅适用于API LEVEL 5中可用的LabeledIntent。 在LabeledIntentOld中,我可以实现另一种控制方式,在我的情况下,我返回意图本身而不进行其他操作。

调用此类的方法如下:

LabeledIntentBridge.INSTANCE.BuildLabeledIntent(URLtest,theIntent);

你的项目使用的是哪个框架版本? - Flo
@Flo.- 我的AndroidManifest文件定义了minSdkVersion="4"。LabeledIntent只包含在API LEVEL 5及以上的SDK中。 - netadictos
是的,但你的项目实际上使用哪个框架版本?minSdkVersion只是清单文件中的元信息。在创建项目时,你应该在创建对话框中选择一个框架版本。 - Flo
@Flo.- 我需要在2.2和1.6之间切换,我的应用程序必须与两者兼容。 - netadictos
好的,当你切换回1.6时,编译器会抛出一个错误,因为你试图使用的类不在Android 1.6框架中。正如你已经说过的,你将不得不使用反射,就像你链接的博客文章中提到的那样。 - Flo
2个回答

2

我看不太清楚。在链接中,他们使用了Debug.class.getMethod()方法,这将是检索LabeledIntent类的方法吗?感谢提供一些代码。 - netadictos
@netadictos:请查看https://github.com/commonsguy/cw-advandroid/tree/master/Contacts/Spinners/,了解另一种解决问题的方法。 - CommonsWare
它可以以另一种方式帮助我创建旋转器,但是您指示我的代码兼容性不适用于1.6,因为当我使用Android 1.6时,它无法识别android.provider.ContactsContract类。必须编译为2.2才能在1.6手机上运行吗? - netadictos
非常感谢,最终我模仿了你的代码,我认为在引用较新的API类时,只要它们位于未实例化的类中,执行包没有问题。我在我的答案中注释了我所做的事情。对于初学者来说,明确指出必须使用较新的SDK进行编译,否则将无法编译。 - netadictos

1

你必须使用反射...这个想法很好,但是在你的代码中引用了LabeledIntent,而1.6版本中没有该类,因此当你的应用程序运行在1.6设备上时,它找不到该类并会崩溃。

所以,这个想法是编写代码,在1.6中不引用LabeledIntent。为了做到这一点,你可以编写一个包装类(LabeledIntentWrapper),它扩展了LabeledIntent,并在你的函数中调用它。因此,在1.6中,设备将看到对已知类LabeledIntentWrapper的引用。


问题在于您仍然使用了对LabeledIntent的引用。这就是为什么我提到反射,它是必不可少的,但我真的不知道如何实现它,因为它有参数。 - netadictos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接