一.Bmob云服务简介
Bomb是一个移动后端云服务平台,提供了后端服务器的数据服务,文件服务,推送服务等,让开发者可以专注客户端的开发,从而达到快速构建一个APP的目的。
二.入门与BmobSDK集成
1.快速入门
①首先注册Bmob帐号
在网址栏输入www.bmob.cn或者在百度输入Bmob进行搜索,打开Bmob官网后,点击右上角的“注册”,在跳转页面填入你的姓名、邮箱、设置密码,确认后到你的邮箱激活Bmob账户,你就可以用Bmob轻松开发应用了。
②网站后台创建应用
登录账号进入bmob后台后,点击后台界面左上角“创建应用”,在弹出框输入你应用的名称,然后确认,你就拥有了一个等待开发的应用。
③获取应用密钥和下载SDK
创建应用
在应用key中可以获取所需要的密钥
Application ID:SDK初始化必须用到此密钥
REST API Key:REST API请求中HTTP头部信息必须附带密钥之一
Secret Key:是SDK安全密钥,不可泄漏,在云函数测试云函数时需要用到
Master Key:超级权限Key。应用开发或调试的时候可以使用该密钥进行各种权限的操作,此密钥不可泄漏
④SDK的下载与导入
1)下载SDK(下载地址:http://www.bmob.cn/site/sdk#android_sdk)
2)推荐使用自动导入,手动导入会出现jar冲突等
首先在 Project 的 build.gradle 文件中添加 Bmob的maven仓库地址
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
}
}
allprojects {
repositories {
jcenter()
//Bmob的maven仓库地址--必填
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'
}
注:
[1]、v3.6.8-rc2开始,远程仓库中数据SDK包含了libbmob.so及自动更新组件所需要的资源文件。
[2]、每个版本的im依赖特定版本的bmob-sdk:
bmob-im:1.1.8--->bmob-sdk:3.3.5
bmob-im:1.1.9--->bmob-sdk:3.4.3
bmob-im:2.0.1--->bmob-sdk:3.4.6-0304
bmob-im:2.0.2--->bmob-sdk:3.4.6-0304
bmob-im:2.0.3--->bmob-sdk:3.4.6
bmob-im:2.0.4--->bmob-sdk:3.4.6
bmob-im:2.0.5--->bmob-sdk:3.4.7-aar
bmob-im:2.0.6--->bmob-sdk:3.5.0
其中
bmob-sdk:3.4.6-0304是Bmob Android SDK的过渡版本,主要用于NewIM_v2.0.1及v2.0.2
bmob-sdk:3.4.6的相关依赖包可见注释[3]
[3]、bmob-sdk:3.4.6依赖以下包:
implementation 'cn.bmob.android:bmob-sdk:3.4.6'
implementation 'com.squareup.okhttp:okhttp:2.4.0'//CDN文件服务使用okhttp相关包进行文件的上传和下载(必填)
implementation 'com.squareup.okio:okio:1.4.0'
[4]、bmob-sms适用于只需要使用Bmob短信功能的开发者,而bmob-sdk内部包含了bmob-sms的短信功能,请不要重复添加。
[5]、BmobSDK的官方仓库:bmob-android-sdk,开发者可到此仓库查看最新发布的各版本SDK,我们会尽量与官网发布的SDK保持同步更新。
2.SDK集成
所需权限说明
<!--允许联网 -->
<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" />
配置AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.bmob.example"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name="cn.bmob.example.MainActivity"
android:screenOrientation="portrait"
android:label="@string/app_name">
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<activity
android:name=".CreateActivity"
android:screenOrientation="portrait">
<activity
android:name=".DeleteActivity"
android:screenOrientation="portrait">
<activity
android:name=".UpdateActivity"
android:screenOrientation="portrait">
<activity
android:name=".FindActivity"
android:screenOrientation="portrait">
</application>
</manifest>
配置ContentProvider
<application>
···
<provider
android:name="cn.bmob.v3.util.BmobContentProvider"
android:authorities="你的应用包名.BmobContentProvider">
</provider>
···
</application>
初始化BmobSDK
在你应用程序启动的Application的onCreate()方法中初始化Bmob功能
Bmob.initialize(this, "Your Application ID");
三.Bmob数据库的增删查改
1.添加数据
创建JavaBean
public class Person extends BmobObject {
private String name;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
添加数据
Person p2 = new Person();
p2.setName("lucky");
p2.setAddress("北京海淀");
p2.save(new SaveListener<String>() {
@Override
public void done(String objectId,BmobException e) {
if(e==null){
toast("添加数据成功,返回objectId为:"+objectId);
}else{
toast("创建数据失败:" + e.getMessage());
}
}
});
2.删除数据
Person p2 = new Person();
p2.setObjectId("6b6c11c537");
p2.delete(new UpdateListener() {
@Override
public void done(BmobException e) {
if(e==null){
toast("删除成功:"+p2.getUpdatedAt());
}else{
toast("删除失败:" + e.getMessage());
}
}
});
3.查询数据
//查找Person表里面id为6b6c11c537的数据
BmobQuery<Person> bmobQuery = new BmobQuery<Person>();
bmobQuery.getObject("6b6c11c537", new >QueryListener<Person>() {
@Override
public void done(Person object,BmobException e) {
if(e==null){
toast("查询成功");
}else{
toast("查询失败:" + e.getMessage());
}
}
});
4.修改数据
//更新Person表里面id为6b6c11c537的数据,address内容更新为“北京朝阳”
Person p2 = new Person();
p2.setAddress("北京朝阳");
p2.update("6b6c11c537", new UpdateListener() {
@Override
public void done(BmobException e) {
if(e==null){
toast("更新成功:"+p2.getUpdatedAt());
}else{
toast("更新失败:" + e.getMessage());
}
}
});
四.简单的登录注册案例
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.lenovo.bmobc">
<!-- 允许联网 -->
<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" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
</activity>
<activity android:name=".LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".RegActivity"/>
<provider
android:name="cn.bmob.v3.util.BmobContentProvider"
android:authorities="com.example.lenovo.bmobc.BmobContentProvider">
</provider>
</application>
</manifest>
Person.java
import cn.bmob.v3.BmobObject;
public class Person extends BmobObject {
private String name;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Person{" +
"address='" + address + '\'' +
", name='" + name + '\'' +
'}';
}
}
User.java
import cn.bmob.v3.BmobUser;
import cn.bmob.v3.datatype.BmobFile;
public class User extends BmobUser {
private BmobFile icon;
public BmobFile getIcon() {
return icon;
}
public void setIcon(BmobFile icon) {
this.icon = icon;
}
}
LoginActivity.java
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import cn.bmob.v3.Bmob;
import cn.bmob.v3.BmobUser;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.SaveListener;
public class LoginActivity extends AppCompatActivity {
private EditText editText_username, editText_password;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// 初始化 Bmob SDK
// 使用时请将第二个参数Application ID替换成你在Bmob服务器端创建的Application ID
Bmob.initialize(this, "8f6ee1e358d294d3fed2fe3b338c178b");
editText_username = (EditText) findViewById(R.id.editText_username);
editText_password = (EditText) findViewById(R.id.editText_password);
}
//用户登录
public void loginClick(View v) {
String username = editText_username.getText().toString();
String password = editText_password.getText().toString();
final BmobUser bmobUser = new BmobUser();
bmobUser.setUsername(username);
bmobUser.setPassword(password);
bmobUser.login(new SaveListener<User>() {
@Override
public void done(User bmobUser, BmobException e) {
if (e == null) {
User user = BmobUser.getCurrentUser(User.class);
Toast.makeText(LoginActivity.this, "登录成功", Toast.LENGTH_LONG).show();
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
intent.putExtra("user", user);
startActivity(intent);
} else {
Toast.makeText(LoginActivity.this, "登录失败", Toast.LENGTH_LONG).show();
}
}
});
}
public void registerClick(View v) {
Intent intent = new Intent(this, RegActivity.class);
startActivity(intent);
}
}
RegActivity.java
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import java.io.File;
import cn.bmob.v3.datatype.BmobFile;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.SaveListener;
import cn.bmob.v3.listener.UploadFileListener;
public class RegActivity extends AppCompatActivity {
private EditText editText_name, editText_password, editText_email, editText_icon;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reg);
editText_name = (EditText) findViewById(R.id.editText_username);
editText_password = (EditText) findViewById(R.id.editText_password);
editText_email = (EditText) findViewById(R.id.editText_email);
editText_icon = (EditText) findViewById(R.id.editText_icon);
}
//注册功能
public void registerClick(View v) {
final String name = editText_name.getText().toString();
final String password = editText_password.getText().toString();
final String email = editText_email.getText().toString();
/**
* 账号密码注册
*/
User user = new User();
user.setUsername("" + System.currentTimeMillis());
user.setPassword("" + System.currentTimeMillis());
user = new User();
user.setUsername(name);
user.setPassword(password);
user.setEmail(email);
user.signUp(new SaveListener<User>() {
@Override
public void done(User user, BmobException e) {
if (e == null) {
Toast.makeText(RegActivity.this, "注册成功", Toast.LENGTH_LONG).show();
Intent intent = new Intent(RegActivity.this, LoginActivity.class);
startActivity(intent);
} else {
Toast.makeText(RegActivity.this, "注册失败", Toast.LENGTH_SHORT).show();
}
}
});
}
}
MainActivity.java
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import cn.bmob.v3.BmobQuery;
import cn.bmob.v3.datatype.BmobFile;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.DownloadFileListener;
import cn.bmob.v3.listener.QueryListener;
import cn.bmob.v3.listener.SaveListener;
import cn.bmob.v3.listener.UpdateListener;
public class MainActivity extends AppCompatActivity {
private TextView textView;
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化 Bmob SDK
// 使用时请将第二个参数Application ID替换成你在Bmob服务器端创建的Application ID
//Bmob.initialize(this, "获取到的Application ID");
textView = (TextView) findViewById(R.id.textView);
iv = (ImageView) findViewById(R.id.imageView_icon);
Intent intent = getIntent();
User user = (User) intent.getSerializableExtra("user");
textView.setText(user.getUsername() + "," + user.getEmail());
}
//添加数据
public void addClick(View view) {
Person p2 = new Person();
p2.setName("小明");
p2.setAddress("浙江");
p2.save(new SaveListener<String>() {
@Override
public void done(String objectId,BmobException e) {
if(e==null){
Toast.makeText(MainActivity.this, "添加数据成功,返回objectId为:"+objectId, Toast.LENGTH_LONG).show();
}else{
Toast.makeText(MainActivity.this, "创建数据失败:" + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
});
}
//删除数据
public void delClick(View view) {
Person p2 = new Person();
p2.setObjectId("填写从Bmob数据库中获取的objectId");
p2.delete(new UpdateListener() {
@Override
public void done(BmobException e) {
if(e==null){
Toast.makeText(MainActivity.this,"删除成功", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(MainActivity.this,"删除失败:" + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
});
}
//更新数据
public void updateClick(View view) {
Person p2 = new Person();
p2.setAddress("北京");
p2.update("填写从Bmob数据库中获取的objectId", new UpdateListener() {
@Override
public void done(BmobException e) {
if(e==null){
Toast.makeText(MainActivity.this,"更新成功", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(MainActivity.this,"更新失败:" + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
});
}
//查询数据
public void queryClick(View view) {
BmobQuery<Person> bmobQuery = new BmobQuery<Person>();
bmobQuery.getObject("a96e6beea8", new QueryListener<Person> (){
@Override
public void done(Person object,BmobException e) {
if(e==null){
Toast.makeText(MainActivity.this,"查询成功", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(MainActivity.this,"查询失败:" + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
});
}
}
activity_login.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LoginActivity">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:hint="用户名"
android:id="@+id/editText_username"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:ems="10"
android:hint="密码"
android:id="@+id/editText_password"
android:layout_below="@+id/editText_username"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/editText_username"
android:layout_alignEnd="@+id/editText_username" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登录"
android:id="@+id/button_login"
android:onClick="loginClick"
android:layout_marginLeft="105dp"
android:layout_marginStart="105dp"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="注册"
android:onClick="registerClick"
android:id="@+id/button_register"
android:layout_alignTop="@+id/button_login"
android:layout_toRightOf="@+id/button_login"
android:layout_toEndOf="@+id/button_login" />
</RelativeLayout>
activity_reg.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".RegActivity">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:text=""
android:hint="请输入名称"
android:ems="10"
android:id="@+id/editText_username"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:ems="10"
android:hint="请输入密码"
android:id="@+id/editText_password"
android:layout_below="@+id/editText_username"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/editText_username"
android:layout_alignEnd="@+id/editText_username" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:ems="10"
android:hint="请输入邮箱"
android:id="@+id/editText_email"
android:layout_below="@+id/editText_password"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/editText_password"
android:layout_alignEnd="@+id/editText_password" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/editText_icon"
android:layout_below="@+id/editText_email"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/editText_email"
android:layout_alignEnd="@+id/editText_email" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="注册"
android:id="@+id/button_register"
android:onClick="registerClick"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="128dp" />
</RelativeLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bmob云服务测试"
android:id="@+id/textView"
android:textSize="36px"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="添加数据"
android:onClick="addClick"
android:id="@+id/button_add"
android:layout_below="@+id/textView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="删除数据"
android:onClick="delClick"
android:id="@+id/button_del"
android:layout_below="@+id/button_add"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="修改数据"
android:onClick="updateClick"
android:id="@+id/button_update"
android:layout_below="@+id/button_del"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查询数据"
android:onClick="queryClick"
android:id="@+id/button_query"
android:layout_below="@+id/button_update"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView_icon"
android:layout_below="@+id/button_query"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>