Libgdx实现异步加载网络图片并保存到SD卡或者data/data目录下边,当本地有图片的时候,直接从本地读取图片,如果本地没有图片,将从服务器异步加载图片
package com.example.libgdx_net;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.PixmapIO;
import com.badlogic.gdx.graphics.Texture;
import android.content.Context;
import android.os.Environment;
public class ImageUtil {
private static final String SDCARD_CACHE_IMG_PATH = Environment
.getExternalStorageDirectory().getPath() + "/myGame/images/";
private static Texture texture;
private static Context mContext;
// 返回图片存到sd卡的路径
public static String getCacheImgPath() {
return SDCARD_CACHE_IMG_PATH;
}
public static String getDataImgPath() {
return mContext.getFilesDir().getPath();
}
public static String getImagePath(String url) {
if (isSDcardExist()) {
return getCacheImgPath().concat(ImageUtil.md5(url));
} else {
return getDataImgPath().concat(ImageUtil.md5(url));
}
}
/**
* 判断是否有存储卡,有返回TRUE,否则FALSE
*
* @return
*/
public static boolean isSDcardExist() {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
return true;
} else {
return false;
}
}
/**
*
* @return
* @throws IOException
*/
public static Texture loadImage(Context context,final String imgUrl,
final ImageCallBack imageCallback) {
mContext=context;
final String imagePath = getImagePath(imgUrl);
texture = getImageFromLocal(imagePath);
if (texture != null) {
return texture;
} else {// 从网上加载
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
URL url;
try {
url = new URL(/blog_article/imgUrl/index.html);
URLConnection conn = url.openConnection();
conn.connect();
final InputStream is = conn.getInputStream();
try {
saveImage(imagePath, is);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Gdx.app.postRunnable(new Runnable() { //这里是将texture 实例化到主线程
@Override
public void run() {
// TODO Auto-generated method stub
texture = getImageFromLocal(imagePath);
// Pixmap pixmap = texture.getTextureData().consumePixmap();
// savePixmap(imagePath,pixmap);
imageCallback.loadImage(texture, imagePath);
}
});
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
return null;
}
demo地址:
/**
* 从SD卡加载图片
*
* @param imagePath
* @return
*/
public static Texture getImageFromLocal(String imagePath) {
File file = new File(imagePath);
if (file.exists()) {
file.setLastModified(System.currentTimeMillis());
try {
final FileInputStream fis = new FileInputStream(imagePath);
Texture tures = new Texture(new FileHandle("image.jpg") {
@Override
public InputStream read() {
return fis;
}
});
return tures;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
// public static void savePixmap(String imagePath,Pixmap pixmap){
// File f = new File(imagePath);
// if (f.exists()) {
// return;
// } else {
// File parentFile = f.getParentFile();
// if (!parentFile.exists()) {
// parentFile.mkdirs();
// }
// try {
// f.createNewFile();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// FileHandle fh=new FileHandle(f);
// PixmapIO.writePNG(fh,pixmap);
// }
//
// }
/**
* 保存图片到SD卡
*
* @param imagePath
* @param buffer
* @throws IOException
*/
public static void saveImage(String imagePath, InputStream is)
throws IOException {
File f = new File(imagePath);
if (f.exists()) {
return;
} else {
File parentFile = f.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
f.createNewFile();
FileOutputStream fos = new FileOutputStream(imagePath);
try {
fos.write(readStream(is));
fos.flush();
fos.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 将InputStream转换成byte数组
*
* @param b
* @return
*/
public static byte[] readStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
outStream.close();
// inStream.close();
return outStream.toByteArray();
}
public static String md5(String paramString) {
String returnStr;
try {
MessageDigest localMessageDigest = MessageDigest.getInstance("MD5");
localMessageDigest.update(paramString.getBytes());
returnStr = byteToHexString(localMessageDigest.digest());
return returnStr;
} catch (Exception e) {
return paramString;
}
}
/**
* 将指定byte数组转换成16进制字符串
*
* @param b
* @return
*/
public static String byteToHexString(byte[] b) {
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < b.length; i++) {
String hex = Integer.toHexString(b[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
hexString.append(hex.toUpperCase());
}
return hexString.toString();
}
}
demo地址:http://download.csdn.net/detail/lihonghao1017/6249037
百度SDK中提供了离线下载功能,这样在有网络的时候可以把地图下载下来,那么以后在无网的时候就可以使用地图功能了,百度Demo代码如下:
OffLineActivity:
package com.home; import java.util.ArrayList; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import com.baidu.mapapi.BMapManager; import com.baidu.mapapi.map.MKOLSearchRecord; import com.baidu.mapapi.map.MKOLUpdateElement; import com.baidu.mapapi.map.MKOfflineMap; import com.baidu.mapapi.map.MKOfflineMapListener; import com.baidu.mapapi.map.MapController; import com.baidu.mapapi.map.MapView; public class OffLineActivity extends Activity implements MKOfflineMapListener { private MapView mMapView = null; private MKOfflineMap mOffline = null; private TextView cidView; private TextView stateView; private EditText cityNameView; private MapController mMapController = null; /** * 已下载的离线地图信息列表 */ private ArrayList<MKOLUpdateElement> localMapList = null; private LocalMapAdapter lAdapter = null; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); DemoApplication app = (DemoApplication) this.getApplication(); if (app.mBMapManager == null) { app.mBMapManager = new BMapManager(this); app.mBMapManager.init(DemoApplication.strKey, new DemoApplication.MyGeneralListener()); } setContentView(R.layout.activity_offline); mMapView = new MapView(this); mMapController = mMapView.getController(); mOffline = new MKOfflineMap(); /** * 初始化离线地图模块,MapControler可从MapView.getController()获取 */ mOffline.init(mMapController, this); initView(); } private void initView() { cidView = (TextView) findViewById(R.id.cityid); cityNameView = (EditText) findViewById(R.id.city); stateView = (TextView) findViewById(R.id.state); ListView hotCityList = (ListView) findViewById(R.id.hotcitylist); ArrayList<String> hotCities = new ArrayList<String>(); // 获取热门城市列表 ArrayList<MKOLSearchRecord> records1 = mOffline.getHotCityList(); if (records1 != null) { for (MKOLSearchRecord r : records1) { hotCities.add(r.cityName + "(" + r.cityID + ")" + " --" + this.formatDataSize(r.size)); } } ListAdapter hAdapter = (ListAdapter) new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, hotCities); hotCityList.setAdapter(hAdapter); ListView allCityList = (ListView) findViewById(R.id.allcitylist); // 获取所有支持离线地图的城市 ArrayList<String> allCities = new ArrayList<String>(); ArrayList<MKOLSearchRecord> records2 = mOffline.getOfflineCityList(); if (records1 != null) { for (MKOLSearchRecord r : records2) { allCities.add(r.cityName + "(" + r.cityID + ")" + " --" + this.formatDataSize(r.size)); } } ListAdapter aAdapter = (ListAdapter) new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, allCities); allCityList.setAdapter(aAdapter); LinearLayout cl = (LinearLayout) findViewById(R.id.citylist_layout); LinearLayout lm = (LinearLayout) findViewById(R.id.localmap_layout); lm.setVisibility(View.GONE); cl.setVisibility(View.VISIBLE); // 获取已下过的离线地图信息 localMapList = mOffline.getAllUpdateInfo(); if (localMapList == null) { localMapList = new ArrayList<MKOLUpdateElement>(); } ListView localMapListView = (ListView) findViewById(R.id.localmaplist); lAdapter = new LocalMapAdapter(); localMapListView.setAdapter(lAdapter); } /** * 切换至城市列表 * * @param view */ public void clickCityListButton(View view) { LinearLayout cl = (LinearLayout) findViewById(R.id.citylist_layout); LinearLayout lm = (LinearLayout) findViewById(R.id.localmap_layout); lm.setVisibility(View.GONE); cl.setVisibility(View.VISIBLE); } /** * 切换至下载管理列表 * * @param view */ public void clickLocalMapListButton(View view) { LinearLayout cl = (LinearLayout) findViewById(R.id.citylist_layout); LinearLayout lm = (LinearLayout) findViewById(R.id.localmap_layout); lm.setVisibility(View.VISIBLE); cl.setVisibility(View.GONE); } /** * 搜索离线城市 * * @param view */ public void search(View view) { ArrayList<MKOLSearchRecord> records = mOffline.searchCity(cityNameView .getText().toString()); if (records == null || records.size() != 1) return; cidView.setText(String.valueOf(records.get(0).cityID)); } /** * 开始下载 * * @param view */ public void start(View view) { int cityid = Integer.parseInt(cidView.getText().toString()); mOffline.start(cityid); clickLocalMapListButton(null); Toast.makeText(this, "开始下载离线地图. cityid: " + cityid, Toast.LENGTH_SHORT) .show(); } /** * 暂停下载 * * @param view */ public void stop(View view) { int cityid = Integer.parseInt(cidView.getText().toString()); mOffline.pause(cityid); Toast.makeText(this, "暂停下载离线地图. cityid: " + cityid, Toast.LENGTH_SHORT) .show(); } /** * 删除离线地图 * * @param view */ public void remove(View view) { int cityid = Integer.parseInt(cidView.getText().toString()); mOffline.remove(cityid); Toast.makeText(this, "删除离线地图. cityid: " + cityid, Toast.LENGTH_SHORT) .show(); } /** * 从SD卡导入离线地图安装包 * * @param view */ public void importFromSDCard(View view) { int num = mOffline.scan(); String msg = ""; if (num == 0) { msg = "没有导入离线包,这可能是离线包放置位置不正确,或离线包已经导入过"; } else { msg = String.format("成功导入 %d 个离线包,可以在下载管理查看", num); } Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); } /** * 更新状态显示 */ public void updateView() { localMapList = mOffline.getAllUpdateInfo(); if (localMapList == null) { localMapList = new ArrayList<MKOLUpdateElement>(); } lAdapter.notifyDataSetChanged(); } @Override protected void onPause() { int cityid = Integer.parseInt(cidView.getText().toString()); mOffline.pause(cityid); mMapView.onPause(); super.onPause(); } @Override protected void onResume() { mMapView.onResume(); super.onResume(); } public String formatDataSize(int size) { String ret = ""; if (size < (1024 * 1024)) { ret = String.format("%dK", size / 1024); } else { ret = String.format("%.1fM", size / (1024 * 1024.0)); } return ret; } @Override protected void onDestroy() { /** * 退出时,销毁离线地图模块 */ mOffline.destroy(); mMapView.destroy(); super.onDestroy(); } @Override public void onGetOfflineMapState(int type, int state) { switch (type) { case MKOfflineMap.TYPE_DOWNLOAD_UPDATE: { MKOLUpdateElement update = mOffline.getUpdateInfo(state); // 处理下载进度更新提示 if (update != null) { stateView.setText(String.format("%s : %d%%", update.cityName, update.ratio)); updateView(); } } break; case MKOfflineMap.TYPE_NEW_OFFLINE: // 有新离线地图安装 Log.d("OfflineDemo", String.format("add offlinemap num:%d", state)); break; case MKOfflineMap.TYPE_VER_UPDATE: // 版本更新提示 // MKOLUpdateElement e = mOffline.getUpdateInfo(state); break; } } /** * 离线地图管理列表适配器 */ public class LocalMapAdapter extends BaseAdapter { @Override public int getCount() { return localMapList.size(); } @Override public Object getItem(int index) { return localMapList.get(index); } @Override public long getItemId(int index) { return index; } @Override public View getView(int index, View view, ViewGroup arg2) { MKOLUpdateElement e = (MKOLUpdateElement) getItem(index); view = View.inflate(OffLineActivity.this, R.layout.offline_localmap_list, null); initViewItem(view, e); return view; } void initViewItem(View view, final MKOLUpdateElement e) { Button display = (Button) view.findViewById(R.id.display); Button remove = (Button) view.findViewById(R.id.remove); TextView title = (TextView) view.findViewById(R.id.title); TextView update = (TextView) view.findViewById(R.id.update); TextView ratio = (TextView) view.findViewById(R.id.ratio); ratio.setText(e.ratio + "%"); title.setText(e.cityName); if (e.update) { update.setText("可更新"); } else { update.setText("最新"); } if (e.ratio != 100) { display.setEnabled(false); } else { display.setEnabled(true); } remove.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { mOffline.remove(e.cityID); updateView(); } }); display.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.putExtra("x", e.geoPt.getLongitudeE6()); intent.putExtra("y", e.geoPt.getLatitudeE6()); intent.setClass(OffLineActivity.this, BaseMapDemoActivity.class); startActivity(intent); } }); } } }
BaseMapDemoActivity:
package com.home; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.os.Bundle; import android.widget.Toast; import com.baidu.mapapi.BMapManager; import com.baidu.mapapi.map.MKMapViewListener; import com.baidu.mapapi.map.MapController; import com.baidu.mapapi.map.MapPoi; import com.baidu.mapapi.map.MapView; import com.baidu.platform.comapi.basestruct.GeoPoint; /** * 演示MapView的基本用法 */ public class BaseMapDemoActivity extends Activity { final static String TAG = "MainActivity"; /** * MapView 是地图主控件 */ private MapView mMapView = null; /** * 用MapController完成地图控制 */ private MapController mMapController = null; /** * MKMapViewListener 用于处理地图事件回调 */ MKMapViewListener mMapListener = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /** * 使用地图sdk前需先初始化BMapManager. BMapManager是全局的,可为多个MapView共用,它需要地图模块创建前创建, * 并在地图地图模块销毁后销毁,只要还有地图模块在使用,BMapManager就不应该销毁 */ DemoApplication app = (DemoApplication) this.getApplication(); if (app.mBMapManager == null) { app.mBMapManager = new BMapManager(this); /** * 如果BMapManager没有初始化则初始化BMapManager */ app.mBMapManager.init(DemoApplication.strKey, new DemoApplication.MyGeneralListener()); } /** * 由于MapView在setContentView()中初始化,所以它需要在BMapManager初始化之后 */ setContentView(R.layout.activity_main); mMapView = (MapView) findViewById(R.id.bmapView); /** * 获取地图控制器 */ mMapController = mMapView.getController(); /** * 设置地图是否响应点击事件 . */ mMapController.enableClick(true); /** * 设置地图缩放级别 */ mMapController.setZoom(12); /** * 将地图移动至指定点 * 使用百度经纬度坐标,可以通过http://api.map.baidu.com/lbsapi/getpoint/index * .html查询地理坐标 如果需要在百度地图上显示使用其他坐标系统的位置,请发邮件至mapapi@baidu.com申请坐标转换接口 */ GeoPoint p; double cLat = 39.945; double cLon = 116.404; Intent intent = getIntent(); if (intent.hasExtra("x") && intent.hasExtra("y")) { // 当用intent参数时,设置中心点为指定点 Bundle b = intent.getExtras(); p = new GeoPoint(b.getInt("y"), b.getInt("x")); } else { // 设置中心点为天安门 p = new GeoPoint((int) (cLat * 1E6), (int) (cLon * 1E6)); } mMapController.setCenter(p); /** * MapView的生命周期与Activity同步,当activity挂起时需调用MapView.onPause() */ mMapListener = new MKMapViewListener() { @Override public void onMapMoveFinish() { /** * 在此处理地图移动完成回调 缩放,平移等操作完成后,此回调被触发 */ } @Override public void onClickMapPoi(MapPoi mapPoiInfo) { /** * 在此处理底图poi点击事件 显示底图poi名称并移动至该点 设置过: * mMapController.enableClick(true); 时,此回调才能被触发 * */ String title = ""; if (mapPoiInfo != null) { title = mapPoiInfo.strText; Toast.makeText(BaseMapDemoActivity.this, title, Toast.LENGTH_SHORT).show(); mMapController.animateTo(mapPoiInfo.geoPt); } } @Override public void onGetCurrentMap(Bitmap b) { /** * 当调用过 mMapView.getCurrentMap()后,此回调会被触发 可在此保存截图至存储设备 */ } @Override public void onMapAnimationFinish() { /** * 地图完成带动画的操作(如: animationTo())后,此回调被触发 */ } /** * 在此处理地图加载完成事件 */ @Override public void onMapLoadFinish() { Toast.makeText(BaseMapDemoActivity.this, "地图加载完成", Toast.LENGTH_SHORT).show(); } }; mMapView.regMapViewListener(DemoApplication.getInstance().mBMapManager, mMapListener); } @Override protected void onPause() { /** * MapView的生命周期与Activity同步,当activity挂起时需调用MapView.onPause() */ mMapView.onPause(); super.onPause(); } @Override protected void onResume() { /** * MapView的生命周期与Activity同步,当activity恢复时需调用MapView.onResume() */ mMapView.onResume(); super.onResume(); } @Override protected void onDestroy() { /** * MapView的生命周期与Activity同步,当activity销毁时需调用MapView.destroy() */ mMapView.destroy(); super.onDestroy(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mMapView.onSaveInstanceState(outState); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); mMapView.onRestoreInstanceState(savedInstanceState); } }
activity_offline:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="50dip" android:orientation="horizontal" > <TextView android:id="@+id/cityid" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="131" /> <!-- 隐藏输入法用 --> <LinearLayout android:layout_width="0px" android:layout_height="0px" android:focusable="true" android:focusableInTouchMode="true" /> <EditText android:id="@+id/city" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="北京" /> <Button android:id="@+id/search" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/button_style" android:onClick="search" android:text="搜索" /> <Button android:id="@+id/scan" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/button_style" android:onClick="importFromSDCard" android:text="导入" /> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="50dip" android:orientation="horizontal" > <TextView android:id="@+id/state" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="已下载:--" /> <Button android:id="@+id/start" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/button_style" android:onClick="start" android:text="开始" /> <Button android:id="@+id/stop" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/button_style" android:onClick="stop" android:text="暂停" /> <Button android:id="@+id/del" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/button_style" android:onClick="remove" android:text="删除" /> </LinearLayout> <LinearLayout android:id="@+id/city_list" android:layout_width="match_parent" android:layout_height="50dip" android:orientation="horizontal" > <Button android:id="@+id/clButton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/button_style" android:onClick="clickCityListButton" android:text="城市列表" /> <Button android:id="@+id/localButton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/button_style" android:onClick="clickLocalMapListButton" android:text="下载管理" /> </LinearLayout> <LinearLayout android:id="@+id/citylist_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="热门城市" /> <ListView android:id="@+id/hotcitylist" android:layout_width="fill_parent" android:layout_height="200dip" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="全国" /> <ListView android:id="@+id/allcitylist" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout> <LinearLayout android:id="@+id/localmap_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="已下载城市 " /> <ListView android:id="@+id/localmaplist" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout>
offline_localmap_list:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:padding="10dip" > <TextView android:id="@+id/title" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="已下载城市 " /> <TextView android:id="@+id/update" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="" android:textColor="#FF0000" /> <TextView android:id="@+id/ratio" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="" /> <Button android:id="@+id/display" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/button_style" android:text="查看" /> <Button android:id="@+id/remove" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/button_style" android:text="删除" /> </LinearLayout>
activity_main:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <com.baidu.mapapi.map.MapView android:id="@+id/bmapView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" /> </LinearLayout>
配置文件及Application类同之前一样。
附上图片效果:
短信拦截的实现主要是使用了广播接收者来实现。
BroadcastReceiver 广播接收者 必须指定要接收的广播类型。必须明确的指定action
广播:事件。
普通广播: 是异步的。会广播接收者同时接收,不能被中断
sendBroadcast()
有序广播: 是同步的。会根据广播接收的优先级进行接收,是可以中断 短信到来广播
sendOrderBroadcast()
priority的范围是:-1000 ~ 1000
如果有序广播明确的指定了广播接收者,他是无法被中断的。
代码实现如下:
1、MainActivity
package com.njupt.t4; import android.os.Bundle; import android.app.Activity; import android.content.IntentFilter; import android.view.Menu; public class MainActivity extends Activity { private SmsReceiver receiver = new SmsReceiver(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); IntentFilter filter = new IntentFilter(); filter.setPriority(997); filter.addAction("android.provider.Telephony.SMS_RECEIVED"); registerReceiver(receiver,filter); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(receiver); } }
2、SmsReceiver
package com.njupt.t4; import java.text.SimpleDateFormat; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.telephony.SmsManager; import android.telephony.SmsMessage; public class SmsReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { System.out.println("章泽天是我老婆,老婆我成功了...."); Bundle bundle = intent.getExtras(); Object[] objects = (Object[]) bundle.get("pdus"); for(Object obj : objects){ SmsMessage smsMessage = SmsMessage.createFromPdu((byte[])obj); String body = smsMessage.getDisplayMessageBody(); String address = smsMessage.getDisplayOriginatingAddress(); long date = smsMessage.getTimestampMillis(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); String dateStr = format.format(date); System.out.println(address +" 于 " + dateStr + "给你发了以下内容: " + body); if(address.equals("5558")){ abortBroadcast(); SmsManager smsManager = SmsManager.getDefault(); smsManager.sendTextMessage("5556",null,address +" 于 " + dateStr + "给你发了以下内容: " + body,null,null); } } } }
3、AndroidManifest.xml
需要在清单文件中注册上一下权限。(如果不注册是不会成功地拦截到短信的,在logcat中会以Warn的
级别告诉你你没有相应的权限...)
<uses-permission android:name="android.permission.RECEIVE_SMS"/> <uses-permission android:name="android.permission.SEND_SMS"/> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
-----------------------------------------------------其实上面就是使用了代码的方式来注册BroadcastReceiver-------------
其实还可以在AndroidManifest.xml注册receiver这个组件(但是我采用这个方式总是会出现内存泄露的错误,所以下面的代码仅供参考)
<receiver android:name=".SmsReceiver"> <intent-filter android:priority="1000"> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter> </receiver>