2

我在我的应用程序中使用 Mobile Backend Starter,并且能够使用以下代码连续接收数据:

CloudCallbackHandler<List<CloudEntity>> handler = new CloudCallbackHandler<List<CloudEntity>>() {
        @Override
        public void onComplete(List<CloudEntity> results) {
            Logger.log(MainActivity.this, "onComplete");
        }

        @Override
        public void onError(IOException e) {
            Logger.log(MainActivity.this, e);
        }
    };

    CloudQuery cq = new CloudQuery("Test");
    cq.setLimit(50);
    cq.setSort(CloudEntity.PROP_UPDATED_AT, Order.DESC);
    cq.setScope(Scope.FUTURE_AND_PAST);
    getCloudBackend().list(cq, handler);

当我的应用程序处于活动状态时,这一切都可以正常工作,但是当应用程序未处于活动状态时,我想用它来通知用户新数据可用。

当我关闭应用程序(通过按返回,而不是按主页)并强制向我的设备发送消息时,我收到以下错误:

07-04 18:30:23.084: I/CloudBackend(31368): error: 
07-04 18:30:23.084: I/CloudBackend(31368): com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException
07-04 18:30:23.084: I/CloudBackend(31368):  at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:222)
07-04 18:30:23.084: I/CloudBackend(31368):  at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:836)
07-04 18:30:23.084: I/CloudBackend(31368):  at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:412)
07-04 18:30:23.084: I/CloudBackend(31368):  at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:345)
07-04 18:30:23.084: I/CloudBackend(31368):  at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:463)
07-04 18:30:23.084: I/CloudBackend(31368):  at com.myapp.cloudbackend.CloudBackend.list(CloudBackend.java:340)
07-04 18:30:23.084: I/CloudBackend(31368):  at com.myapp.cloudbackend.CloudBackendAsync.access$8(CloudBackendAsync.java:1)
07-04 18:30:23.084: I/CloudBackend(31368):  at com.myapp.cloudbackend.CloudBackendAsync$9.callBackend(CloudBackendAsync.java:283)
07-04 18:30:23.084: I/CloudBackend(31368):  at com.myapp.cloudbackend.CloudBackendAsync$9.callBackend(CloudBackendAsync.java:1)
07-04 18:30:23.084: I/CloudBackend(31368):  at com.myapp.cloudbackend.CloudBackendAsync$BackendCaller.run(CloudBackendAsync.java:429)
07-04 18:30:23.084: I/CloudBackend(31368): Caused by: com.google.android.gms.auth.UserRecoverableAuthException: AppDownloadRequired
07-04 18:30:23.084: I/CloudBackend(31368):  at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
07-04 18:30:23.084: I/CloudBackend(31368):  at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
07-04 18:30:23.084: I/CloudBackend(31368):  at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:192)
07-04 18:30:23.084: I/CloudBackend(31368):  at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:217)
07-04 18:30:23.084: I/CloudBackend(31368):  ... 9 more

我怎样才能达到我想要的?

4

4 回答 4

1

可能最好使用的是服务http://developer.android.com/reference/android/app/Service.html或 GCM 库http://developer.android.com/guide/google/gcm/gs来自 Google 的.html 。它可以向您的 Android 设备发送推送通知,从而强制您的设备执行某些操作。用于同步数据。

于 2013-07-10T13:43:05.263 回答
1

我没有玩过 Mobile Backend Starter,但您的问题听起来像是您想实现一个服务并在服务内使用云后端。因此,您可以在您的应用程序未激活时建立通信。这是一个很好的教程

于 2013-07-08T19:58:24.917 回答
0

这可能在 Activity 中,因此当您关闭应用程序时,应用程序管理器将销毁它。所以最好的办法是使用服务。您可以在 OnServiceConnected 方法中从 Service 获取数据。您也可以从服务中触发通知!

于 2013-07-10T13:35:46.450 回答
0

那么你有两个不同的问题。

让我们谈谈如何通知用户有新数据可用,当应用程序不活跃时,实际上,您不必实现另一个意图服务,CloudBackendAndroidClientSample项目中已经有一个正在运行,您只需要做收到新消息后立即向用户显示通知。这可以通过将以下方法添加到 GCMIntentService 类来轻松完成:

public class GCMIntentService extends GCMBaseIntentService {
...
//add this method
public void showNotification(Context context, int id, String title, String message){
    Intent intent = new Intent(context, GuestbookActivity.class);
    intent.setAction(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_LAUNCHER);

    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    NotificationCompat.Builder mBuilder =
            new NotificationCompat.Builder(context.getApplicationContext())
            .setTicker(message)
            .setSmallIcon(R.drawable.ic_launcher)
            .setContentTitle(title)
            .setContentText(message)
            .setWhen(System.currentTimeMillis())
            .setContentIntent(pendingIntent)
            .setDefaults(Notification.DEFAULT_SOUND)
            .setAutoCancel(true)
            .setOngoing(false)
            .setOnlyAlertOnce(true)
            .setLights(0xFFFF0000, 500, 500); //setLights (int argb, int onMs, int offMs)
    Notification notification = mBuilder.build();

    // show it in the notification list
    notification.setLatestEventInfo(context, title, message, pendingIntent);

    NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(id, notification);
    Log.d(TAG, "notification should be shown");
}
...
//And simply call that function in your onMessage callback
@Override
public void onMessage(Context context, Intent intent) {
    // decode subId in the message
    String subId = intent.getStringExtra(GCM_KEY_SUBID);
    Log.i(Consts.TAG, "onMessage: subId: " + subId);
    String[] tokens = subId.split(":");
    String typeId = tokens[1];

    // dispatch message
    if (GCM_TYPEID_QUERY.equals(typeId)) {
        CloudBackendAsync.handleQueryMessage(tokens[2]);
        Log.e(TAG, "update notif");
        //call the fonction to show up your notification here
        showNotification(context, 1, getString(R.string.app_name), "new messages!");
    }
}
...
}

现在让我们谈谈您遇到的错误,这主要是因为您在 Mobile Backend Starter 服务器配置页面中启用了“由客户端 ID 保护”选项,而没有在服务器配置页面和 android app consts 文件中指定 web_client_id。当前的 CloudBackendAndroidClientSample 无法正确处理 Oauth 授权湖因此,每次您再次启动应用程序并且它需要访问服务器时,都会引发 UserRecoverableAuthIOException 但示例应用程序没有向您显示 OAuth 同意对话框,实际上什么都不做。所以为了解决这个问题,你可以:

  1. (首选)确保您在应用程序和服务器配置中声明并使用相同的 Web 客户端 ID,如19 岁左右的这个 google I/O 视频中所述
  2. (愚蠢)更改示例代码以在发生异常时显示 Oauth 同意对话框,以便用户可以授予对您的应用程序对您的服务器的访问权限,在这种情况下从用户体验的角度来看这是愚蠢的,您可以看一下github上的 google drive 教程示例代码。在 CloudBackendAndroidClientSample 中,CloudBackendAsync 在第 430 行附近捕获了异常

    private abstract class BackendCaller<PARAM, RESULT> extends Thread {  
    ...
    
    @Override
    public void run() {
    ...
    
       try{
          r = callBackend(param);
       } 
       catch (IOException e) {
          Log.i(Consts.TAG, "error: ", e);
          //The UserRecoverableAuthIOException is only logged here, a OAuth Consent Dialog should be opened to grant access to the server.
          ie = e;
       }
    
       //So you should change this catch by something like the following. 
       //Of course you will need an activity context to be able to call startActivityForResult, that is why I said you will need a little bit of refactoring.
       catch (UserRecoverableAuthIOException e) {
          startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
       }
    ...
    }
    
于 2013-07-12T04:08:18.057 回答