2

Я использую Mobile Backend Starter в моем приложении, и я в состоянии непрерывно получать данные, используя этот код:Mobile Backend обрабатывать непрерывные запросы в фоновом режиме

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 

Как я могу добиться того, что я хочу?

ответ

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!"); 
    } 
} 
... 
} 

Теперь давайте поговорим об ошибке вы получили, это в основном потому, что вы включили «Обеспеченный идентификаторов клиента» вариант в вашем мобильном Backend Starter серверную конфигурационную страницу без указания web_client_id как на странице конфигурации сервера, так и в файле андроида app consts. Текущий CloudBackendAndroidClientSample неправильно обрабатывает разрешение Oauth на озеро. Поэтому каждый раз, когда вы запускаете приложение снова, и ему нужно получить доступ к серверу, генерируется UserRecoverableAuthIOException, но вместо того, чтобы показывать вам диалог согласия OAuth, пример приложения фактически ничего не значит. Так что для того, чтобы решить эту проблему, вы можете:

  1. (Preferred) Убедитесь, что вы объявили и использовать один и тот же веб-идентификатор клиента в вашем приложении и в вашей конфигурации сервера, как описано в этом google I/O video around 19'
  2. (Глупо) Измените образец кода, чтобы показать диалог согласия Oauth всякий раз, когда возникает исключение, так что пользователь может предоставить доступ вашему приложению к вашему серверу, что в этом случае глупо с точки зрения пользователя. Вы можете посмотреть Пример кода учебного курса Google на github. В 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); 
        } 
    ... 
    } 
    
1

Я не играл с Mobile Backend Starter, но ваш вопрос звучит так, как будто вы хотели бы реализовать Service и использовать облачный бэкэнд внутри службы. Таким образом, вы можете установить связь, пока ваше приложение неактивно. Вот e good tutorial.

0

Это может быть в Деятельности, поэтому, когда вы закрываете приложение, диспетчер приложений уничтожит его. Лучше всего использовать Сервис. Вы можете использовать данные из службы в методе OnServiceConnected. Также вы можете отправлять уведомления из служб тоже!

1

Возможно, лучше всего использовать либо службу http://developer.android.com/reference/android/app/Service.html, либо библиотеку GCM http://developer.android.com/guide/google/gcm/gs.html от Google. Он может отправлять push-уведомления на ваше Android-устройство, что может заставить ваше устройство что-то сделать. Для синхронизации данных.

Смежные вопросы