0

由于这个谷歌指南,我能够接收 GCM 注册 ID(用于推送通知)并将 reg.id 存储在数据库中,并且无需身份验证一切正常。我使用 web api 2、oauth 2 身份验证和帐户管理器。

1)用户登录应用,App为用户创建一个账户。
- 或者如果存在帐户,则自动登录用户。
2) 应用程序获取身份验证令牌,如果过期则通过 Volley 字符串请求检索它
3) 应用程序检查帐户管理器的用户数据(如果注册)。之前收到的身份证。如果不是 App 请求注册。来自 GCM 的 id 并通过 Volley 将其发布到服务器(此处需要 AuthToken),并且 App 在该 reg 的帐户中设置了一个用户数据。id 已收到。

我的应用程序的上述流程目前只存在于我的脑海中,我有一些问题。

首先,我怎样才能首先获得身份验证令牌,然后根据Guide转到 IntentService 的第 3 步。

其次,假设我们设法完成了第一个问题。如果用户从不同的设备登录到他的帐户会发生什么?我应该更新他的注册吗?他的新设备的 ID。但是,如果这个设备是临时的,他回来使用他的永久设备怎么办?通知将发送到临时设备,因为这是他最后一次登录的设备!

我真的很困惑,并且会感谢任何照亮我的方式的人。谢谢。

编辑

是否可以在 AsyncTask 中同时获取授权令牌和注册 ID(令牌),而不是遵循 Google 的指南(而不是使用 IntentService)?

4

2 回答 2

1

就像问题第二部分的答案一样。用户和他的 regId 之间的关系应该是 1 到 n。所以 1 个用户可以拥有多个设备,并且通过这个多个 regId。当您想向该用户发送消息时 - 您应该发送多条消息(每台设备 1 条)。其他可能的解决方案是使用最近引入的Device Group Messaging,而 IMO 是它的首选方式。

于 2015-08-24T13:00:36.367 回答
0

感谢您的回答,它仅在我使用两个异步任务时才有效,这是我的解决方案。欢迎任何批评或建议。

我创建了一个 TokenCheckerActivity 并将其放在登录活动和主要活动之间。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_token_checker);

    webApiUri = "url Here";
    tokenContext = this;

    accountManager = accountManager.get(tokenContext);
    PpSharedPreferences ppSharedPreferences = new PpSharedPreferences(tokenContext);
    ppAuthenticator = new PpAuthenticator(tokenContext);

    account = ppAuthenticator.getCurrentAccount(ppSharedPreferences.getUsername());

    new GetAuthorizationToken().execute(ppSharedPreferences.getUsername());
}

异步任务

/**
 * Gets the authorization token and checks if GCM registration id received.
 * Gets reg is if not exists.
 */
private class GetAuthorizationToken extends AsyncTask<String,Void,String>{
    @Override
    protected String doInBackground(String... params) {
        String username = params[0];
        String mAuthToken = ppAuthenticator.getPpAuthToken(username);
        return mAuthToken;
    }

    @Override
    protected void onPostExecute(String authToken) {
        if(!TextUtils.isEmpty(authToken))
        {
            final String gcmTokenSent = accountManager.getUserData(account, AccountGeneral.GCM_REGISTRATION_ID);
            if (gcmTokenSent == null || !gcmTokenSent.equals("true")) {
                new GetGcmRegistrationToken().execute(authToken);
            } else {
                // We have the Gcm Registration Id continue to the main activity
                Intent intent = new Intent(tokenContext, MainActivity.class);
                startActivity(intent);
                finish();
            }
        }
    }
}


private class GetGcmRegistrationToken extends AsyncTask<String,Void,PpTokens>{
    @Override
    protected PpTokens doInBackground(String... params) {
        PpTokens tokens = new PpTokens();
        tokens.setAuthToken(params[0]);
        try {
            if (checkPlayServices()) {
                InstanceID instanceID = InstanceID.getInstance(tokenContext);
                String regToken = instanceID.getToken(getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
                tokens.setRegToken(regToken);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return tokens;
    }

    @Override
    protected void onPostExecute(PpTokens tokens) {
        if (!TextUtils.isEmpty(tokens.getRegToken()))
        {
            sendRegistrationToServer(tokens.getRegToken(),tokens.getAuthToken());
        }
    }
}

    private class PpTokens
{
    private String authToken;
    private String regToken;

    public String getAuthToken() {
        return authToken;
    }

    public void setAuthToken(String authToken) {
        this.authToken = authToken;
    }

    public String getRegToken() {
        return regToken;
    }

    public void setRegToken(String regToken) {
        this.regToken = regToken;
    }
}

将 reg id 发送到服务器

private void sendRegistrationToServer(String regToken, final String authToken) {
    final String tag_json_obj = "json_obj_req";
    String url = webApiUri + "?gcmRegistrationToken=" + regToken;

    JsonObjectRequest objectRequest = new JsonObjectRequest(Request.Method.POST, url, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {

            try {
                Log.d("Name for Reg Token:", response.getString("Name"));

                // You should store a boolean that indicates whether the generated token has been
                // sent to your server. If the boolean is false, send the token to your server,
                // otherwise your server should have already received the token.
                accountManager.setUserData(account, AccountGeneral.GCM_REGISTRATION_ID, "true");

                Intent intent = new Intent(tokenContext, MainActivity.class);
                startActivity(intent);
                finish();

            } catch (JSONException e) {
                e.printStackTrace();
            }

        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            String errorMessage = JsonErrorMessageHandler.onErrorResponse(error);
            accountManager.setUserData(acc, AccountGeneral.GCM_REGISTRATION_ID, "false");
        }
    }) {
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("Authorization", "Bearer " + authToken);
            return headers;
        }
    };

    int socketTimeout = 5000;
    int maxRetries = 3;
    RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, maxRetries, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
    objectRequest.setRetryPolicy(policy);

    // Adding request to request queue
    AppController.getInstance().addToRequestQueue(objectRequest, tag_json_obj);
}
于 2015-08-25T07:48:36.553 回答