Bmob开发Android程序快速入门小demo菜鸟的学习

选择你要开发的应用,点击该应用下方对应的“应用密钥”

在跳转页面,获取ApplicationID,此ID将会在初始化SDK中使用到。

获取ApplicationID后,下载SDK,开发者可以根据自己的需求选择相应的iOSSDK或AndroidSDK,点击下载即可。

一、在你的项目根目录下创建"libs"目录,将下载的BmobSDK文件放入该目录下。

二、在你的应用程序中添加相应的权限:

packagecom.bmob.example;importcn.bmob.Bmob;importandroid.app.Activity;importandroid.os.Bundle;publicclassMainActivityextendsActivity{@OverrideprotectedvoidonCreate(BundlesavedInstanceState){//TODOAuto-generatedmethodstubsuper.onCreate(savedInstanceState);//初始化BmobSDK//使用时请将第二个参数ApplicationID替换成你在Bmob服务器端创建的ApplicationIDBmob.initialize(this,"YourApplicationID");}}简介Bmob平台为您的移动应用提供了一个完整的后端解决方案,我们提供轻量级的SDK开发包,让开发者以最小的配置和最简单的方式使用Bmob平台提供的服务,进而完全消除开发者编写服务器代码以及维护服务器的操作。

Bmob致力于为开发者提供快速开发服务,为方便大家更好的理解BmobSDK能够做的事情,我们特意为大家提供了一些源码,大家可以下载之后,嵌入Bmob的AppKey,再打包运行。

阅读源码是一种良好的习惯!!

在Bmob平台注册后,每个账户可创建多个应用程序,创建的每个应用程序都有其独自的应用程序ID,此后所有的应用程序将凭其ID进行BmobSDK的使用。即使只有一个应用程序,也可以以不同的版本进行测试和生产。

目前为止,我们支持的数据类型有String、Integer、Boolean、ArrayList以及BmobObject对象类型。同时Bmob也支持BmobDate、BmobGeoPoint、BmobFile数据类型。

一个对象对应了数据表中的一条数据,也可以理解为应用程序中的JavaBean.

publicclassGameScoreextendsBmobObject{privateStringplayerName;privateIntegerscore;privateBooleancheatMode;privateBmobFilepic;publicStringgetPlayerName(){returnplayerName;}publicvoidsetPlayerName(StringplayerName){this.playerName=playerName;}publicIntegergetScore(){returnscore;}publicvoidsetScore(Integerscore){this.score=score;}publicBooleangetCheatMode(){returncheatMode;}publicvoidsetCheatMode(BooleancheatMode){this.cheatMode=cheatMode;}publicBmobFilegetPic(){returnpic;}publicvoidsetPic(BmobFilepic){this.pic=pic;}}类名和表名的关系//这时候实际操作的表是T_a_bpublicclassGameScoreextendsBmobObject{privateStringplayerName;privateIntegerscore;privateBooleancheatMode;privateBmobFilepic;publicGameScore(){this.setTableName("T_a_b");}publicStringgetPlayerName(){returnplayerName;}//其他方法,见上面的代码}当然了,你也可以在GameScore实例中动态调用setTableName方法,实现操作可变表(如根据日期建立表来存储信息)的可能。

如果您使用了setTableName方法来自定义表名,那么在对该表进行数据查询的时候必须使用以下方法来进行查询。需要注意的是查询的结果是一个JSONArray,您需要自行解析JSONArray中的数据来进行使用。

添加数据非常简单,任何BmobObject对象都具有save方法可以用于将当前对象的内容保存到服务端。例如,你现在要保存一条游戏分数的记录,可以这样做:

GameScoregameScore=newGameScore();gameScore.setPlayerName("Barbie");gameScore.setScore(89);gameScore.setCheatMode(false);gameScore.save(mContext,newSaveListener(){@OverridepublicvoidonSuccess(){//TODOAuto-generatedmethodstubtoast("添加数据成功,返回objectId为:"+gameScore.getObjectId());}@OverridepublicvoidonFailure(intcode,Stringarg0){//TODOAuto-generatedmethodstub//添加失败}});运行完以上代码后,数据即可保存到服务器端。为了确认数据是否真的已经保存成功,你可以在Bmob服务器端你应用程序的数据浏览项目中进行查看。你应该看到类似这样的结果:

objectId:"0c6db13c",score:89,playerName:"Barbie",cheatMode:false,createdAt:"2013-09-2710:32:54",updatedAt:"2013-09-2710:32:54"注:

数据的查询可能是每个应用都会频繁使用到的,BmobSDK中提供了BmobQuery类,它提供了多样的方法来实现不同条件的查询,同时它的使用也是非常的简单和方便的。

查询某个数据表中的所有数据是非常简单的查询操作,例如:查询所有人员的信息。

BmobQueryquery=newBmobQuery();query.findObjects(this,newFindListener(){@OverridepublicvoidonSuccess(Listobject){//TODOAuto-generatedmethodstubtoast("查询成功:共"+object.size()+"条数据。");}@OverridepublicvoidonError(intcode,Stringmsg){//TODOAuto-generatedmethodstubtoast("查询失败:"+msg);}});怎么样,是不是很简单,而且查询的结果不需要进行任何处理,BmobSDK已经为你封装成相应的JavaBean集合了,你直接使用即可。

当我们知道某条数据的objectId时,就可以根据objectId直接获取单条数据对象。例如:查询objectId为a203eba875的人员信息。

BmobQueryquery=newBmobQuery();query.getObject(this,"a203eba875",newGetListener(){@OverridepublicvoidonSuccess(GameScoreobject){//TODOAuto-generatedmethodstubtoast("查询成功:");}@OverridepublicvoidonFailure(intcode,Stringarg0){//TODOAuto-generatedmethodstubtoast("查询失败:"+arg0);}});条件查询在查询的使用过程中,基于不同条件的查询是非常常见的,BmobQuery同样也支持不同条件的查询。

例如:如果要过滤掉特定键的值可以使用addWhereNotEqualTo方法。比如需要查询playerName不等于“Barbie”的数据时可以这样写:

query.addWhereNotEqualTo("playerName","Barbie");当然,你可以在你的查询操作中添加多个约束条件,来查询符合要求的数据。

query.addWhereNotEqualTo("playerName","Barbie");//名字不等于Barbiequery.addWhereGreaterThan("score",60);//条件:分数大于60岁各种不同条件的比较查询:

//分数<50query.addWhereLessThan("score",50);//分数<=50query.addWhereLessThanOrEqualTo("score",50);//分数>50query.addWhereGreaterThan("score",50);//分数>=50query.addWhereGreaterThanOrEqualTo("score",50);如果你想查询匹配几个不同值的数据,如:要查询“Barbie”,“Joe”,“Julia”三个人的成绩时,你可以使用addWhereContainedIn方法来实现。

String[]names={"Barbie","Joe","Julia"};query.addWhereContainedIn("playerName",Arrays.asList(names));相反,如果你想查询排除“Barbie”,“Joe”,“Julia”这三个人的其他同学的信息,你可以使用addWhereNotContainedIn方法来实现。

比如,你想查询2015年2月11号之前的Person数据,那么可以使用addWhereLessThan或者addWhereLessThanOrEqualTo(包含当天)来查询。如果想查询之后的数据,则可以使用addWhereGreaterThan或addWhereGreaterThanOrEqualTo(包含当天)来查询。

BmobQueryquery=newBmobQuery("Person");StringdateString="2015-02-11";SimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-dd");Datedate=null;try{date=sdf.parse(dateString);}catch(ParseExceptione){e.printStackTrace();}//这是查询2015年2月11之前的Person数据query.addWhereLessThan("createdAt",newBmobDate(date));//这是查询2015年2月11之后的Person数据//query.addWhereGreaterThan("createdAt",newBmobDate(date));```java###模糊查询如果你想实现类似数据库的模糊查询,比如,你想查询用户表中用户名中含有“a”的用户,那么你可以使用`addWhereContains`方法来实现。```javaStringvalue="a";query.addWhereContains("username",value);分页查询有时,在数据比较多的情况下,你希望查询出的符合要求的所有数据能按照多少条为一页来显示,这时可以使用setLimit方法来限制查询结果的数据条数来进行分页。默认情况下,Limit的值为10,最大有效设置值1000(设置的数值超过1000还是视为1000)。

query.setLimit(10);//限制最多10条数据结果作为一页在数据较多的情况下,在setLimit的基础上分页显示数据是比较合理的解决办法,setSKip方法可以做到跳过查询的前多少条数据来实现分页查询的功能。默认情况下Skip的值为10。

对应数据的排序,如数字或字符串,你可以使用升序或降序的方式来控制查询数据的结果顺序:

//根据score字段升序显示数据query.order("score");//根据score字段降序显示数据query.order("-score");//多个排序字段可以用(,)号分隔query.order("-score,createdAt");说明:多个字段排序时,先按第一个字段进行排序,再按第二个字段进行排序,依次进行。

如果你只是想统计满足查询对象的数量,你并不需要获取所有匹配对象的具体数据信息,可以直接使用count替代findObjects。例如,查询一个特定玩家玩的游戏场数:

BmobQueryquery=newBmobQuery();query.addWhereEqualTo("playerName","Barbie");query.count(this,GameSauce.class,newCountListener(){@OverridepublicvoidonSuccess(intcount){//TODOAuto-generatedmethodstubtoast("Barbiehasplayed"+count+"games");}@OverridepublicvoidonFailure(intcode,Stringmsg){//TODOAuto-generatedmethodstubtoast("countfailure:"+msg);}});复杂查询复合与查询(and)有些查询需要使用到复合“与”的查询条件,例如:你想查询出Person表中年龄在6-29岁之间且姓名以"y"或者"e"结尾的人,那么,可以采用and查询,示例代码如下:

BmobQueryeq1=newBmobQuery();eq1.addWhereEqualTo("age",29);BmobQueryeq2=newBmobQuery();eq2.addWhereEqualTo("age",6);List>queries=newArrayList>();queries.add(eq1);queries.add(eq2);BmobQuerymainQuery=newBmobQuery();mainQuery.or(queries);mainQuery.findObjects(this,newFindListener(){@OverridepublicvoidonSuccess(Listobject){//TODOAuto-generatedmethodstub}@OverridepublicvoidonError(intcode,Stringmsg){//TODOAuto-generatedmethodstub}});你还可以在此基础上添加更多的约束条件到新创建的BmobQuery对象上,表示一个and查询操作。

如果你要获得某个字段匹配特定BmobObject的对象列表,你可以像查询其他数据类型一样使用addWhereEqualTo来查询。例如:每个Weibo对象都包含一个BmobUser对象在它的author字段上,现在你想查询当前用户发布的所有微博信息,如下:

query.include("weibo.author");这里需要注意的是:

1、include的查询对象只能为BmobPointer类型,而不能是BmobRelation类型。

2、如果你想include两个对象,你可以这样做:

query.include("Comment,User");但不能如下的做法:

query.include("Comment");query.include("User");缓存查询缓存查询通常是将查询结果缓存在磁盘上。当用户的设备处于离线状态时,就可以从缓存中获取数据来显示。或者在应用界面刚刚启动,从网络获取数据还未得到结果时,先使用缓存数据来显示。这样可以让用户不必在按下某个按钮后进行枯燥的等待。默认的查询操作是没有启用缓存的,开发者可以使用setCachePolicy方法来启用缓存功能。例如:优先从缓存获取数据,如果获取失败再从网络获取数据。

bmobQuery.setCachePolicy(CachePolicy.CACHE_ELSE_NETWORK);//先从缓存获取数据,如果没有,再从网络获取。bmobQuery.findObjects(this,newFindListener(){@OverridepublicvoidonSuccess(Listobject){//TODOAuto-generatedmethodstubtoast("查询成功:共"+object.size()+"条数据。");}@OverridepublicvoidonError(intcode,Stringmsg){//TODOAuto-generatedmethodstubtoast("查询失败:"+msg);}});BmobSDK提供了几种不同的缓存策略,以适应不同应用场景的需求:

只从网络获取数据,且不会将数据缓存在本地,这是默认的缓存策略。

只从缓存读取数据,如果缓存没有数据会导致一个BmobException,可以忽略不处理这个BmobException.

只从网络获取数据,同时会在本地缓存数据。

先从缓存读取数据,如果没有,再从网络获取。

先从缓存取数据,无论结果如何都会再次从网络获取数据。也就是说会产生2次调用。通常的用法是先快速取出缓存数据展示view,然后再后台连接网络取得最新数据,取到后用来自网络服务器的最新数据更新view。

如果需要操作缓存内容,可以使用BmobQuery提供的方法做如下操作:

有的时候,一张表的数据列比较多,而我们只想查询返回某些列的数据时,我们可以使用BmobQuery对象提供的addQueryKeys方法来实现。如下所示:

BmobQuerybmobQuery=newBmobQuery();bmobQuery.addQueryKeys("objectId");bmobQuery.findObjects(this,newFindListener(){@OverridepublicvoidonSuccess(Listobject){//TODOAuto-generatedmethodstubtoast("查询成功:共"+object.size()+"条数据。");//注意:这里的Person对象中只有指定列的数据。}@OverridepublicvoidonError(intcode,Stringmsg){//TODOAuto-generatedmethodstubtoast("查询失败:"+msg);}});指定多列时用,号分隔每列,如:addQueryKeys("objectId,name,add");

更新一个对象也是非常简单。例如:将GameScore表中objectId为0c6db13c的游戏分数修改为77.

GameScoregameScore=newGameScore();gameScore.setScore(77);gameScore.update(this,"0c6db13c",newUpdateListener(){@OverridepublicvoidonSuccess(){//TODOAuto-generatedmethodstubtoast("更新成功:");}@OverridepublicvoidonFailure(intcode,Stringmsg){//TODOAuto-generatedmethodstubtoast("更新失败:"+msg);}});删除数据从服务器删除对象。例如:将GameScore表中objectId为dd8e6aff28的数据删除。

GameScoregameScore=newGameScore();gameScore.setObjectId("dd8e6aff28");gameScore.delete(this,newDeleteListener(){@OverridepublicvoidonSuccess(){//TODOAuto-generatedmethodstubtoast("删除成功");}@OverridepublicvoidonFailure(intcode,Stringmsg){//TODOAuto-generatedmethodstubtoast("删除失败:"+msg);}});删除字段你可以在一个对象中删除一个字段,通过remove操作:

GameScoregameScore=newGameScore();gameScore.setObjectId("dd8e6aff28");gameScore.remove("score");//删除GameScore对象中的score字段gameScore.update(this,newUpdateListener(){@OverridepublicvoidonSuccess(){//TODOAuto-generatedmethodstubtoast("删除GameScore对象中的score字段成功");}@OverridepublicvoidonFailure(intcode,Stringmsg){//TODOAuto-generatedmethodstubtoast("删除GameScore对象中的score字段失败:"+msg);}});数组对于数组型数据,BmobSDK提供了3种操作来原子性地更改一个数组字段:add、addAll在一个数组字段的后面添加一些指定的对象(包装在一个数组内)addUnique、addAllUnique只会在原本数组字段中没有这些对象的情形下才会添加入数组,插入数组的位置不固定的removeAll从一个数组字段的值内移除指定的数组中的所有对象

给一个数据对象中的数组类型字段添加数据可以使用以下方法添加:

Personp=newPerson();p.add("hobby","唱歌");//添加一个值到hobby字段中,hobby为数组类型//p.addAll("hobby",Arrays.asList("游泳","看书"));//一次添加多个值到hobby字段中p.save(this,newSaveListener(){@OverridepublicvoidonSuccess(){//TODOAuto-generatedmethodstubtoast("保存成功");}@OverridepublicvoidonFailure(intcode,Stringmsg){//TODOAuto-generatedmethodstubtoast("保存失败:"+msg);}});更新数组数据举个例子,hobby(爱好)是一个数组类型的字段,那么我们可以在hobby字段中加入一些爱好,只有在hobby字段中不包含这些爱好的情况下才会被加入:

Personp=newPerson();p.setObjectId("d32143db92");p.addUnique("hobby","爬山");//添加一个值到hobby字段中//p.addAllUnique("hobby",Arrays.asList("游泳","羽毛球"));//一次添加多个值到hobby字段中p2.update(this,newUpdateListener(){@OverridepublicvoidonSuccess(){//TODOAuto-generatedmethodstubtoast("更新爱好成功");}@OverridepublicvoidonFailure(intcode,Stringmsg){//TODOAuto-generatedmethodstubtoast("更新爱好失败:"+msg);}});查询数组数据对于字段类型为数组的情况,可以查找字段中的数组值包含有xxx的对象:

BmobQueryquery=newBmobQuery();String[]hobby={"阅读","唱歌"};query.addWhereContainsAll("hobby",Arrays.asList(hobby));query.findObjects(this,newFindListener(){@OverridepublicvoidonSuccess(Listobject){//TODOAuto-generatedmethodstubtoast("查询成功:共"+object.size()+"条数据。");}@OverridepublicvoidonError(intcode,Stringmsg){//TODOAuto-generatedmethodstubtoast("查询失败:"+code);}});删除数组数据同理我们也可以使用removeAll从数组字段中移除某些值:

由于关联关系讲解起来比较复杂,以下用一个简单的案例来说明在Bmob中是如何使用关联关系的,最后会提供相应的源码。这个场景是这样的:我们生活中每个人都可能会办理多张银行卡,而每张银行卡的登记人只有一个。从这个场景可以看出有两个对象,一个是人,一个是银行卡。

我们接下来需要在Web端创建对应的表,分别是用户表和银行卡表,其中用户表我们直接使用Bmob提供的系统表User表。在创建数据表的字段的时候,当选择字段类型为Pointer或Relation时,会提示你选择该字段所指向或关联的数据表。如下图所示:

根据本案例的场景,我们需要在User表中多增加一列为cards,数据类型为Relation,然后创建一个银行卡信息表(BankCard),银行卡表的主要结构如下:bankNameString银行名称cardNumberString银行卡号userPointer<_User>银行卡用户

为了更直观的展示数据表的结构,我将两个表的截图贴上,以供参考:

用户表(注意cards字段)

银行卡表(注意user字段)

接下来我们需要创建User表和BankCard表对应的数据对象,User表对应的数据对象的代码如下:

BankCard表对应的数据对象的代码如下:

publicclassBankCardextendsBmobObject{/***银行卡号*/privateStringcardNumber;/***银行名称*/privateStringbankName;/***户主*/privateMyUseruser;publicStringgetCardNumber(){returncardNumber;}publicvoidsetCardNumber(StringcardNumber){this.cardNumber=cardNumber;}publicStringgetBankName(){returnbankName;}publicvoidsetBankName(StringbankName){this.bankName=bankName;}publicMyUsergetUser(){returnuser;}publicvoidsetUser(MyUseruser){this.user=user;}}这里需要注意的是:1、类名要和表名保持一致。2、MyUser属性对应为Pointer的指针类型。

接下来我们就从代码层次上来讲解,怎么样来操作这些关联关系的数据。首先我们来讲添加关联关系。在我们创建一张银行卡信息时,需要指定这张卡的户主(user),这就是添加的一对一的关联关系。代码如下:

/***创建一条银行卡信息到BankCard表中,并关联到用户的银行卡信息中*@parambankName银行名称*@paramcardNumber银行卡号*/privatevoidsaveBankCardInfo(StringbankName,StringcardNumber){if(TextUtils.isEmpty(user.getObjectId())){toast("当前用户的object为空");return;}card=newBankCard();card.setBankName(bankName);//设置银行名称card.setCardNumber(cardNumber);//设置银行卡号card.setUser(user);//设置银行卡户主card.save(this,newSaveListener(){@OverridepublicvoidonSuccess(){//TODOAuto-generatedmethodstubtoast("成功保存一条银行卡信息到BankCard表中");addCardToUser();}@OverridepublicvoidonFailure(intarg0,Stringarg1){//TODOAuto-generatedmethodstubtoast("很遗憾,保存一条银行卡信息到BankCard表中失败了");}});}修改关联关系当我们的这张银行卡创建成功后,不仅仅只是设置银行卡的户主就可以来,我们还需要更新户主的信息,也就是将当前银行卡关联到用户的cards列中。这就是修改关联关系,代码如下:

/***添加银行卡到用户的银行卡信息中*/privatevoidaddCardToUser(){if(TextUtils.isEmpty(user.getObjectId())||TextUtils.isEmpty(card.getObjectId())){toast("当前用户或者当前Card对象的object为空");return;}BmobRelationcards=newBmobRelation();cards.add(card);user.setCards(cards);user.update(this,newUpdateListener(){@OverridepublicvoidonSuccess(){//TODOAuto-generatedmethodstubtoast("已成功添加到用户的银行卡信息中");}@OverridepublicvoidonFailure(intarg0,Stringarg1){//TODOAuto-generatedmethodstubtoast("很遗憾,用户的银行卡信息添加失败");}});}上面的代码将某银行卡添加到了用户的银行卡信息中,还有一种情况是从用户的银行卡信息中删除掉某银行卡的信息,在现实生活中我叫注销我的银行卡。代码示例如下:

/***删除用户信息中的某银行卡信息*/privatevoidremoveCardToUser(){if(TextUtils.isEmpty(user.getObjectId())||TextUtils.isEmpty(card.getObjectId())){toast("当前用户或者当前Card对象的object为空");return;}BmobRelationcards=newBmobRelation();cards.remove(card);user.setCards(cards);user.update(this,newUpdateListener(){@OverridepublicvoidonSuccess(){//TODOAuto-generatedmethodstubtoast("在用户信息中已成功移除该银行卡信息");}@OverridepublicvoidonFailure(intarg0,Stringarg1){//TODOAuto-generatedmethodstubtoast("很遗憾,移除失败");}});}查询关联关系需求1:查询我的所有银行卡信息,代码如下:

/***查询我的所有银行卡信息*/privatevoidfindMyCards(){BmobQuerycards=newBmobQuery();/***注意这里的查询条件*第一个参数:是User表中的cards字段名*第二个参数:是指向User表中的某个用户的BmobPo*er对象*/cards.addWhereRelatedTo("cards",newBmobPointer(user));cards.findObjects(this,newFindListener(){@OverridepublicvoidonSuccess(Listarg0){//TODOAuto-generatedmethodstubtoast("我现在有"+arg0.size()+"张银行卡");for(BankCardbankCard:arg0){Log.d("bmob","objectId:"+bankCard.getObjectId()+",银行名称:"+bankCard.getBankName()+",卡号:"+bankCard.getCardNumber());}}@OverridepublicvoidonError(intarg0,Stringarg1){//TODOAuto-generatedmethodstubtoast("查询我银行卡信息失败");}});}需求2:查询银行卡信息时同时获取该卡的户主信息,代码如下:

在BmobObject对象中提供了三种用于批量操作的方法,分别是insertBatch、updateBatch、deleteBatch,批量添加、更新、删除。

很多应用可能会有计数器功能的需求(并发请求会出现这个问题),比如某条信息被点赞多少次,如果多人同时操作,如果用普通的更新方法的话,可能会导致数据不一致的情况。为此,Bmob提供了原子计数器来保证原子性的修改某一数值字段的值。注意:原子计数器只能对应用于Web后台的Number字段,和实体类实现中的Integer对象类型(类中请不要用int类型)。

gameScore.increment("score");//分数递增1gameScore.update(this,updateListener);您还可以通过increment(key,amount)方法来递增或递减任意幅度的数字

创建文件对象方式如下:

StringpicPath="sdcard/temp.jpg";BmobFilebmobFile=newBmobFile(newFile(picPath));上传单一文件文件分片上传的方法非常简单,示例代码如下:

StringpicPath="sdcard/temp.jpg";BmobFilebmobFile=newBmobFile(newFile(picPath));bmobFile.uploadblock(this,newUploadFileListener(){@OverridepublicvoidonSuccess(){//TODOAuto-generatedmethodstub//bmobFile.getUrl()---返回的上传文件的地址(不带域名)//bmobFile.getFileUrl(context)--返回的上传文件的完整地址(带域名)toast("上传文件成功:"+bmobFile.getFileUrl(context));}@OverridepublicvoidonProgress(Integervalue){//TODOAuto-generatedmethodstub//返回的上传进度(百分比)}@OverridepublicvoidonFailure(intcode,Stringmsg){//TODOAuto-generatedmethodstubtoast("上传文件失败:"+msg);}});批量上传文件BmobSDK_V3.2.7新增批量上传文件的方法,使用起来也很简单,示例代码如下:

bmobQuery.findObjects(this,newFindListener(){@OverridepublicvoidonSuccess(Listobject){//TODOAuto-generatedmethodstubtoast("查询成功:共"+object.size()+"条数据。");for(Personperson:object){if(person.getPic()!=null){//文件名称person.getPic().getFilename();//文件下载地址person.getPic().getFileUrl();}}}@OverridepublicvoidonError(intcode,Stringmsg){//TODOAuto-generatedmethodstubtoast("查询失败:"+msg);}});删除文件BmobSDKV3.3.0提供了删除文件的接口,方便开发者对文件进行管理,示例代码如下:

注:

1、单个文件上传大小不可超过200M;

2、文件分片上传的大小不可超过200M;

3、有时候使用upload方式上传不超过10M的文件的时候会出现OOM异常,故,建议开发者使用uploadblock(分片上传)方法来上传文件。

4、文件的批量上传是BmobSDK_v3.2.7版本才提供的功能,如需使用,请更新版本。

1、获取缩略图

如果你的BmobFile对象是保存的图片类型的文件,那么当你需要使用缩略图功能的时候,可以使用loadImageThumbnail方法来获取改图片的缩略图。

bmobFile.loadImageThumbnail(this,imageView,300,300);你还可以指定获取缩略图的图片质量

bmobFile.loadImageThumbnail(this,imageView,300,300,100);2、获取图片

很多时候您可能只是想直接加载图片来显示,那么你可以使用loadImage方法来加载原图。

bmobFile.loadImage(this,imageView);同样您也可以指定加载原图显示的大小

bmobFile.loadImage(this,imageView,300,300);3、缩略图的案例源码

新版文件管理是通过BmobProFile类(自BmobSDKv3.2.9开始)完成的,其提供了文件的单一上传、批量上传、文件下载、生成缩略图等功能,

BmobProFile和BmobFile两者之间是不兼容的,也就是说不能用BmobFile类上传的成功后得到的文件名再用BmobProFile类提供的下载方法来下载。

单一文件上传只需要调用BmobProFile类提供的静态方法:upload,示例代码如下:

BTPFileResponseresponse=BmobProFile.getInstance(MainActivity.this).upload(filePath,newUploadListener(){@OverridepublicvoidonSuccess(StringfileName,Stringurl){//TODOAuto-generatedmethodstubdialog.dismiss();showToast("文件已上传成功:"+fileName);}@OverridepublicvoidonProgress(intratio){//TODOAuto-generatedmethodstubBmobLog.i("MainActivity-onProgress:"+ratio);}@OverridepublicvoidonError(intstatuscode,Stringerrormsg){//TODOAuto-generatedmethodstubshowToast("上传出错:"+errormsg);}});onSuccess方法参数:

1、fileName:文件名(带后缀),这个文件名是唯一的,开发者需要记录下该文件名,方便后续下载该文件。

2、url:文件服务器地址(如果你上传的是图片类型的文件,此url地址并不能直接在浏览器查看(会出现404错误),需要经过URL签名得到真正的可访问的URL地址)。

1、使用场景:

开发者上传的如果是图片且希望能够访问完整的URL地址用来客户端直接显示图片,那么就需要用到URL签名。

2、签名认证步骤:

1)、开启签名认证:

开发者需要在web后台开启文件管理的URL签名认证:

文件管理-->基本配置-->设置SecretKey-->开启-->保存

注:此处的secretKey可任意填写,它是专门针对文件服务的,和"应用密钥"中的数据服务使用到的SecretKey是不一样的。

此部分为配置了URL的签名认证安全的开发者使用,若没配置,则按照正常处理。

2)、URL签名说明:

开启签名认证的URL地址格式:

未开启签名认证的URL地址格式:

URL=url(文件上传成功之后返回的url地址)t=(客户端类型)&a=(应用密钥中的AccessKey)

1、t:客户端类型(1~19代表SDK客户端,1:IOS,2:Android,3:wp,…,20:官网后台;21:其他网站)

2、AccessKey:在web后台的应用密钥中查看

4、Token:Token签名使用了web后台的文件管理中设置的SecretKey,开发者要注意此值的安全不被泄漏.

3)、URL签名步骤:

请求的文件名称fileName:dfwsdweqe0012.jpg;

假如请求参数为:

当前客户端类型:t=1//注释:Android

App的AccessKey:a=b63737a2825821fc3208b8a80a524da

当前的密钥SecretKey:abcdefg

组装请求URI:

Uri=/dfwsdweqe0012.jpgt=1&a=b63737a2825821fc3208b8a80a524da&e=1415697363

得到Token:

1、针对Uri进行HMAC-SHA1算法签名;

2、对签名后的字符串进行URL安全Base64编码;

3、编码后即为要要发送的token。

伪代码如下:

Token=urlbase64_encode(hmacsha1(Uri,secretKey));

得到最终的发送请求的URL为:

注:1、以上所有的参数名(t,a,e,token)均为小写,参数顺序为t,a,e,token,uri、secretkey等编码格式都为utf-8。

2、URL安全的Base64编码方式的基本过程是先将内容以Base64格式编码为字符串,然后检查该编码后的字符串,将字符串中的加号+换成中划线-,斜杠/换成下划线_,得到最终的字符串;

4)、URL签名方法:

鉴于URL签名比较复杂,BmobSDKV3.3.0的BmobProFile类为开发者提供了获取URL签名的方法:signURL(V3.3.2已修改为BmobProFile类的内部方法)

/***@paramfileName:文件名*@paramfileUrl:文件url地址*@paramaccessKey:web应用密钥中的AccessKey*@parameffectTime:有效时长(秒)*@paramsecretKey:密钥*@return可访问的URL地址*/StringURL=BmobProFile.getInstance(MainActivity.this).signURL(StringfileName,StringfileUrl,StringaccessKey,longeffectTime,StringsecretKey)未开启URL签名认证的示例代码如下:

1、fileName/fileUrl:表示上传(批量上传)成功后得到的文件名/文件服务器地址。

2、effectTime:表示这个URL请求的有效时长,单位为秒,一旦超过有效时长,则该URL请求失效。

3、若开发者未开启URL签名认证,则前三个参数必填,后面的effectTime传0,secretKey传null即可。

4、若文件类型为图片类型,客户端需要直接显示的话,则不建议开启URL签名认证

BmobProFile同样提供了批量上传文件的静态方法:uploadBatch:示例代码如下:

BmobProFile.getInstance(MainActivity.this).uploadBatch(files,newUploadBatchListener(){@OverridepublicvoidonSuccess(booleanisFinish,String[]fileNames,String[]urls){//TODOAuto-generatedmethodstubif(isFinish){dialog.dismiss();}showToast(""+isFinish+"-----"+Arrays.asList(fileNames)+"----"+Arrays.asList(urls));}@OverridepublicvoidonProgress(intcurIndex,intcurPercent,inttotal,inttotalPercent){//TODOAuto-generatedmethodstubdialog.setProgress(curIndex);BmobLog.i("MainActivity-onProgress:"+curIndex+"---"+curPercent+"---"+total+"----"+totalPercent);}@OverridepublicvoidonError(intstatuscode,Stringerrormsg){//TODOAuto-generatedmethodstubdialog.dismiss();showToast("批量上传出错:"+statuscode+"--"+errormsg);}});}onProgress方法参数:

1、curIndex:表示当前第几个文件正在上传

2、curPercent:表示当前上传文件的进度值(百分比)

3、total:表示总的上传文件数

4、totalPercent:表示总的上传进度(百分比)

BmobProFile同样提供了文件下载的静态方法:download,只需要将上传文件后记录下来的文件名fileName(必须是通过BmobProFile类的upload方法得到的)作为参数即可,示例代码如下:

BmobProFile.getInstance(MainActivity.this).download(fileName,newDownloadListener(){@OverridepublicvoidonSuccess(StringfullPath){//TODOAuto-generatedmethodstubshowToast("下载成功:"+fullPath);}@OverridepublicvoidonProgress(StringlocalPath,intpercent){//TODOAuto-generatedmethodstubBmobLog.i("MainActivity-download-->onProgress:"+percent);dialog.setProgress(percent);}@OverridepublicvoidonError(intstatuscode,Stringerrormsg){//TODOAuto-generatedmethodstubdialog.dismiss();showToast("下载出错:"+statuscode+"--"+errormsg);}});注:

1、onProgress参数localPath:表示当前下载文件的地址,当下载进度不为100的时候,这个地址下面的文件是不完整的,只有一部分。

2、onSuccess参数fullPath:表示下载成功后文件的存储完整地址,和localpath的路径是一样的。

3、允许开发者自定义保存下载文件的目录名,可在Apllication中对其进行初始化配置。示例如下:

BmobConfigurationconfig=newBmobConfiguration.Builder(context).customExternalCacheDir("目录名").build();BmobPro.getInstance(context).initConfig(config);缩略图处理对图片进行缩略图处理,BmobProFile类提供了两种方式:

一种将生成缩略图的任务提交给服务器,由服务器来处理并同步返回生成后的服务器缩略图地址(submitThumnailTask);另一种是SDK提供的本地处理缩略图的方法(getLocalThumbnail)。

一、submitThumnailTask

示例代码如下:

BmobProFile.getInstance(MainActivity.this).submitThumnailTask(fileName,modelId,newThumbnailListener(){@OverridepublicvoidonSuccess(StringthumbnailName,StringthumbnailUrl){//TODOAuto-generatedmethodstub//此处得到的缩略图地址(thumbnailUrl)不一定能够请求的到,此方法为异步方法BmobLog.i("MainActivity-onSuccess:"+thumbnailName+"-->"+thumbnailUrl);}@OverridepublicvoidonError(intstatuscode,Stringerrormsg){//TODOAuto-generatedmethodstubBmobLog.i("MainActivity-onError:"+statuscode+"---"+errormsg);}});注:

A、请求参数:fileName:文件名,modelId:缩略图的规格类型ID

B、thumbnailName的格式:

fileName+"_"+modelId

如果fileName=f24af10cbc15476e9789afaf168c3b8e.jpg,modelId=1,那么thumbnailName=f24af10cbc15476e9789afaf168c3b8e.jpg_1。

C、目前Bmob提供的规格类型ID(modelId)有六种:

1--指定宽,高自适应,等比例缩放;

2--指定高,宽自适应,等比例缩放;

3--指定最长边,短边自适应,等比例缩放;

4--指定最短边,长边自适应,等比例缩放;

5--指定最大宽高,等比例缩放;

6--固定宽高,居中裁剪;

二、getLocalThumbnail

SDK提供了三种处理本地缩略图的方式:

一、指定规格ID

BmobProFile.getInstance(LocalThumbnailActivity.this).getLocalThumbnail(localPath,modelId,newLocalThumbnailListener(){@OverridepublicvoidonError(intstatuscode,Stringerrormsg){//TODOAuto-generatedmethodstubBmobLog.i("MainActivity-localThumbnail-->生成缩略图失败:"+statuscode+","+errormsg);}@OverridepublicvoidonSuccess(StringthumbnailPath){//TODOAuto-generatedmethodstubBmobLog.i("MainActivity-localThumbnail-->生成后的缩略图路径:"+thumbnailPath);}});二、指定规格ID、宽、高

BmobProFile.getInstance(LocalThumbnailActivity.this).getLocalThumbnail(localPath,modeId,width,height,newLocalThumbnailListener(){@OverridepublicvoidonError(intstatuscode,Stringerrormsg){//TODOAuto-generatedmethodstubshowToast("本地缩略图创建失败:"+statuscode+","+errormsg);}@OverridepublicvoidonSuccess(StringthumbnailPath){//TODOAuto-generatedmethodstubshowToast("本地缩略图创建成功:"+thumbnailPath);}});三、指定规格ID、宽、高、图片压缩质量

为了方便开发者对图片进行压缩处理,V3.3.3版本在获取本地缩略图的方法中新增了图片压缩质量(quality)参数,取值范围:0-100。示例代码如下:

BmobProFile.getInstance(LocalThumbnailActivity.this).getLocalThumbnail(localPath,modeId,width,height,quality,newLocalThumbnailListener(){@OverridepublicvoidonError(intstatuscode,Stringerrormsg){//TODOAuto-generatedmethodstubshowToast("本地缩略图创建失败:"+statuscode+","+errormsg);}@OverridepublicvoidonSuccess(StringthumbnailPath){//TODOAuto-generatedmethodstubshowToast("本地缩略图创建成功:"+thumbnailPath);}});注:

1、localPath:图片的本地路径,需要带后缀名

2、modelId:开发者应事先在应用管理后台(文件管理-->自定义版本-->缩略图配置版本)完成基本的生成缩略图的规格配置:

数据实时同步是一个超酷的功能!

SDK可以实现对数据表或行的监听,当这个表或者行的数据发生变化时,Bmob会立即将变化的信息告知SDK。这种服务非常适合做游戏开发(如,开发斗地主游戏,三个人同时监听一行数据的变化,任何一个人出牌都会将数据写入到这行数据中,其他人也就立即知道了)、群聊(一群人监听某个表的变化,任何人发言都会将数据写入到这个表中,其他人也可以立即知道了)等实时性要求很高的场景中。

使用数据实时功能,首先需要创建BmobRealTimeData对象,然后调用start方法连接服务器。

BmobRealTimeDatartd=newBmobRealTimeData();rtd.start(this,newValueEventListener(){@OverridepublicvoidonDataChange(JSONObjectdata){//TODOAuto-generatedmethodstubLog.d("bmob","("+data.optString("action")+")"+"数据:"+data);}@OverridepublicvoidonConnectCompleted(){//TODOAuto-generatedmethodstubLog.d("bmob","连接成功:"+rtd.isConnected());}});start方法中的ValueEventListener参数用于监听连接成功和数据变化的回调。当有数据变化时会通过onDataChange回调方法反馈到客户端。开发者只需要处理得到的data就可以了。

1、监听器不支持UI线程,在监听回调中请不要直接操作UI;

2、如果你要监听User、Installation等系统表的话,表名前需要加上“_”,例如:_User

在BmobRealTimeData对象连接成功后,就可以进行数据的监听了。BmobSDK提供了监听表和行的方法如下:

//监听表更新rtd.subTableUpdate(tableName);//监听表删除rtd.subTableDelete(tableName);//监听行更新rtd.subRowUpdate(tableName,objectId);//监听行删除rtd.subRowDelete(tableName,objectId);其中tableName为要监听的数据表名,objectId为要监听的数据行Id,通常比较保险的做法是在BmobRealTimeData对象的连接状态为true的情况下进行监听,代码如下:

if(rtd.isConnected()){//监听表更新rtd.subTableUpdate(tableName);}取消监听当开发者想取消监听某个行为是,可使用下面的方法:

//取消监听表更新rtd.unsubTableUpdate(testTableName);//取消监听表删除rtd.unsubTableDelete(testTableName);//取消监听行更新rtd.unsubRowUpdate(testTableName,objectId);//取消监听行删除rtd.unsubRowDelete(testTableName,objectId);用户管理用户是一个应用程序的核心。对于个人开发者来说,自己的应用程序积累到越多的用户,就会给自己带来越强的创作动力。因此Bmob提供了一个专门的用户类——BmobUser来自动处理用户账户管理所需的功能。

有了这个类,你就可以在你的应用程序中添加用户账户功能。

BmobUser除了从BmobObject继承的属性外,还有几个特定的属性:username:用户的用户名(必需)。password:用户的密码(必需)。email:用户的电子邮件地址(可选)。

很多时候,你的用户表还会有很多其他字段,如性别、年龄、头像等。那么,你需要对BmobUser类进行扩展,添加一些新的属性。示例代码如下所示:

publicclassSpecialUserextendsBmobUser{privatebooleansex;privateStringnick;publicbooleangetSex(){returnthis.sex;}publicvoidsetSex(booleansex){this.sex=sex;}publicStringgetNick(){returnthis.sex;}publicvoidsetNick(Stringnick){this.nick=nick;}}更多代码实现大家可以下载SDK,在里面的BmobExample中查找MyUser类,参考它的用法。

创建用户对象如下:

BmobUseruser=newBmobUser();注册用户你的应用程序可能会要求用户注册。下面的代码是一个典型的注册过程:

BmobUserbu=newBmobUser();bu.setUsername("sendi");bu.setPassword("123456");bu.setEmail("sendi@163.com");bu.signUp(this,newSaveListener(){@OverridepublicvoidonSuccess(){//TODOAuto-generatedmethodstubtoast("注册成功:");}@OverridepublicvoidonFailure(intcode,Stringmsg){//TODOAuto-generatedmethodstubtoast("注册失败:"+msg);}});在注册过程中,服务器会对注册用户信息进行检查,以确保注册的用户名和电子邮件地址是独一无二的。此外,对于用户的密码,你可以在应用程序中进行相应的加密处理后提交。

如果注册不成功,你可以查看返回的错误对象。最有可能的情况是,用户名或电子邮件已经被另一个用户注册。这种情况你可以提示用户,要求他们尝试使用不同的用户名进行注册。

你也可以要求用户使用Email做为用户名注册,这样做的好处是,你在提交信息的时候可以将输入的“用户名“默认设置为用户的Email地址,以后在用户忘记密码的情况下可以使用Bmob提供重置密码功能。

这里有两点需要注意的:

BmobUser.logOut(this);//清除缓存用户对象BmobUsercurrentUser=BmobUser.getCurrentUser(this);//现在的currentUser是null了更新用户很多情况下你可能需要修改用户信息,比如你的应用具备修改个人资料的功能,Bmob提供的用户更新方式有两种写法:

第一种:新建一个用户对象,并调用update(context,objectId,updateListener)方法来更新(推荐使用),示例:

BmobUsernewUser=newBmobUser();newUser.setEmail("xxx@163.com");BmobUserbmobUser=BmobUser.getCurrentUser(this);newUser.update(this,bmobUser.getObjectId(),newUpdateListener(){@OverridepublicvoidonSuccess(){//TODOAuto-generatedmethodstubtoast("更新用户信息成功:");}@OverridepublicvoidonFailure(intcode,Stringmsg){//TODOAuto-generatedmethodstubtoast("更新用户信息失败:"+msg);}});第二种:获取本地的用户对象,并调用update(context,updateListener)方法来更新(不推荐使用),示例:

查询用户和查询普通对象一样,只需指定BmobUser类即可,如下:

BmobQueryquery=newBmobQuery();query.addWhereEqualTo("username","lucky");query.findObjects(this,newFindListener(){@OverridepublicvoidonSuccess(Listobject){//TODOAuto-generatedmethodstubtoast("查询用户成功:"+object.size());}@OverridepublicvoidonError(intcode,Stringmsg){//TODOAuto-generatedmethodstubtoast("查询用户失败:"+msg);}});浏览器中查看用户表

User表是一个特殊的表,专门存储BmobUser对象。在浏览器端,你会看到一个User表旁边有一个小人的图标。

一旦你引入了一个密码系统,那么肯定会有用户忘记密码的情况。对于这种情况,我们提供了一种方法,让用户安全地重置起密码。

重置密码的流程很简单,开发者只需要求用户输入注册的电子邮件地址即可:

为方便大家了解如何用Bmob开发找回密码的功能,我们为大家准备了另外一份文档,详细见我们在Github中的文档:

emailVerified字段有3种状态可以考虑:

{"qq":{"openid":"AAC61872C459FB196AECFA9D6FEBA334","access_token":"19A1E9FB3E440B4D15DBB44a39946FD4","expires_in":7776000}}解除绑定解除第三方账号与BmobUser的绑定关系如下代码所示:

其中,最灵活的方法是通过ACL和角色,它的思路是每一条数据有一个用户和角色的列表,以及这些用户和角色拥有什么样的许可权限。

大多数应用程序需要对不同的数据进行灵活的访问和控制,这就可以使用Bmob提供的ACL模式来实现。例如:

用BmobSDK,你可以对这些数据设置一个默认的ACL,这样,即使黑客反编译了你的应用,获取到ApplicationKey,也仍然无法操作和破坏你的用户数据,确保了用户数据的安全可靠。而作为开发者,当你需要对这些数据进行管理时,可以通过超级权限Key(MasterKey)进行。

在没有显示指定的情况下,每一个BmobObject(表)中的ACL(列)属性的默认值是所有人可读可写的。在客户端想要修改这个权限设置,只需要简单调用BmobACL的setPublicReadAccess方法和setPublicWriteAccess方法,即:

BmobACLaCL=newBmobACL();aCL.setPublicReadAccess(true);aCL.setPublicWriteAccess(true);注意:可读可写是默认的权限,不需要写额外的代码。

Blogblog=newBlog();blog.setTitle("论电影的七个元素");blog.setContent("这是blog的具体内容");BmobACLacl=newBmobACL();//创建一个ACL对象acl.setPublicReadAccess(true);//设置所有人可读的权限acl.setWriteAccess(BmobUser.getCurrentUser(this),true);//设置当前用户可写的权限blog.setACL(acl);//设置这条数据的ACL信息blog.save(this,newSaveListener(){@OverridepublicvoidonSuccess(){//添加成功}@OverridepublicvoidonFailure(intcode,Stringmsg){//添加失败}});有时,用户想发表一篇不公开的日志,这种情况只有发布者才对这篇日志拥有读写权限,相应的代码如下:

Blogblog=newBlog();blog.setTitle("一个人的秘密");blog.setContent("这是blog的具体内容");BmobACLacl=newBmobACL();//创建ACL对象acl.setReadAccess(BmobUser.getCurrentUser(this),true);//设置当前用户可写的权限acl.setWriteAccess(BmobUser.getCurrentUser(this),true);//设置当前用户可写的权限blog.setACL(acl);//设置这条数据的ACL信息blog.save(this,newSaveListener(){@OverridepublicvoidonSuccess(){//添加成功}@OverridepublicvoidonFailure(intcode,Stringmsg){//添加失败}});角色管理上面的指定用户访问权限虽然很方便,但是对于有些应用可能会有一定的局限性。比如一家公司的工资系统,员工和公司的出纳们只拥有工资的读权限,而公司的人事和老板才拥有全部的读写权限。要实现这种功能,你也可以通过设置每个用户的ACL权限来实现,如下:

//创建公司某用户的工资对象WageInfowageinfo=newWageInfo();wageinfo.setWage(100000);//这里创建四个用户对象,分别为老板、人事小张、出纳小谢和自己BmobUserboss;BmobUserhr_zhang;BmobUsercashier_xie;BmobUserme;//创建ACL对象BmobACLacl=newBmobACL();//设置四个用户读的权限acl.setReadAccess(boos,true);acl.setReadAccess(hr_zhang,true);acl.setReadAccess(cashier_xie,true);acl.setReadAccess(me,true);//设置老板和人事小张对这个工资的写权限acl.setWriteAccess(boss,true);acl.setWriteAccess(hr_zhang,true);//设置工资对象的ACLwageinfo.setACL(acl);wageinfo.save(this,newSaveListener(){@OverridepublicvoidonSuccess(){//保存成功}@OverridepublicvoidonFailure(intcode,Stringmsg){//保存失败}});但是,一个公司的人事、出纳和员工不仅仅只有一个人,同时还会有离职、调换岗位以及新员工加入等问题存在。如果用上面的代码对公司的每个人进行一一设置的话是不现实的,既麻烦也很难维护。针对这个问题,我们可以利用BmobRole来解决。我们只需要对用户进行分类,每个分类赋予不同的权限。如下代码实现:

下面我们来说一下角色与角色之间的从属关系。用一个例子来说明下:一个互联网企业有移动部门,部门中有不同的小组,如Android开发组和IOS开发组。每个小组只拥有自己小组的代码读写权限,但这两个小组同时拥有核心库代码的读权限。

Bmob允许用户根据地球的经度和纬度坐标进行基于地理位置的信息查询。通过在BmobObject的查询中添加一个BmobGeoPoint的对象查询,你就可以实现轻松查找出离当前用户最接近的信息或地点的功能。

首先需要创建一个BmobGeoPoint对象。例如,创建一个东经116.39727786183357度,北纬39.913768382429105度的BmobGeoPoint对象:

BmobGeoPointpoint=newBmobGeoPoint(116.39727786183357,39.913768382429105);查询地理位置信息现在,你的数据表中有了一定的地理坐标对象的数据,这样可以测试找出最接近某个点的信息了。你可以使用BmobQuery对象的addWhereNear方法来这样做:

BmobQuerybmobQuery=newBmobQuery();bmobQuery.addWhereNear("gpsAdd",newBmobGeoPoint(112.934755,24.52065));bmobQuery.setLimit(10);//获取最接近用户地点的10条数据bmobQuery.findObjects(this,newFindListener(){@OverridepublicvoidonSuccess(Listobject){//TODOAuto-generatedmethodstubtoast("查询成功:共"+object.size()+"条数据。");}@OverridepublicvoidonError(intcode,Stringmsg){//TODOAuto-generatedmethodstubtoast("查询失败:"+msg);}});要限制查询指定距离范围的数据可以使用addWhereWithinKilometers、addWhereWithinMiles或addWhereWithinRadians方法。

要查询一个矩形范围内的信息可以使用addWhereWithinGeoBox来实现:

BmobGeoPointsouthwestOfSF=newBmobGeoPoint(116.10675,39.711669);BmobGeoPointnortheastOfSF=newBmobGeoPoint(116.627623,40.143687);BmobQueryquery=newBmobQuery();query.addWhereWithinGeoBox("gpsAdd",southwestOfSF,northeastOfSF);query.findObjects(this,newFindListener(){@OverridepublicvoidonSuccess(Listobject){//TODOAuto-generatedmethodstubtoast("查询成功:共"+object.size()+"条数据。");}@OverridepublicvoidonError(intcode,Stringmsg){//TODOAuto-generatedmethodstubtoast("查询失败:"+msg);}});注意事项目前有几个需要注意的地方:

很多时候,单纯的前端代码是不能完成全部事情的,一些重要和复杂的业务逻辑还是希望能够在服务端中执行。比如:对比较大量的比赛数据进行排序,对某个网站进行资料采集和处理,获取用户的IP信息,等等。Bmob不仅提供了云端存储,还开放了云端的业务逻辑代码功能,也就是云端代码。

云端代码的执行有多种方法:

其中,在SDK中调用云端代码的方法如下:

AsyncCustomEndpointsace=newAsyncCustomEndpoints();//第一个参数是上下文对象,第二个参数是云端代码的方法名称,第三个参数是上传到云端代码的参数列表(JSONObjectcloudCodeParams),第四个参数是回调类ace.callEndpoint.callEndpoint(MainActivity.this,cloudCodeName,params,newCloudCodeListener(){@OverridepublicvoidonSuccess(Objectobject){//TODOAuto-generatedmethodstubtoast("云端usertest方法返回:"+object.toString());}@OverridepublicvoidonFailure(intcode,Stringmsg){//TODOAuto-generatedmethodstubtoast("访问云端usertest方法失败:"+msg);}});消息推送消息推送简介推送通知是让用户及时被通知、和你的应用保持联系的一种非常棒的方式,你可以快速而有效地通知到所有的用户,下面这个教程将会教你如何使用Bmob来推送消息。

二、在您的应用程序AndroidManifest.xml文件中添加相应的权限:

三、在您的应用程序AndroidManifest.xml文件中注册BmobPushSDK运行所需的推送服务和消息接收器:

四、在你的应用程序中创建一个消息接收器。

Push消息通过action=cn.bmob.push.action.MESSAGE的Intent把数据发送给客户端your.package.MyPushMessageReceiver,消息格式由应用自己决定,PushService只负责把服务器下发的消息以字符串格式透传给客户端。your.package.MyPushMessageReceiver代码示例如下:

publicclassMyPushMessageReceiverextendsBroadcastReceiver{@OverridepublicvoidonReceive(Contextcontext,Intentintent){//TODOAuto-generatedmethodstubif(intent.getAction().equals(PushConstants.ACTION_MESSAGE)){Log.d("bmob","客户端收到推送内容:"+intent.getStringExtra(PushConstants.EXTRA_PUSH_MESSAGE_STRING));}}}五、启动推送服务

在你的应用程序主Activity中调用如下方法:

六、在web端进行推送设置

七、在web端推送消息

在后台推送消息给Android和iOS两个平台的时候,有一些需要注意的:1、由于Android和iOS的提送机制不同,iOS要经过APNS,Android的推送完全是走Bmob的长连接服务,为兼容这个问题,如果你选择发送格式为“json”格式时,需要添加APNS兼容头部(见下面json的aps部分),推送内容格式如下:

{"aps":{"sound":"cheering.caf","alert":"这个是通知栏上显示的内容","badge":0},"xx":"json的key-value对,你可以根据情况添加更多的,客户端进行解析获取",}其中,sound是iOS接收时的声音,badge是iOS通知栏的累计消息数。

2、如果你选择发送格式为“text”时,推送内容为“推送消息测试。。。。”,Bmob会自动添加aps部分发送给APNS,,相当于自动生成如下的json格式的推送内容:

{"aps":{"alert":"推送消息测试。。。。",}}同时,也会发送给Android端,相当于自动生成如下的json格式的推送内容:

{"alert":"推送消息测试。。。。",}3、如果只是发送给Android端,大家可以自定义json格式的数据。

4、由于iOS的APNS的推送的大小是有限制的,默认最多256bytes,因此,如果你需要跨平台互通的话,需注意推送的内容不要太长。

八、源码下载

Bmob官方为大家准备了消息推送的视频教程,有需要的朋友可以移步浏览视频教程:

每一个Bmob的App被安装在用户的设备上后,如果要使用消息推送功能,BmobSDK会自动生成一个Installation对象。Installation对象包含了推送所需要的所有信息。举例:一个棒球的App,你可以让用户订阅感兴趣的棒球队,然后及时将这个球队的消息推送给用户。您可以使用BmobSDK,通过BmobInstallation对象进行一系列操作,就像你存储和获取其他的普通对象一样,比如BmobObject对象。

BmobInstallation对象有几个系统默认的特殊字段来帮助你进行设备定位等管理:

使用消息推送前,首先需要保存设备信息。

BmobInstallation.getCurrentInstallation(this).save();你还可以通过定义继承自BmobInstallation的JavaBean来为BmobInstallation对象添加更多的属性,用来定制更通用的推送。

publicclassMyBmobInstallationextendsBmobInstallation{privateintscore;publicintgetScore(){returnscore;}publicvoidsetScore(intscore){this.score=score;}}订阅频道和退订订阅频道订阅频道可使用subscribe方法

BmobInstallationinstallation=BmobInstallation.getCurrentInstallation(this);installation.subscribe("Giants");installation.subscribe("Mets");installation.save();退订频道退订频道可使用unsubscribe方法

BmobInstallationinstallation=BmobInstallation.getCurrentInstallation(this);installation.unsubscribe("Giants");installation.save();广播推送消息在客户端实现推送消息的功能,通过BmobPushManager对象来完成,比如给所有设备推送一条消息,如下:

BmobPushManagerbmobPush=newBmobPushManager(this);bmobPush.pushMessageAll("HelloBmob.");组播推送消息发送消息给订阅了Giants频道的用户

BmobPushManagerbmobPush=newBmobPushManager(this);BmobQueryquery=BmobInstallation.getQuery();Listchannels=newArrayList();channels.add("Giants");query.addWhereEqualTo("channels",channels);bmobPush.setQuery(query);bmobPush.pushMessage("消息内容");同时发送消息给多个频道时,可以将其他频道添加在channels中。

BmobPushManagerbmobPush=newBmobPushManager(this);BmobQueryquery=BmobInstallation.getQuery();query.addWhereLessThan("updatedAt",newBmobDate(newDate()));bmobPush.setQuery(query);bmobPush.pushMessage("消息内容");根据查询条件做推送BmobPushManagerbmobPush=newBmobPushManager(this);BmobQueryquery=BmobInstallation.getQuery();query.addWhereEqualTo("score",80);bmobPush.setQuery(query);bmobPush.pushMessage("消息内容");请注意,where条件查询的都是installations表。这里是假设installations表存储了score的Number属性,你可以像查询普通对象一样构造where查询

给Android平台的终端推送

BmobPushManagerbmobPush=newBmobPushManager(this);BmobQueryquery=BmobInstallation.getQuery();query.addWhereEqualTo("deviceType","android");bmobPush.setQuery(query);bmobPush.pushMessage("消息内容");给IOS平台的终端推送

BmobPushManagerbmobPush=newBmobPushManager(this);BmobQueryquery=BmobInstallation.getQuery();query.addWhereEqualTo("deviceType","ios");bmobPush.setQuery(query);bmobPush.pushMessage("消息内容");根据地理位置信息做推送BmobPushManagerbmobPush=newBmobPushManager(this);BmobQueryquery=BmobInstallation.getQuery();query.addWhereWithinRadians("location",newBmobGeoPoint(112.934755,24.52065),1.0);bmobPush.setQuery(query);bmobPush.pushMessage("消息内容");上面的例子假设installation表中有个location属性是GeoPoint类型,我们就可以根据地理信息位置做推送。

发送给Android单个客户端

StringinstallationId="客户端installationId";BmobPushManagerbmobPush=newBmobPushManager(this);BmobQueryquery=BmobInstallation.getQuery();query.addWhereEqualTo("installationId",installationId);bmobPush.setQuery(query);bmobPush.pushMessage("消息内容");发送给iOS单个客户端

短信服务的功能包括:

9001

内容:AppKeyisNull,PleaseinitializeBmobSDK.

含义:AppKey为空,请初始化。

9002

内容:Parsedataerror

含义:解析返回数据出错

9003

内容:uploadfileerror

含义:上传文件出错

9004

内容:uploadfilefailure

含义:文件上传失败

9005

内容:Abatchoperationcannotbemorethan50

含义:批量操作只支持最多50条

9006

内容:objectIdisnull

含义:objectId为空

9007

内容:BmobFileFilesizemustbelessthan10M.

含义:文件大小超过10M

9008

内容:BmobFileFiledoesnotexist.

含义:上传文件不存在

9009

内容:Nocachedata.

含义:没有缓存数据

9010

内容:Thenetworkisnotnormal.(Timeout)

含义:网络超时

9011

内容:BmobUserdoesnotsupportbatchoperations.

含义:BmobUser类不支持批量操作

9012

内容:contextisnull.

含义:上下文为空

9013

内容:BmobObjectObjectnames(databasetablename)formatisnotcorrect.

含义:BmobObject(数据表名称)格式不正确

9014

9015

含义:其他错误均返回此code

9016

内容:Thenetworkisnotavailable,pleasecheckyournetwork!

含义:无网络连接,请检查您的手机网络。

由于BmobAndroidSDK本身进行了代码混淆,因此,你在给应用打包编译混淆时,请不要混淆BmobSDK的代码,另外,任何继承自BmobObject、BmobUser的JavaBean请不要混淆。具体可参考BmobExample中proguard-project.txt的代码:

THE END
1.steam账号被盗邮箱被改怎么找回?steam邮箱找回账号步骤找回账号需要流畅的网络,方便我们在找回过程中不会出现卡顿,找回失败的情况。 用迅游加速器,永久免费加速team商店,steam社区网络,找回账号更轻松。 点击左下角【口令兑换】输入口令【2468】免费领取3天加速时长 首先我们进入steam的官网,点击这里直接进入 然后点击客服,点击下面的请求帮助,我无法登录 https://www.xunyou.com/452/99168.shtml
2.密码找回流程:基于邮件验证的安全找回方案通过邮件验证找回密码可以避免一些安全问题,比如用户忘记密码时无法找回、被他人冒充找回密码等情况,提高了账号的安全性。 流程清晰简单 基于邮件验证的密码找回流程简单清晰,用户只需通过点击邮件中的链接和设置新密码两个步骤即可完成密码找回,无需繁琐的操作,提高了用户体验。 https://www.jianshu.com/p/6337e93e9ea0
3.网页忘记密码怎么办?一招帮你找回密码!怎么查看网站上的密码一招帮你找回密码! 有没有遇到过这种情况,网页上还保存着密码,但是就是忘记了密码是多少,想着换电脑或者退出登录后就怎么办? 其实找回密码非常简单,选择密码,然后鼠标右键点击检查。 把Password改成text,然后回车即可发现密码已经显示,没有比这个操作更加简单的了。https://blog.csdn.net/yaosichengalpha/article/details/143996070
4.个人档案存放查询入口官网,一步教你找回档案!个人档案存放查询入口官网,一步教你找回档案!档案资料存放之后一些问题就接踵而来了,比如说档案资料造成丢失,或者是档案资料需要查询的问题。在毕业季的时候都是比较频繁的,大多数朋友所呈现出来的问题都是档案资料需要查询,因为他们没有办法准确的判断自己的个人档案https://www.jyjindu.com/danganchaxun/43280/
5.2025辽宁国家公务员考试成绩查询入口什么时间开通2准考证号查询找回方法二:到人事考试网中找 1、登录当地人事考试网。例如你是北京的,就去北京人事局官网。附:全国各省市人事网站点击查看全文国考成绩计算方法1第一种情况考生只参加公共科目笔试和面试 综合成绩计算方法:公共科目笔试总成绩(非通用语职位和特殊专业职位笔试合成成绩)占50:%,面试成绩和专业科目考https://ln.offcn.com/zg/gkcj/
6.你注册过哪些网站?一搜便知手机换号,如何保护您的数据?立即采取行动,找回您使用原手机号注册或绑定过的各种应用,进行注销或解绑操作。如何找回注册过的各种应用?上 REG007,一搜便知。https://www.reg007.com/
7.海外购改版通知跳至主要内容https://www.amazon.cn/gp/help/customer/display.html
8.中国建设银行建行官网、建设银行官方网站、建行、中国建设银行、存贷及银行卡、悦享生活、优智规划、账户查询、网点直通、便利服务、业务申请、电子银行开通、电话银行菜单定制、快搜快购、存款、贷款、闲钱也能增值、莘莘学子馆、积分圆梦微公益、不http://www.ccb.com/
9.我的小米云服务小米云服务 简体中文 了解云服务 随时随地,管理你的所有设备和数据 使用小米账号登录https://us.i.mi.com/
10.小米账号小米账号能使用小米手机,小米云,多看阅读,米聊,小米社区等小米服务。http://www.account.xiaomi.com/
11.托福考试报名官网入口:https://toefl.neea.cn点击进入新东方在线托福整理了2024年托福考试时间、成绩查询、分数说明、 报名官网入口和费用等信息,今天带来的是托福考试报名官网入口:https: toefl neea cn,希望对大家的托福考试有所帮助!https://toefl.koolearn.com/20231010/857069.html
12.找果网苹果手机找回方法,苹果iPhone手机丢了找回,认准找果网!找果网,成立于2012年,是全国较早开始提供iPhone找回服务网站之一,提供专业和权威的苹果手机找回方法,公司从事丢失iPhone找回服务8年时间,累计已成功找回iPhone手机超过万余台,是全国多地治安单位指定技术合作企业!https://www.zhaoiphone.com/
13.找回你www.zhaohuini.com网友收藏找回你 链接基本信息: 链接地址:http://www.zhaohuini.com/ 链接标题:找回你,注册过哪些网站 所属网站:www.zhaohuini.com 被收藏次数:1次 发现者:qtgjwhbd 最先发现时间:2018-07-05 06:47:48 所有收藏用户:qtgjwhbd 您也可以收藏:收藏该链接 链接相关查询: http://www.fwol.cn/show_sc.php?urlid=15765406
14.“查找手机”帮你锁定设备保护数据常见问题3. 如丢失的手机已开启【手机无网络时用短信查询】功能,丢失后即使无网络,仍可通过短信查找(前提:设备需要插入中国大陆境内运营商SIM卡)。 *定位手机最高精准度可在10米左右。 如何使用【查找手机】进行定位? 方法一、使用网页查找手机 ①进入云服务官网(cloud.heytap.com),使用丢失手机的realme账号登录; https://www.realme.com/cn/support/kw/doc/2086809
15.《梦幻西游》电脑版客服专区梦幻西游电脑版官网|网易通行证|官方论坛 快速搜索: 解除账号锁定 游戏自助解锁/解封入口 处罚记录查询 游戏处罚原因查询通道 安全模式 安全模式介绍与解除方法 几率/摆错价问题 这类问题无法处理 物品/金钱被回收 查看回收原因 忘记账号找回 找回丢失的账号 https://xyq.gm.163.com/
16.和包中国移动和包是面向个人和企业客户提供的一项综合性移动支付业务。用和包APP,可享方便快捷的线上支付(手机免费转账、互联网购物、充话费、生活缴费等)及线下和包(NFC)消费功能(便利店、商场、公交、地铁等)https://www.cmpay.com/
17.恢复你的Apple账户忘记密码? 验证你的账户信息以重设密码。https://iforgot.apple.com/cn
18.移动手机号码的服务密码怎么查询?这四种方法帮你轻松找回!这四种方法帮你轻松找回! 我们在日常去营业厅办理手机业务时经常会被客服询问手机号码的服务密码,有的小伙伴儿们对于就十分疑惑不知道自己的手机号码服务密码是什么?那么移动手机号码的服务密码怎么查询?今天小编就教大家四种方法轻松找回移动手机号码服务密码!https://www.shoujihao.com/show-50-11404/
19.帮你找回“私房钱”!这些APP立功了帮你找回“私房钱”!这些APP立功了 炒股第一步,先开个股票账户 上周基金E账户APP试运行之后,不少朋友找回了遗忘的“私房钱”,中证君也找回了两年前在某平台上投资的2000多块钱基金,有点小欣喜。 有人说,如果名下的银行卡和存款也能一网查询就好了。其实云闪付APP早就有这个功能,中证君就查过很多次。https://finance.eastmoney.com/a/202302132635026779.html
20.oppo云服务云服务可以在云端安全存储您的照片、视频、联系人、便签等重要数据。当您的手机数据意外丢失或者需要更换手机时,可以随时将这些存储在云端的数据快速恢复到手机中。同时支持跨端查看、编辑手机本地文件,是您高效的随身工作台。http://note.yun.oppo.com/
21.圆通快递单号查询物流信息的多种方法,你知道几种?如果物流订单号丢失,首先需要找回。 1.快递单号的序列号。 当你发现你寄的快递单号不见了,你可以去查一下你写的那个号码的序列号,当然前提是你拿出来的快递单上会有每个号码的序列号,要么是上一个,要么是下一个。 2.如果是收件人的订单号,请直接联系寄件人,或者再次向寄件人索取。 http://www.bjhwtx.com/h-nd-232899.html
22.开封Plus客户端隐私政策隐私协议在你使用发布文章、帐号找回等需要进行身份认证的功能或相关服务时,根据相关法律法规,我们可能会收集你的真实身份信息(真实姓名、电话号码)以完成实名验证。 其中身份证号码属于个人敏感信息,你可以拒绝提供,如果拒绝提供你将可能无法获得相关服务,但不影响其他功能与服务的正常使用。 https://www.kf.cn/c/2020-12-25/27744.shtml