我的本意是第二篇写Mob的shareSDK分享组件的,奈何需要去注册各平台的账号,还要审核,有些审核还挺久,就没办法,改为写这个Bmob了,相信大家对Bmob都是挺期待的吧,因为他作为Android后端的实现很好的支持,国内很多软件都在使用它,他的功能也是特别神奇,这里就不一一细说了,我们用实际的例子来见证他的神奇
注意本教程是根据Bmob官方教程改写
我们当然不可能按部就班的找些上面写,不过入门都是一样的,我们这些流程还是得走一遍,这样才更有利于你对Bmob的认知和了解
我们首先新建一个工程,以Eclipse为例哈,也是为了编写小Demo方便
然后我们打开Bmob的官网去创建我们的项目
控制面板
创建项目
项目列表
相关的一些key
好了,我们得到了我们想要的key了,我们就可以开始编写了
这个相信都不用多说了
鉴于目前Google官方推荐使用 Android Studio 进行Android项目开发,自 V3.4.2 开始,Bmob Android SDK 可以使用Gradle来进行包依赖管理,如果你使用Android Studio来进行基于BmobSDK的项目开发
1.在Project的build.gradle文件中添加如下配置(注意文字说明部分)
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" }
}
}
2、在app的build.gradle文件中添加如下配置(注意文字说明部分):
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion '22.0.1'
defaultConfig {
applicationId "cn.bmob.android"
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions{
abortOnError false
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'
//以下SDK开发者请根据需要自行选择
//bmob-sdk :Bmob的android sdk包
compile 'cn.bmob.android:bmob-sdk:3.4.5'
//bmob-push:Bmob的推送包
compile 'cn.bmob.android:bmob-push:0.6'
//bmob-im:bmob的im包,以下两个配置是im功能所需
compile 'cn.bmob.android:bmob-im:1.1.9'
compile 'cn.bmob.android:bmob-sdk:3.4.3'
//okhttp(选填):为解决弱网情况下SDK请求失败及响应慢的问题,自`V3.4.3版本`开始使用`okhttp`优化SDK的网络框架。
compile 'com.squareup.okhttp:okhttp:2.4.0'
compile 'com.squareup.okio:okio:1.4.0'
//bmob-sms :Bmob单独为短信服务提供的包
compile 'cn.bmob.android:bmob-sms:1.0.1'
}
注:
1、如果你只需要Bmob提供的短信功能,那么你只需单独配置bmob-sms,如果你既需要bmob的数据服务,也需要短信服务,那么你只需要配置bmob-sdk即可。
2、每个版本的im都对应特定版本的bmob-sdk,如果你使用的是1.1.8版本的im,那么配套的bmob-sdk的版本为3.3.5。使用的是1.1.9配套的bmob-sdk的版本为3.4.3.
3、与okhttp有关的配置依赖不是必填项,开发者可以不添加该依赖。
直接拷贝到lib目录下
下面的例子均在Eclipse环境下完成
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_LOGS"/>
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
// 初始化 Bmob SDK
// 使用时请将第二个参数Application ID替换成你在Bmob服务器端创建的Application ID
Bmob.initialize(this, "Your Application ID");
}
}
首先我们把布局添加一下
<LinearLayout 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"
android:orientation="vertical" >
<Button
android:id="@+id/btn_add"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="添加数据" />
<Button
android:id="@+id/btn_update"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="更新数据" />
<Button
android:id="@+id/btn_delete"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="删除数据" />
<Button
android:id="@+id/btn_query"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="查询数据" />
</LinearLayout>
然后实例化这四个Button
private Button btn_add, btn_update, btn_delete, btn_query;
btn_add = (Button) findViewById(R.id.btn_add);
btn_add.setOnClickListener(this);
btn_update = (Button) findViewById(R.id.btn_update);
btn_update.setOnClickListener(this);
btn_delete = (Button) findViewById(R.id.btn_delete);
btn_delete.setOnClickListener(this);
btn_query = (Button) findViewById(R.id.btn_query);
btn_query.setOnClickListener(this);
因为考虑到有四个点击事件,我们直接implements OnClickListener这样也许更直观一点,所以onClick()方法就是这个样子了
@Override
public void onClick(View v) {
switch (v.getId()) {
//添加数据
case R.id.btn_add:
break;
//更新数据
case R.id.btn_update:
break;
//删除数据
case R.id.btn_delete:
break;
//查询数据
case R.id.btn_query:
break;
}
}
准备工作差不多都做完了?No,还有一件非常重要的事情要做
我们新建一个类继承BmobObject,具体操作看注释
package com.lgl.bmobdemo;
import cn.bmob.v3.BmobObject;
/** * javabean * * @author lgl * */
public class Bean extends BmobObject {
/** * 这个javabean必须视情况而定,也就是你需要你的表上有什么信息你就加什么,当然,前提是,你的表单上有 * 添加表单可以在Bmob应用控制-数据浏览页面操作,后续会讲到 这里,我们假设有三个信息数据,分别是姓名,年龄,分数 */
private String name;
private int age;
private int score;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
}
其实就是调用了Bean的get,set方法
case R.id.btn_add:
// new出这个bean
Bean bean = new Bean();
// 分别设置相应的信息
bean.setName("刘桂林");
bean.setAge(20);
bean.setScore(100);
bean.save(this, new SaveListener() {
@Override
public void onSuccess() {
// 成功
Toast.makeText(MainActivity.this, "保存成功", 1)
.show();
}
@Override
public void onFailure(int arg0, String arg1) {
// 失败
Toast.makeText(MainActivity.this, "保存失败", Toast.LENGTH_LONG)
.show();
}
});
break;
我们运行程序,然后点击添加数据,当弹出Toast说明保存成功后,我们回到Bmob官网,找到我们的项目,点击数据浏览,就会看到已经保存的信息,这个就是我们的后台了
更新数据,就是更新一条数据的记录,就像你修改个人信息,本来是男,现在要修改成女一样,但是,我们必须知道一点,就是如下图所示的objectid
case R.id.btn_update:
bean = new Bean();
bean.setObjectId("edec38a77d");
bean.setName("修改刘桂林");
bean.setScore(30);
bean.update(this, new UpdateListener() {
@Override
public void onSuccess() {
// 成功
Toast.makeText(MainActivity.this, "更新成功", 1).show();
}
@Override
public void onFailure(int arg0, String arg1) {
// 失败
Toast.makeText(MainActivity.this, "更新失败", 1).show();
}
});
break;
然后我们来运行程序,点击更新数据,然后我们回到后台去查看
同样的,你要删除一条数据,你还得知道人家的objectid
case R.id.btn_delete:
bean = new Bean();
bean.setObjectId("edec38a77d");
bean.delete(this, new DeleteListener() {
@Override
public void onSuccess() {
//成功
Toast.makeText(MainActivity.this, "删除成功", 1).show();
}
@Override
public void onFailure(int arg0, String arg1) {
//失败
Toast.makeText(MainActivity.this, "删除失败", 1).show();
}
});
break;
然后我们运行程序,点击删除数据后回到后台
可以看到,表明bean还在,但是数据已经被删除了
这几个数据操作,唯一不同的就是查询了,他必须使用到一个查询的类BmobQuery
case R.id.btn_query:
// BmobQuery<要查询的数据表> 项目一般不会只有一张表的
BmobQuery<Bean> query = new BmobQuery<Bean>();
query.findObjects(this, new FindListener<Bean>() {
@Override
public void onSuccess(List<Bean> arg0) {
// 成功
Toast.makeText(MainActivity.this, "查询成功"+arg0.size(), 1).show();
}
@Override
public void onError(int arg0, String arg1) {
// 失败
Toast.makeText(MainActivity.this, "查询失败", 1).show();
}
});
break;
然后我们点击查询之后,他返回的是一个List,这里我们就不详细看List里面有什么了,表里只有一条数据,我们直接Toast他的size
跟数据库操作是一样的,你可以根据条件来查询,看代码
case R.id.btn_query:
// BmobQuery<要查询的数据表> 项目一般不会只有一张表的
BmobQuery<Bean> query = new BmobQuery<Bean>();
//条件查询 我们查询名称是刘桂林的数据
query.addWhereEqualTo("name", "刘桂林");
query.findObjects(this, new FindListener<Bean>() {
@Override
public void onSuccess(List<Bean> arg0) {
// 成功
// Toast.makeText(MainActivity.this, "查询成功"+arg0.size(), 1).show();
for (Bean bean : arg0) {
Toast.makeText(MainActivity.this, "查询成功"+bean.getName()+"---"+bean.getAge(), 1).show();
}
}
@Override
public void onError(int arg0, String arg1) {
// 失败
Toast.makeText(MainActivity.this, "查询失败", 1).show();
}
});
break;
运行的结果
case R.id.btn_query:
// BmobQuery<要查询的数据表> 项目一般不会只有一张表的
BmobQuery<Bean> query = new BmobQuery<Bean>();
// 查询单条数据
query.getObject(this, "9fe91ce9a6", new GetListener<Bean>() {
@Override
public void onFailure(int arg0, String arg1) {
// 失败
Toast.makeText(MainActivity.this, "查询失败", 1).show();
}
@Override
public void onSuccess(Bean bean) {
// 成功
Toast.makeText(MainActivity.this, bean.getName()+","+bean.getAge(), 1).show();
}
});
break;
这里你要单条数据查询的话,你就必须只带objectid才行,这里就不演示了
前面废话啰嗦了也有一大堆了,现在来聊聊实际点的东西,Bmob他毕竟是一个后台数据管理的平台,所以前面才说了一堆的数据操作,我们接下来要实现的功能就是用户的注册和登录。
Bmob实现登录注册,还有邮箱验证的功能,其实就是利用上面的数据操作,也就是增删查改
我们进入后台会看到用户表单里面有一些字段
这可不是固定的,而是根据我们的需求可以增加或者删除的,默认的是最基本的
我们为了方便,新建一个工程BmobTest,然后把架包放在lib目录下,添加相应的权限以及在onCreate()方法里初始化Bmob,准备工作做完了之后,我们开始写代码:
我们还是用回上面的哪个Bean,因为用户名和密码是不需要复写的,不过这里特别需要注意的是,这次我们不是继承BmobObject,而是继承BmobUser;
**
我们要先搭建一个工程
<LinearLayout 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" android:orientation="vertical" >
<EditText android:id="@+id/et_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入用户名" />
<EditText android:id="@+id/et_pass" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入密码" />
<Button android:id="@+id/btn_login" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="登录" />
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="15dp" android:orientation="horizontal" >
<TextView android:id="@+id/tv_etpass" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:text="修改密码" />
<TextView android:id="@+id/tv_register" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:text="注册用户" />
</LinearLayout>
</LinearLayout>
<?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" >
<EditText android:id="@+id/et_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入用户名" />
<EditText android:id="@+id/et_pass" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入密码" />
<Button android:id="@+id/btn_register" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="注册" />
</LinearLayout>
布局就是这样,想必跳转的逻辑也不用说了吧,很简单的一个例子,那我们先来注册:
package com.lgl.bmobtest;
import cn.bmob.v3.listener.SaveListener;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class RegisterActivity extends Activity {
private Button btn_register;
private EditText et_name, et_pass;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
btn_register = (Button) findViewById(R.id.btn_register);
et_name = (EditText) findViewById(R.id.et_name);
et_pass = (EditText) findViewById(R.id.et_pass);
btn_register.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Bean bean = new Bean();
// 设置的内容可以不需要,这里为了简便直接写死了
bean.setName("刘桂林");
bean.setAge(20);
bean.setScore(100);
bean.setUsername(et_name.getText().toString());
bean.setPassword(et_pass.getText().toString());
bean.signUp(RegisterActivity.this, new SaveListener() {
@Override
public void onSuccess() {
// 如果注册成功,就finish()掉,也就是退回主界面
finish();
}
@Override
public void onFailure(int arg0, String arg1) {
Toast.makeText(RegisterActivity.this, "注册失败",
Toast.LENGTH_LONG).show();
}
});
}
});
}
}
我们把项目部署在模拟器上
点击注册之后直接就finish()了说明注册成功了,我们进Bmob后端控制台去看一下
表里面有数据,说明我们已经注册成功了
用户名是12345 密码是67890
登录其实是比较简单的
case R.id.btn_login:
Bean bean = new Bean();
bean.setUsername(et_name.getText().toString());
bean.setPassword(et_pass.getText().toString());
bean.login(this, new SaveListener() {
@Override
public void onSuccess() {
Toast.makeText(MainActivity.this, "登录成功", Toast.LENGTH_LONG)
.show();
}
@Override
public void onFailure(int arg0, String arg1) {
Toast.makeText(MainActivity.this, "账号或密码错误",
Toast.LENGTH_LONG).show();
}
});
break;
我们把项目部署在模拟器上
我们时常就是会碰到这么一个场景,自己的个人信息填写错了,需要修改
这里我们在主布局加一个Button
<Button android:id="@+id/btn_update" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="更新用户信息" />
更新信息的代码其实和上面的数据操作是有异曲同工的
case R.id.btn_update:
// Bmob在登录成功后会缓存
bean = BmobUser.getCurrentUser(this, Bean.class);
bean.setName("刘桂林修改");
bean.update(this, new UpdateListener() {
@Override
public void onSuccess() {
Toast.makeText(MainActivity.this, "修改成功", Toast.LENGTH_LONG)
.show();
}
@Override
public void onFailure(int arg0, String arg1) {
}
});
break;
我们把项目部署在模拟器上
注意:我们更新用户信息的前提是已经登录
有图有真相,我们看一下控制台
使用邮件验证功能,我们必须去后端控制台开启这个功能
里面的信息我们可以自定义,我们将之前注册的过程进行修改,如果觉得乱的会后续也会贴上源码,其实就是加个邮箱而已
bean.setEmail("748778890@qq.com");
然后我们把项目部署在模拟器上,我们项目注册之后就有一个邮箱了
然后我们会收到验证邮件
是不是很神奇,我们来看看邮件的内容,你会发现,就是Bmob后台的邮件信息,你是可以自定义的
我们点击链接
如果我们没有验证的话,就算你的注册时能finish(),你也不能登录的,挺实用的
我们可以在登录的时间写一个判断
if (bean.getEmailVerified()) {
Toast.makeText(MainActivity.this, "登录成功", Toast.LENGTH_LONG).show();
}else {
Toast.makeText(MainActivity.this, "请前往邮箱验证", Toast.LENGTH_LONG).show();
}
修改密码同样会使用到邮箱验证的功能,在邮箱信息的地方可以看到密码修改信息
case R.id.tv_etpass:
String email = "[email protected]";
BmobUser.resetPasswordByEmail(this, email, new ResetPasswordByEmailListener() {
@Override
public void onSuccess() {
Toast.makeText(MainActivity.this, "验证邮箱已发送", Toast.LENGTH_LONG)
.show();
}
@Override
public void onFailure(int arg0, String arg1) {
Toast.makeText(MainActivity.this, "更改失败", Toast.LENGTH_LONG)
.show();
}
});
break;
注意,修改密码的前提是你是登录状态哦
我们把项目部署在模拟器上
然后看短信内容
现在就可以修改密码了,修改迷失是根据你的邮箱来更改的
OK,是不是挺简单的
后面其实都是依葫芦画瓢,我就文字多啰嗦几句,代码少些一点了
// 上传文件,这里是指定文件的路径,只要你指定了这个路径下的文件,不管是什么类型,都是可以上传的
String picPath = "sdcard/Download/image.png";
//然后我们创建一个file对象
final BmobFile file = new BmobFile(new File(picPath));
//我们拿到这个file对象把他上传
file.upload(this, new UploadFileListener() {
@Override
public void onSuccess() {
//上传成功
}
@Override
public void onProgress(Integer arg0) {
// 上传进度
}
@Override
public void onFailure(int arg0, String arg1) {
// 上传失败
}
});
break;
只要我们上传了之后,是可以在控制端后台看到的
Bmob的操作都是很相似的,我们下载和上传也是差不多的
//我们首先查询这个数据库
BmobQuery<Bean> query = new BmobQuery<Bean>();
//根据objectid我们进行操作
query.getObject(this, "55f9e5c116", new GetListener<Bean>() {
@Override
public void onSuccess(Bean arg0) {
//这里返回的文件是一个File类型,因为我们这里是图片所以就直接geticon();
BmobFile icon = arg0.getIcon();
//我们可以直接获取到这个图片的Url,但是毕竟是一张图片,我们就直接设置在控件上
// String url = icon.getFileUrl();
icon.loadImage(MainActivity.this, iv_icon);
}
@Override
public void onFailure(int arg0, String arg1) {
//失败
}
});
图片采用Bmob官方
所谓的缩略图就是加载图片的时候为了节约啥啥啥的所对图片进行了一定的压缩,我们只要把刚才加载图片的方法改变一下就可以了
//参数:上下文,指定路径,长,宽,照片质量
icon.loadImageThumbnail(MainActivity.this, iv_icon, 100, 100, 100);
要使用推送功能,你必须要有推送SDK,不过估计你也已经添加了
<service android:label="PushService" android:name="cn.bmob.push.lib.service.PushService" android:process="cn.bmob.push" android:exported="true">
<intent-filter>
<action android:name="cn.bmob.push.lib.service.PushService"/>
</intent-filter>
</service>
<receiver android:name="cn.bmob.push.PushReceiver" >
<intent-filter android:priority="2147483647" ><!--优先级加最高-->
<!-- 系统启动完成后会调用 -->
<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>
Push消息通过action=cn.bmob.push.action.MESSAGE的Intent把数据发送给客户端your.package.MyPushMessageReceiver,消息格式由应用自己决定,PushService只负责把服务器下发的消息以字符串格式透传给客户端。
我们新建一个广播类
public class MyPushMessageReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if (intent.getAction().equals("msg")) {
Toast.makeText(context,
"客户端收到推送内容:" + intent.getStringExtra("msg"),
Toast.LENGTH_LONG).show();
}
}
}
在你的应用程序主Activity中调用如下方法:
// 使用推送服务时的初始化操作
BmobInstallation.getCurrentInstallation(this).save();
// 启动推送服务
BmobPush.startWork(this, "你的Application Id");
准备工作都做完之后我们应该在后端控制面板开启推送服务
这些内容自定义之后别急着点击发送,我们还需要配置一下包名
等都绑定了之后我们就可以点击推送了