前言:《Bmob》是一个可以开发云存储的移动应用软件,给应用软件快速添加一个安全灵活的后台管理系统,方便浏览终端保存的各种信息。针对移动应用开发的特性,Bmob还提供了主动推送服务.
可以让移动开发者将信息从服务器直接推送到应用程序中,从而实现软件的主动更新、信息通知等服务
1、首先注册Bmob账号,地址:https://www.bmob.cn/register
不想注册可使用APP ID:4dacb15a8bcea4f9dd2f78cb9b544f89 作为测试使用
①:注册成功后进入我的控制台>>左上角创建应用如下图:
关于版本的收费情况以及功能介绍:https://www.bmob.cn/prices
②、创建应用后点开该应用,找到左边设置按钮查看对应的应用信息
2、找到主工程的build.gradle添加Bmob的依赖,如下图所示:
①:
maven { url "https://raw.github.com/bmob/bmob-android-sdk/master" }
②:回到app的build.gradle中:
android {
useLibrary 'org.apache.http.legacy'
}
dependencies {
implementation 'cn.bmob.android:bmob-sdk:3.7.3-rc1'
implementation "io.reactivex.rxjava2:rxjava:2.2.2"
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'com.squareup.okio:okio:2.1.0'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.squareup.okhttp3:okhttp:3.12.0'
implementation 'cn.bmob.android:http-legacy:1.0'
}
注意:useLibrary 'org.apache.http.legacy’和implementation ‘cn.bmob.android:http-legacy:1.0’
两者任选其一
③:AndroidManifest.xml清单文件中添加权限:
<!--允许联网 -->
<uses-permission android:name="android.permission.INTERNET" />
<!--获取GSM(2g)、WCDMA(联通3g)等网络状态的信息 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--获取wifi网络状态的信息 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--保持CPU 运转,屏幕和键盘灯有可能是关闭的,用于文件上传和下载 -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!--获取sd卡写的权限,用于文件上传和下载-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--允许读取手机状态 用于创建BmobInstallation-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
④:配置ContentProvider
<application>
···
<provider
android:name="cn.bmob.v3.util.BmobContentProvider"
android:authorities="你的应用包名.BmobContentProvider">
</provider>
···
</application>
⑤:注册MyApplication代码如下:
public class MyApplication extends Application {
private static final String TAG = "MyApplication";
@Override
public void onCreate() {
super.onCreate();
//初始化Bmob后端
//自v3.4.7版本开始,设置BmobConfig,允许设置请求超时时间、文件分片上传时每片的大小、文件的过期时间(单位为秒),
BmobConfig config = new BmobConfig.Builder(this)
.setApplicationId("4dacb15a8bcea4f9dd2f78cb9b544f89")//设置appkey
.setConnectTimeout(15)//请求超时时间(单位为秒):默认15s
.setUploadBlockSize(1024 * 1024)//文件分片上传时每片的大小(单位字节),默认512*1024
.setFileExpiration(2500)//文件的过期时间(单位为秒):默认1800s
.build();
Bmob.initialize(config);
//TODO 初始化Bmob推送服务(不需要注释以下代码)
BmobInstallationManager.getInstance().initialize(new InstallationListener<BmobInstallation>() {
@Override
public void done(BmobInstallation bmobInstallation, BmobException e) {
if (e == null) {
Log.e(TAG, "推送成功ID:" + bmobInstallation.getObjectId()
+ "-" + bmobInstallation.getInstallationId());
} else {
//LogUtils.e("推送失败信息:" + e.getMessage());
Log.e(TAG, "推送失败信息:" + e.getMessage());
}
}
});
// 启动推送服务
BmobPush.startWork(this);
}
}
最后在AndroidManifest的application 添加 android:name=".MyApplication"
如果需要推送服务添加如下代码:
implementation 'cn.bmob.android:bmob-push:1.0.3'
3、代码部分:创建地址实体类AddressManagerDto
public class AddressManagerDto extends BmobObject implements Serializable {
//收货人
private String consignee;
//手机号码
private String phoneNumber;
//省
private String province;
//市
private String city;
//区
private String area;
//省市区
private String provinces;
//详细地址
private String detailedAddress;
//是否是默认地址
private boolean isDefault;
//唯一标识不可重复
private String uuid;
//所属账户
private String account;
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getConsignee() {
return consignee;
}
public void setConsignee(String consignee) {
this.consignee = consignee;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getArea() {
return area;
}
public void setArea(String area) {
this.area = area;
}
public String getProvinces() {
return provinces;
}
public void setProvinces(String provinces) {
this.provinces = provinces;
}
public String getDetailedAddress() {
return detailedAddress;
}
public void setDetailedAddress(String detailedAddress) {
this.detailedAddress = detailedAddress;
}
public boolean isDefault() {
return isDefault;
}
public void setDefault(boolean aDefault) {
isDefault = aDefault;
}
}
①:新增
private void addTheAddress() {
AddressManagerDto managerDto = new AddressManagerDto();
managerDto.setConsignee("张三");
managerDto.setPhoneNumber("18888888888");
managerDto.setProvinces("江西省南昌市青云谱区");
managerDto.setDetailedAddress("罗湖街道110号");
managerDto.setDefault(true);//是默认地址
managerDto.setUuid(UUID.randomUUID().toString());//唯一标识(https://blog.csdn.net/yxiaom/article/details/17117519)
managerDto.setAccount("李四");
managerDto.save(new SaveListener<String>() {
@Override
public void done(String objectId, BmobException e) {
//错误为null标识保存成功
if (null != e) {
//保存成功
} else {
//保存失败
//e.getErrorCode();e.getMessage();
}
}
});
}
新增成功后如下图:
系统默认生成字段 createdAt 创建时间和 updatedAt 更新时间 以及objectID
②:查询
private void queryAddress() {
BmobQuery<AddressManagerDto> query = new BmobQuery<>();
//1、比较查询
//【等于】(例:查询收货人为张三的)
query.addWhereEqualTo("consignee", "张三");
//【不等于】(例:查询收货人不为张三的)
query.addWhereNotEqualTo("consignee", getPhone());
//【小于】
query.addWhereLessThan("查询字段", "值");
//【小于等于】
query.addWhereLessThanOrEqualTo("查询字段", "值");
//【大于】
query.addWhereGreaterThan("查询字段", "值");
//【大于等于】
query.addWhereGreaterThanOrEqualTo("查询字段", "值");
//2、子查询 (例:查询收货人为张三、李四、王五)
String[] names = {"张三", "李四", "王五"};
query.addWhereContainedIn("consignee", Arrays.asList(names));
//相反的(例:排除收货人为张三、李四、王五)
query.addWhereNotContainedIn("consignee", Arrays.asList(names));
//3、时间查询(同比较查询一致)
String createdAt = "2019-11-23 10:30:00";
query.addWhereEqualTo("createdAt", createdAt);//时间等于
query.addWhereNotEqualTo("createdAt", createdAt);//时间外
//query.addWhereLessThan("createdAt", createdAt);//时间前
//query.addWhereLessThanOrEqualTo("createdAt", createdAt);//时间及以前
//query.addWhereGreaterThan("createdAt", createdAt);//时间后
//query.addWhereGreaterThanOrEqualTo("createdAt", createdAt);//时间及以后
//4、数组查询 【包含所有 例:查询A、B、C用户】
String[] alias = new String[]{"A", "B", "C"};
query.addWhereContainsAll("consignee", Arrays.asList(alias));
//5、模糊查询【正则表达式来检索相匹配的值】
query.addWhereMatches("consignee", "^[A-Z]\\d");
//查询consignee字段的值含有“张”的数据
query.addWhereContains("consignee", "张");
//查询consignee字段的值是以“张“字开头的数据
query.addWhereStartsWith("consignee", "张");
// 查询consignee字段的值是以“三“字结尾的数据
query.addWhereEndsWith("consignee", "三");
//分页查询【Limit的值为100,最大有效设置值500(设置的数值超过500还是视为500)】
query.setLimit(20);
query.setSkip(20);//忽略前20条数据(即第一页数据结果)
// 根据score字段升序显示数据
query.order("score");
// 根据score字段降序显示数据
query.order("-score");
//多个排序字段可以用(,)号分隔
query.order("-score,createdAt");//createdAt默认生成
//说明:多个字段排序时,先按第一个字段进行排序,再按第二个字段进行排序,依次进行。
query.findObjects(new FindListener<AddressManagerDto>() {
@Override
public void done(List<AddressManagerDto> list, BmobException e) {
if (null == e) {
//查询成功
} else {
//查询失败
}
}
});
}
③:修改
private void updateAddress() {
//1、更新对象
AddressManagerDto managerDto = new AddressManagerDto();
managerDto.setConsignee("李四");
managerDto.setPhoneNumber("16666666666");
managerDto.setProvinces("北京市东城区");
managerDto.setDetailedAddress("三里屯鹿角大道");
//2更新数组
//更新String类型数组中的值
managerDto.setValue("张三", "李四");//将张三中第一个位置的修改为李四
//更新Object类型数组中的某个位置的对象值(0对应集合中第一个元素)
//p2.setValue("张三", new AddressManagerDto("张三", "李四"));//将地址中第一个位置修改为指定AddressManagerDto对象
//更新Object类型数组中指定对象的指定字段的值
//p2.setValue("AddressManagerDto.0.consignee", "王五");//将AddressManagerDto中第一个位置的银行卡名称修改为王五
//p2.setValue("AddressManagerDto.1.consignee", "王五");//将AddressManagerDto中第二个位置的银行卡账号修改为王五
//例如:在列表中可通过【list.get(position).getObjectID()来获取】
managerDto.update("更新的objectId", new UpdateListener() {
@Override
public void done(BmobException e) {
if (e == null) {
//更新成功
} else {
//更新失败
}
}
});
}
④:删除
private void deleteAddress(final int position) {
String objectId = list.get(position).getObjectId();
//1、删除对象
AddressManagerDto managerDto = new AddressManagerDto();
//2、删除数组
managerDto.removeAll("consignee", Arrays.asList("张三","李四","王五"));
//例:list.get(position).getObjectId()
managerDto.delete(objectId, new UpdateListener() {
@Override
public void done(BmobException e) {
if (e == null) {
//删除成功
} else {
//删除失败
}
}
});
}
⑤:上传文件需要域名,19年7月份之前是不用的,找到应用设置的域名管理,如下图所示:
注意:一定需要【国内的】已经【备案】的域名,香港、国外的都不行
1、上传文件代码,以图片为例:
/**
* 上传图片单张
* path:图片的路径
*/
private void uploadImgPath(String path) {
final BmobFile file = new BmobFile(new File(path));
file.uploadblock(new UploadFileListener() {
@Override
public void done(BmobException e) {
if (null == e) {
//上传成功
} else {
//上传失败
}
}
@Override
public void onProgress(Integer value) {
super.onProgress(value);
//上传进度
}
});
}
/**
* 多张图片上传
*/
private void uploadImgPath() {
//本地图片路径
String path1 = "test1.png";
String path2 = "test2.png";
String path3 = "test3.png";
String[] filePaths = new String[3];
filePaths[0] = path1;
filePaths[1] = path2;
filePaths[2] = path3;
BmobFile.uploadBatch(filePaths, new UploadBatchListener() {
@Override
public void onSuccess(List<BmobFile> files, List<String> urls) {
//1、files-上传完成后的BmobFile集合,是为了方便大家对其上传后的数据进行操作,例如你可以将该文件保存到表中
//2、urls-上传文件的完整url地址
if (urls.size() == filePaths.length) {
//如果数量相等,则代表文件全部上传完成
}
}
@Override
public void one rror(int statuscode, String errormsg) {
//"错误码" + statuscode + ",错误描述:" + errormsg
}
@Override
public void onProgress(int curIndex, int curPercent, int total, int totalPercent) {
//1、curIndex--表示当前第几个文件正在上传
//2、curPercent--表示当前上传文件的进度值(百分比)
//3、total--表示总的上传文件数
//4、totalPercent--表示总的上传进度(百分比)
}
});
}
2、推送部分,在AndroidManifest.xml清单文件中配置如下代码:
<provider
android:name="cn.bmob.v3.util.BmobContentProvider"
android:authorities="你的应用包名.BmobContentProvider" /> <!-- TODO 集成:1.2、添加推送所需要的服务和广播 -->
<service
android:name="cn.bmob.push.lib.service.PushService"
android:exported="true"
android:label="PushService"
android:process=":bmobpush">
<intent-filter>
<action android:name="cn.bmob.push.lib.service.PushService" />
</intent-filter>
</service> <!-- 用于进程保活 -->
<service
android:name="cn.bmob.push.lib.service.PushNotifyService"
android:process=":bmobpush" />
<receiver android:name="cn.bmob.push.PushReceiver">
<intent-filter>
<!-- 系统启动完成后会调用 -->
<action android:name="android.intent.action.BOOT_COMPLETED" />
<!-- 解锁完成后会调用 -->
<action android:name="android.intent.action.USER_PRESENT" />
<!-- 监听网络连通性 -->
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver> <!-- 第3步中创建的消息接收器,在这里进行注册 -->
<receiver android:name=".MyPushMessageReceiver">
<intent-filter>
<action android:name="cn.bmob.push.action.MESSAGE" />
</intent-filter>
</receiver> <!-- 接收心跳和唤醒的广播,要和PushService运行在同个进程 -->
<receiver
android:name="cn.bmob.push.PushNotifyReceiver"
android:process=":bmobpush">
<intent-filter>
<!-- 接收心跳广播的action -->
<action android:name="cn.bmob.push.action.HEARTBEAT" />
<!-- 接收唤醒广播的action -->
<action android:name="cn.bmob.push.action.NOTIFY" />
</intent-filter>
</receiver>
新建MyPushMessageReceiver类:
public class MyPushMessageReceiver extends BroadcastReceiver {
private static final String TAG = "MyPushMessageReceiver";
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(PushConstants.ACTION_MESSAGE)) {
String notic = intent.getStringExtra("msg");
try {
JSONObject object = new JSONObject(notic);
String str = object.getString("alert");
Log.e(TAG, "onReceive: " + str);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
回到Bmob控制台:
状态码链接:http://doc.bmob.cn/other/error_code/
官方文档:http://doc.bmob.cn/