每次广播到来时 , 会重新创建 BroadcastReceiver 对象 , 并且调用 onReceive() 方法 , 执行完以后 , 该对象即被销毁 . 当 onReceive() 方法在 10 秒内没有执行完毕, Android 会认为该程序无响应 . 所以在BroadcastReceiver 里不能做一些比较耗时的操作 , 否侧会弹出 ANR(Application NoResponse) 的对话框 .
如果需要完成一项比较耗时的工作 , 应该通过发送 Intent 给 Service, 由 Service 来完成 . 这里不能使用子线程来解决 , 因为 BroadcastReceiver 的生命周期很短 , 子线程可能还没有结束BroadcastReceiver 就先结束了 .BroadcastReceiver 一旦结束 , 此时 BroadcastReceiver 的所在进程很容易在系统需要内存时被优先杀死 , 因为它属于空进程 ( 没有任何活动组件的进程 ). 如果它的宿主进程被杀死 , 那么正在工作的子线程也会被杀死 . 所以采用子线程来解决是不可靠的 .
//实现public class MyReceiver extends BroadcastReceiver {private String tag="MyReceiver";@Overridepublic void onReceive(Context context, Intent intent) {// TODO Auto-generated method stubLog.i(tag, intent.getAction());}}
清单中配置<uses-permission android:name="android.permission.RECEIVE_SMS"/><receiver android:name=".MyReceiver"><intent-filter ><action android:name="android.provider.Telephony.SMS_RECEIVED"/></intent-filter></receiver>
//注册IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");registerReceiver(mBroadcastReceiver, filter);
//广播接受者private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver(){@Overridepublic void onReceive(Context context, Intent intent) {Log.i(tag, "代码注册"+intent.getAction());}};
//取消注册建议在onPuase()中执行unregisterReceiver(mBroadcastReceiver);
//注册IntentFilter filter = new IntentFilter(" cn.lt.MYRECEIVER ");registerReceiver(mBroadcastReceiver, filter);
//广播接受者private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver(){@Overridepublic void onReceive(Context context, Intent intent) {Log.i(tag, "代码注册"+intent.getAction());}};
//发送广播Intent intent = new Intent();intent.setAction("cn.lt.MYRECEIVER");sendBroadcast(intent);
abortBroadcast()
这个方法可以截获由 sendOrderedBroadcast() 发送来的广播,让其它广播接收者无法收到这个广播
clearAbortBroadcast()
这个方法是针对 abortBroadcast() 方法,用于取消截获广播。这样它的下一级广播接收者就能够收到该广播了
getAbortBroadcast()
是否终止广播, true终止
//获取SharedPreferences对象SharedPreferences preferences = getSharedPreferences("CONFIG", Context.MODE_PRIVATE);//存储数据Editor editor = preferences.edit();editor.putString("name", "luv");editor.commit(); //提交//得到数据String mString = preferences.getString("name", "");
public class MySqlHelper extends SQLiteOpenHelper {/**** @param context 上下文* @param name 数据库名* @param factory 缺省为null* @param version 数据库版本*/public MySqlHelper(Context context, String name, CursorFactory factory,int version) {super(context, name, factory, version);}@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL("CREATE TABLE person (_id integer primary key autoincrement, name varchar(30))");}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}}
//表操作实现类public class PersonDao {private String tag = "PersonDao";private MySqlHelper sqlHelper;public PersonDao(Context context) {sqlHelper = new MySqlHelper(context, "person.db", null, 1);}public void add(String name) {SQLiteDatabase db = sqlHelper.getReadableDatabase();if (db.isOpen()) {db.execSQL("insert into person (name) values(?)", new Object[]{name});db.close();}}public void all() {SQLiteDatabase db = sqlHelper.getReadableDatabase();if (db.isOpen()) {Cursor cursor = db.rawQuery("select name from person ", null);while (cursor.moveToNext()) {Log.i(tag, cursor.getString(0));}db.close();}}}
//创建PersonDao实现private PersonDao personDao;personDao = new PersonDao(this);personDao.add("luv");personDao.all();
URL url = new URL("http://192.168.1.104:8080/newapk.apk");HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setReadTimeout(5000);conn.setRequestMethod("GET");if (conn.getResponseCode() == 200) {//得到文件长度int total = conn.getContentLength();pdDialog.setMax(total);InputStream is = conn.getInputStream();File file = new File(filePath);FileOutputStream fos = new FileOutputStream(file);byte[] buffer = new byte[1024];int len;int process = 0;while ((len = is.read(buffer))!= -1) {fos.write(buffer,0, len);process += len;pdDialog.setProgress(process);}fos.flush();fos.close();is.close();return file;
}
Intent intent = new Intent();intent.setAction(Intent.ACTION_VIEW);//file -> apk 文件intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");startActivity(intent);
//创建提供者public class PersonDBProvider extends ContentProvider {//定义一个uri的匹配器用于匹配uri,如果路径不满足返回-1private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);private static final int INSERT = 1;private static final int DELETE = 2;private static final int UPDATE = 3;private static final int QUERY = 4;
static {//添加匹配规则matcher.addURI("cn.lt.personprovider", "insert", INSERT);matcher.addURI("cn.lt.personprovider", "delete", DELETE);matcher.addURI("cn.lt.personprovider", "update", UPDATE);matcher.addURI("cn.lt.personprovider", "query", QUERY);}private MySqlHelper sqlHelper;@Overridepublic boolean onCreate() {// TODO Auto-generated method stubsqlHelper = new MySqlHelper(getContext(), "person.db", null, 1);return false;}@Overridepublic Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {if (matcher.match(uri)==QUERY) {SQLiteDatabase db = sqlHelper.getReadableDatabase();return db.query("person", projection, selection, selectionArgs, null, null, sortOrder);} else {throw new IllegalArgumentException("查询路径不合法");}}@Overridepublic String getType(Uri uri) {return null;}@Overridepublic Uri insert(Uri uri, ContentValues values) {return null;}@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {return 0;}@Overridepublic int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {return 0;}}
<!-- 清单中声明,其中exported表示内容提供者被其他应用程序调用,在版本17以后默认为false,需手动设为true --><providerandroid:name=".PersonDBProvider"android:authorities="cn.lt.personprovider"android:exported="true" />
//创建一个新的Android程序,获取到上面程序中提供的数据ContentResolver resolver = getContentResolver();Uri uri = Uri.parse("content://cn.lt.personprovider/query");Cursor cursor = resolver.query(uri, null, null, null, null);while (cursor.moveToNext()) {Log.i(tag , cursor.getString(0));}
/ / 获取位置管理服务LocationManager locationManager;String serviceName = Context.LOCATION_SERVICE;locationManager = (LocationManager) this.getSystemService(serviceName);// 查找到服务信息Criteria criteria = new Criteria();criteria.setAccuracy(Criteria.ACCURACY_FINE); // 高精度criteria.setAltitudeRequired(false);criteria.setBearingRequired(false);criteria.setCostAllowed(true);criteria.setPowerRequirement(Criteria.POWER_HIGH); // 低功耗String provider = locationManager.getBestProvider(criteria, true); // 获取GPS信息Location location = locationManager.getLastKnownLocation(provider); // 获取最后的位置updateToNewLocation(location);// 设置监听器,自动更新的最小时间为间隔1000*10毫秒, 最小位移变化超过1000米locationManager.requestLocationUpdates(provider, 10*1000 , 1000,new MyLocationListener());
//监听器private class MyLocationListener implements LocationListener {@Overridepublic void onLocationChanged(Location location) {double latitude = location.getLatitude();double longitude= location.getLongitude();String ss = "纬度:" + latitude+ " 经度" + longitude;tView.setText(ss);}@Overridepublic void onStatusChanged(String provider, int status, Bundle extras) {}@Overridepublic void onProviderEnabled(String provider) {}@Overridepublic void onProviderDisabled(String provider) {}}
//获取最后的位置private void updateToNewLocation(Location location) {if (location != null) {double latitude = location.getLatitude();double longitude= location.getLongitude();String ss = "纬度:" + latitude+ " 经度" + longitude;tView.setText(ss);} else {tView.setText("无法获取地理信息");}}
TelephonyManager manager = (TelephonyManager) context.getSystemService(Context. TELEPHONY_SERVICE );String currentsim = manager.getSimSerialNumber();String realsim = sp.getString("sim", "");if(!currentsim.equals(realsim)){ //sim 卡串号不同// 发送报警短信Log.i(TAG,"发送报警短信");SmsManager smsmanager = SmsManager.getDefault();String destinationAddress = sp.getString("safenumber", "");smsmanager.sendTextMessage(destinationAddress, null, "sim卡发生了改变,手机可能被盗", null, null);}
提供统一的接口向其他应用程序提供数据, 其数据操作类似于操作数据库.先看如何使用:getContentResolver ().insert(Uri. parse ( "content:// cn.luv.mydata.provider /insert" ), values);分析:A 标准前缀B 内容提供者标识, 在Mainnifeset.xml 中声明的 : < provider android:authorities="cn.luv.mydata.provider" ></ provider >C 子路径, 其在contentprovider 中定义: matcher .addURI("cn.itcast.applockprovider", "insert", INSERT);
在执行上面操作时,将调用到contentprovider 中的重载insert函数:public Uri insert(Uri uri, ContentValues values) {int result = matcher.match(uri);if (result == INSERT) {//do ....} else {throw new IllegalArgumentException("uri地址不正确");}return null;}此函数中的matcher 定义如下:private static final int INSERT = 10;private static final int DELETE = 11;private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);static {matcher.addURI("cn.itcast.applockprovider", "insert", INSERT);matcher.addURI("cn.itcast.applockprovider", "delete", DELETE);}
//1.public class MyProvider extends ContentProvider {private static final int INSERT = 10;private static final int DELETE = 11;private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);static {//t添加urimatcher.addURI("cn.luv.mydata.provider", "insert", INSERT); //插入urimatcher.addURI("cn.luv.mydata.provider", "delete", DELETE); //删除uri}//本地数据库实例private PersonDao dao;@Overridepublic boolean onCreate() {dao = new PersonDao(getContext());return false;}@Overridepublic Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {return null;}@Overridepublic String getType(Uri uri) {return null;}@Overridepublic Uri insert(Uri uri, ContentValues values) {int result = matcher.match(uri);if (result == INSERT) { //插入到数据库中dao.add(values.getAsString("name"));//通知内容观察者// getContext ().getContentResolver().notifyChange(Uri. parse ( "content://cn.luv.mydata.provider/haha" ), null );} else {throw new IllegalArgumentException("uri地址不正确");}return null;}@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {return 0;}@Overridepublic int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {return 0;}}
//数据库daopublic class PersonDao {private String tag = "PersonDao";private MySqlHelper sqlHelper;public PersonDao(Context context) {sqlHelper = new MySqlHelper(context, "person.db", null, 1);}//插入一条数据public void add(String name) {SQLiteDatabase db = sqlHelper.getReadableDatabase();if (db.isOpen()) {db.execSQL("insert into person (name) values(?)", new Object[]{name});db.close();}}public void all() {SQLiteDatabase db = sqlHelper.getReadableDatabase();if (db.isOpen()) {Cursor cursor = db.rawQuery("select name from person ", null);while (cursor.moveToNext()) {Log.i(tag, cursor.getString(0));}db.close();}}}
public class MySqlHelper extends SQLiteOpenHelper {public MySqlHelper(Context context, String name, CursorFactory factory,int version) {super(context, name, factory, version);}@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL("CREATE TABLE person (_id integer primary key autoincrement, name varchar(30))");}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}}
顺便提下内容观察者, 在上面的内容提供者中, 我们可以通过注册一个内容观察者来监听数据库中数据的变化,实现如下:在MainActivity.java 中注册观察者getContentResolver().registerContentObserver(Uri.parse("content://cn.luv.mydata.provider/haha"), true, new MyObserver(new Handler()));在ContentProvider 中通知观察者getContext().getContentResolver().notifyChange(Uri.parse("content://cn.luv.mydata.provider/haha"), null);
MyObserver 实现:public class MyObserver extends ContentObserver {@Overridepublic void onChange(boolean selfChange) {// TODO Auto-generated method stubsuper.onChange(selfChange);Log.i(TAG, "数据库有变化.....");}public MyObserver(Handler handler) {super(handler);}}