简单的翻译了一下sdk
在应用中声明
<provider android:authorities="com.huawei.gps.ProviderTest1" android:name="com.huawei.gps.ProviderTest"> </provider>
android:authorities指明了对其他应用开放的接口
其他应用中可以通过如下方法调用该provider
Uri uri=Uri.parse("content://com.huawei.gps.ProviderTest1"); getContentResolver().delete(uri, null, null);
关键技能和概念
l 构建Activity
l 使用Android菜单
l 使用AutoCompleteTextView
本章对Views与Intents做了深入的研究,这些对于Android的新手来说是需要掌握的最重要的特性。这两个实体组成了你的前期应用的主体。你创建的每一个Activity几乎都会有多个视图,并且大部分需要条用一两个Intent。
深入学习这些主题的最佳方式是采用一种非常容易上手的方法。阅读这些主题并回顾属性列表是一种,但是独立进行代码实现是完全不同的。也就是说,就像前几章中你已经做的,你将非常频繁地利用Views和Intents构建Activity。通过构建这个应用,你会得到Views和Intents的最佳实践。
前两章通过创建简单的Activity,使用大量关于Views和Intents的基础功能,简单地介绍了Views和Intents。本章中,你会构建稍微复杂一点的Activity,即使用新Intents调用我们创建的新Activity。这些新的Activity会展示当前Android SDK版本可用的大部分视图。本章解释这些视图的基本功能,例如AutoComplete 列表和Gallery,并介绍了每个Activity对应的每个视图属性的变量。
首先,创建一个新的名为AndroidViews的Eclipse项目。用如下所示的参数创建项目:一个包名android_programmers_guide. AndroidViews,一个Activity名AndroidViews,和一个应用名AndroidViews。
完成项目创建并打开main.xml文件。从main.xml中删除Hello World!代码。创建项目和清除main.xml代码后,你就可以添加自己的代码了。
构建Activity截止目前,你已经创建了单一Activity的应用。也就是说,你已经创建了相当简单的应用,仅仅包含一屏数据。稍等一下,思考一下你用到的上几个应用。可能他们使用了多个窗口。大部分应用使用多个窗口来收集,显示和保存数据。你的 Android应用应该也一样。
尽管你还不了解如何创建可以在Android运行的多Activity的应用,但在上一章你也得到了如何充分开发利用多Activity的提示。你使用一个新概念名为Intents来调用——并运行——核心的Android Activity。虽然这个概念在本章提出,但是和调用核心的Android Activity相比,当你调用自己创建的Activity时其执行却有所不同。
你要做的第一件事是构建Activity。然后你创建可以调用它们的Intents。当构建Activity时,你需要遵从一个三步走流程。
● 在.xml文件中创建Intent代码。
● 在.java文件中创建Intents代码。
● 利用 Intent条用Activity
一旦你创建了第一个多功能Activity,其余的就会很简单了。
在.xml文件中创建Intent代码
记住,所有Android Activity都有三个部分组成:包含代码的.java文件,保存布局的.xml文件和包的Manifest。
截止到当前,你已经使用main.xml控制一个单Activity的布局。然而,为了利用多Activity,你必须拥有多个..xml布局文件。
要创建一个新的.xml文件,打开你的Eclipse项目并浏览Package Explorer。打开res目录,右击layout文件夹,并选择New|File。
在New File对话框中,如下,命名你的文件test.xml。
布局文件创建后是空的。要让Activity一开始就顺利运行,就为test.xml文件增加下面的代码。本书为你的布局提供了范例。如果你需要,你可以简单的从已有的main.xml文件中复杂这些代码。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
</LinearLayout>
在.java文件中创建Intent代码
再次使用Package Explorer,浏览src目录,打开它,并右击android_programmers_guide.AndroidViews包,如下所示。
再次你会在文件夹中添加一个新文件。在右击AndroidViews包后,在内容菜单选择New|File。这个文件会保存第二个Activity中的全部代码。将文件命名为test.java。现在你会有一个漂亮的新(但是空的).java文件。你仅需要在文件中添加少量的代码行就可以让它有用:
package testPackage.test;
import android.app.Activity;
import android.os.Bundle;
public class test extends Activity {
/** Called when the Activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.test);
/** This is our Test Activity
All code goes below */
}
}
注意你在setContentView方法中通过R.layout.test调用的test.xml。 这一行告诉新Activity文件使用你创建的.xml文件作为本页的布局文件。
修改AndroidManifest.xml
在Eclipse中打开你的AndroidManifest.xml文件。本书还没有详细讨论AndroidManifest.xml。AndroidManifest.xml包含对你的项目的全局设置。更重要的是,AndroidManifest.xml也包含了项目的Intent Filters。
第七章讨论过Android如何使用Intent Filters管理什么Activity能接受什么Intent。纾缓这个流程的信息保存在AndroidManifest.xml中。
你的AndroidManifest.xml现在打开了,它应该显示如下:
<activity android:name=".AndroidViews" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
现在你看到的是AndroidViews Activity的Intent Filter,主Activity在项目中创建。这个文件中,你可以添加其他任何你想让项目处理的Intent Filters。本例中,你要添加一个处理新建的Test Activity的Intent Filter。
下面就是你需要添加到AndroidManifest.xml文件中的Intent Filter代码:
<activity android:name=".Test" android:label="Test Activity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
为AndroidManifest.xml添加这段代码可以使Android将Test Activity的Intents传递到正确的位置。完整的AndroidManifest.xml文件应该看起来这样:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android=http://schemas.android.com/apk/res/android
package="android_programmers_guide.AndroidViews">
<application android:icon="@drawable/icon">
<activity android:name=".AndroidViews" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".AutoComplete" android:label="AutoComplete">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"
/>
</intent-filter>
</activity>
</application>
</manifest>
现在你的Activity可以处理Test Activity的Intent呼叫了。要创建Test Activity 的Intent call,你会使用一种类似于的在第七章中你调用手机拨号器的那种框架。下面一行代码会建立Intent:
Intent testActivity = new Intent(this, test.class);
这一行创建了一个名为testActivity的Intent。参数test.class告诉呼叫你想让Intent testActivity代表你创建的Test Activity和这个Activity相关联。
最后使用startActivity()方法,启动Test Activity:
startActivity(autocomplete);
你完成的AndroidViews.java看起来像:
package android_programmers_guide.AndroidViews;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.content.Intent;
public class AndroidViews extends Activity {
/** Called when the Activity is first created. /
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
/**Set up our Intent /
在模拟器中运行该应用。Android会启动AndroidViews Activity,然后是Test Activity。
下面一节,你会使用这些技术,创建启动多Activity的应用。每个Activity都会有一个View,你可以在里面设置不同的项。这会给你大量实践显示和操作视图的机会,如同处理Activity一样。
使用菜单本节中,你会构建一个应用,允许用户从一些不同的视图中选择。当用户选择一个视图,包含在选择视图中的一个新的Activity就会启动。
你将使用的为用户提供选择的工具是Android Menu。看看下面的插图。当用户触发菜单按钮,菜单就会显示。
如你所见,从Android主屏选择Menu Button出现一个Wallpaper setting选项。你可以为你的主Activity创建一个相似的菜单来保存所有视图选项,供用户选择。现在,AndroidViews.java文件看起来像这样:
package android_programmers_guide.AndroidViews;
import android.app.Activity;
import android.os.Bundle;
public class AndroidViews extends Activity {
/** Called when the Activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
}
}
一切停当之后。你需要导入一个新包来创建目录。将android.view.Menu导入到你的AndroidViews Activity:
Import android.view.Menu;
要创建Menu,你需要覆盖Activity的onCreateOptionsMenu()方法。onCreateOptionsMenu()方法是一个布尔方法,当用户第一次选择Menu Button时会调用它。你会用该方法构建你的Menu并为它添加选择项。给AndroidViews.java添加以下代码:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
}
你将在onCreateOptionsMenu()内部添加代码来创建Menu。你需要添加到Menu中的项是你将在项目中创建的视图。下面就是你将添加到Menu中的视图名称列表
● AutoComplete
● Button
● CheckBox
● EditText
● RadioGroup
● Spinner
在前面创建的代码,覆盖了onCreateOptionsMenu()方法,你在Menu中传递的变量为menu。该变量代表在Android接口上创建的实际菜单项。
要为Menu添加项,你需要使用menu.add()方法。语法如下:
menu.add(<group>,<id>,<title>)
参数组用来关联菜单项。在本例中你不会使用组。然而值非常重要。参数用来判定什么菜单项被选中。最后参数标题就是在Menu中显示的文本。
为onCreateOptionsMenu()方法添加下面的代码:
menu.add(0, 0, "AutoComplete");
menu.add(0, 1, "Button");
menu.add(0, 2, "CheckBox");
menu.add(0, 3, "EditText");
menu.add(0, 4, "RadioGroup");
menu.add(0, 5, "Spinner");
完整的AndroidViews.java文件应该看起来像这样:
package android_programmers_guide.AndroidViews;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
public class AndroidViews extends Activity {
/** Called when the Activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, 0, "AutoComplete");
menu.add(0, 1, "Button");
menu.add(0, 2, "CheckBox");
menu.add(0, 3, "EditText");
menu.add(0, 4, "RadioGroup");
menu.add(0, 5, "Spinner");
return true;
}
}
如果你照这样执行代码,你应该会看到如图8-1所示的菜单。
图8-1 拥有六个视图的菜单
这正是你想要完成的。然而,试着点击菜单中的任何项。当用户选择一个菜单项时你不会在Activity中触发任何事件。
处理菜单项的调用时你需要覆盖的方法是onOptionsItemSelected()。再次,像onCreateOptionsMenu()一样,当选择一个菜单项时,onOptionsItemSelected()也是一个需要用特定代码覆盖的布尔型的方法。覆盖的代码像这样:
@Override
public boolean onOptionsItemSelected(Menu.Item item){
}
import android.view.MenuItem;
最后程序报错:
Error generating final archive: java.io.FileNotFoundException: C:\xxx\bin\resources.ap_ does not exist
解决方法:“Project”-“Clean”,不ok的话重启eclipse
import android.view.MenuItem;
否则public boolean onOptionsItemSelected(MenuItem item){中的
MenuItem 会报错。
用法:
String add=address.getString();
String con=content.getString();
SMSSender smsSender = SMSSender.getSMSSender();
smsSender.setMessageText(add,con);
Thread t = new Thread(smsSender);
t.start();
import java.io.IOException; import javax.microedition.io.Connector; import javax.wireless.messaging.MessageConnection; import javax.wireless.messaging.TextMessage; /** * File Name : SMSSender.java * Created on : 2005-4-28 * Summary : A standalone thead, which is used to send SMS. * Author : Jedi Chen */ public final class SMSSender implements Runnable { // the string stores the text message that will be sent. private String message; // the destination address for current SMS sender. private String address; // boolean variable indicates whether the SMS has been sent successfully. // initialized as false when get the singleton instance. private static boolean doSuccessfully; // boolean variable indicates whether error occured while sending SMS. // initialized as false when get the singleton instance. private static boolean errorOccured; // the singleton instance of SMSSender, since one instance is enough // for one MIDlet, we apply the Singleton pattern for this class. private static SMSSender instance; /** * the Factory method to get the singleton instance. */ public static SMSSender getSMSSender() { if (instance == null) { instance = new SMSSender(); } else { instance.reset(); } return instance; } /** * The private constructor for SMSSender, only could be called * by getSMSSender. * * call resetSenderStatus() to reset the members. */ private SMSSender() { reset(); } /** * Once the caller get the sender status, it must * call this method to reset both status. */ private void reset() { doSuccessfully = false; errorOccured = false; address = null; message = null; } public synchronized void setMessageText(String address, String message) { // assert(address != null && !address.equals("")); this.address = "sms://" + address; if(message == null || message.equals("")) message = "[WARN] Error formatted message!"; this.message = message; // System.out.println("[SMS] " + s); // m_fDoSuccessfully = false; // m_fErrorOccured = false; } /* * Send the message in a standalone thread. * * @see java.lang.Runnable#run() */ public void run() { MessageConnection smsconn = null; try { smsconn = (MessageConnection) Connector.open(address); TextMessage txtmsg = (TextMessage) smsconn.newMessage(MessageConnection.TEXT_MESSAGE); txtmsg.setPayloadText(message); smsconn.send(txtmsg); doSuccessfully = true; // System.out.println("[SMS] SMS sent successfully :)"); } catch (Exception expt) { errorOccured = true; // System.out.println("[SMS] SMS sent error!"); } finally { if (smsconn != null) { try { smsconn.close(); } catch (IOException ioex) { // System.out.println("[SMS] Close SMS connection error caught!"); } } } } /** * @return Returns the doSuccessfully. */ public static synchronized boolean isDoSuccessfully() { return doSuccessfully; } /** * @return Returns the errorOccured. */ public static synchronized boolean isErrorOccured() { return errorOccured; } }