Android 4 学习(12):Linkify & Broadcast event
参考《Professional Android 4 Development》
Linkify
Linkfy类可以在Text View中创建超链接。匹配LInkify中正则表达式的文本将被Linkify转为超链接,这些链接将隐式调用startActivity方法。Linkify类中包含默认类型如电话号码,email地址和web地址,使用方法如下:
TextView textView = (TextView)findViewById(R.id.myTextView); Linkify.addLinks(textView, Linkify.WEB_URLS|Linkify.EMAIL_ADDRESSES);
除此之外,还可以在配置文件里面进行配置:
<TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="@string/linkify_me" android:autoLink="phone|email" />
自定义Linkify
String baseUri = "content://com.paad.earthquake/earthquakes/"; // Contruct an Intent to test if there is an Activity capable of viewing the content you are Linkifying. Use the Package Manager to perform the test. PackageManager pm = getPackageManager(); Intent testIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(baseUri)); boolean activityExists = testIntent.resolveActivity(pm) != null; // If there is an Activity capable of viewing the content linkify the text. if (activityExists) { int flags = Pattern.CASE_INSENSITIVE; Pattern p = Pattern.compile("\\bquake[\\s]?[0-9]+\\b", flags);
Linkify.addLinks(myTextView, p, baseUri); }
testIntent是用于测试能否View对应的Activity。在上面的代码片段中,任何匹配正则表达式p的字符串都可以生成Link,而不仅仅是baseUri。可以使用TransformFilter或MatchFilter来解决这个问题,下面是TransformFilter和MatchFilter的例子:
Linkify.addLinks(myTextView, p, baseUri, new MyMatchFilter(), new MyTransformFilter()); class MyMatchFilter implements MatchFilter { public boolean acceptMatch(CharSequence s, int start, int end) { return (start == 0 || s.charAt(start-1) != '!'); } } class MyTransformFilter implements TransformFilter { public String transformUrl(Matcher match, String url) { return url.toLowerCase().replace(“ “, “”); } }
使用Intent实现Broadcast Event
使用sendBroadcast方法发送广播
public static final String NEW_LIFEFORM_DETECTED = “com.paad.action.NEW_LIFEFORM”; Intent intent = new Intent(LifeformDetectedReceiver.NEW_LIFEFORM); intent.putExtra(LifeformDetectedReceiver.EXTRA_LIFEFORM_NAME, detectedLifeform); intent.putExtra(LifeformDetectedReceiver.EXTRA_LONGITUDE, currentLongitude); intent.putExtra(LifeformDetectedReceiver.EXTRA_LATITUDE, currentLatitude); sendBroadcast(intent);
Intent构造函数中的String用于唯一标识这个Intent,一般由包名+说明符构成。
使用Broadcast Receiver监听Broadcast
Broadcast Receiver必须注册后才能使用,注册有两种方法,一种是在代码中注册,另一种是在配置文件中注册,后者也被称为manifest receiver。通过继承BroadcastReceiver类,即可实现自己的Receiver:
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //TODO: React to the Intent received. } }
onReceive在主线程中执行,因此它必须快速执行完。onReceive方法的执行时间被限制为5秒,否则将出现Force Close的对话框。这个时间决定了BroadcastReceiver不会包含具体处理Broadcast的逻辑,更多地是进行启动其他的Activity,Service等操作。下面是一个BroadcastReceiver的示例代码:
public class LifeformDetectedReceiver extends BroadcastReceiver { public final static String EXTRA_LIFEFORM_NAME = “EXTRA_LIFEFORM_NAME”; public final static String EXTRA_LATITUDE = “EXTRA_LATITUDE”; public final static String EXTRA_LONGITUDE = “EXTRA_LONGITUDE”; public static final String ACTION_BURN = “com.paad.alien.action.BURN_IT_WITH_FIRE”; public static final String NEW_LIFEFORM = “com.paad.alien.action.NEW_LIFEFORM”; @Override public void onReceive(Context context, Intent intent) { // Get the lifeform details from the intent. Uri data = intent.getData(); String type = intent.getStringExtra(EXTRA_LIFEFORM_NAME); double lat = intent.getDoubleExtra(EXTRA_LATITUDE, 0); double lng = intent.getDoubleExtra(EXTRA_LONGITUDE, 0); Location loc = new Location(“gps”); loc.setLatitude(lat); loc.setLongitude(lng); if (type.equals(“facehugger”)) { Intent startIntent = new Intent(ACTION_BURN, data); startIntent.putExtra(EXTRA_LATITUDE, lat); startIntent.putExtra(EXTRA_LONGITUDE, lng); context.startService(startIntent); } } }
在代码中注册Broadcast Receiver:
public static final String NEW_LIFEFORM = “com.paad.alien.action.NEW_LIFEFORM”; .... private IntentFilter filter = new IntentFilter(LifeformDetectedReceiver.NEW_LIFEFORM); private LifeformDetectedReceiver receiver = new LifeformDetectedReceiver();
.... @Override public void onResume() { super.onResume(); // Register the broadcast receiver. registerReceiver(receiver, filter); } @Override public void onPause() { // Unregister the receiver unregisterReceiver(receiver); super.onPause(); }
在配置文件中注册BroadcastReceiver:
<receiver android:name=”.LifeformDetectedReceiver”> <intent-filter> <action android:name=”com.paad.alien.action.NEW_LIFEFORM”/> </intent-filter> </receiver>
广播Ordered Intent
使用sendOrderedBroadcast方法可以广播有序的Intent。有序的Intent可以设置Permission,只有具有Permission的Receiver才能处理这个Intent:
String requiredPermission = “com.paad.MY_BROADCAST_PERMISSION”; sendOrderedBroadcast(intent, requiredPermission);
BroadcastReceiver可以在配置文件中配置Permission:
<receiver android:name=”.MyOrderedReceiver” android:permission=”com.paad.MY_BROADCAST_PERMISSION”> <intent-filter android:priority=”100”> <action android:name=”com.paad.action.ORDERED_BROADCAST” /> </intent-filter> </receiver>
在上面的代码中,android:priority可以用于设置BroadcastReceiver的优先级。sendOrderedBroadcast方法可以设置一个最终的Receiver以及initialResult, initialData和initialExtras:
// Specify the default result, data, and extras. // The may be modified by any of the Receivers who handle the broadcast before being received by the final Receiver. int initialResult = Activity.RESULT_OK; String initialData = null; String initialExtras = null; // A special Handler instance on which to receive the final result. // Specify null to use the Context on which the Intent was broadcast. Handler scheduler = null; sendOrderedBroadcast(intent, requiredPermission, finalResultReceiver, scheduler, initialResult, initialData, initialExtras);
finalResultReceiver将被添加到Receiver链的末端,从而保证最后一个处理Intent。, initialData和initialExtras可以被任意一个Receiver链中的BroadcastReceiver处理。
广播Sticky Intent
使用sticky intent,我们可以不使用Receiver获取广播Intent,示例如下:
IntentFilter battery = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); Intent currentBatteryCharge = registerReceiver(null, battery);
设置IntentFilter来filter一个Sticky Intent,即可通过调用registerReceiver获取此Sticky Intent的信息。
发送自定义的Sticky Intent:
sendStickyBroadcast(intent);
删除Sticky Inent:
removeStickyBroadcast(intent);