0

我正在开发适用于 Android 的 Pandora 应用程序,因此我可以向其添加 Wear 应用程序,当我尝试以用户身份在我的应用程序服务中连接时,我收到错误代码 13:

boolean partnerLoggedIn = Pandora.partnerLogin();
if (partnerLoggedIn) {
    boolean userLoggedIn = Pandora.userLogin(username, password);
    if (userLoggedIn) {
       //Do post login stuff

这是合作伙伴登录()。我获得了成功,并且能够毫无问题地解析响应中的所有数据:

public static boolean partnerLogin() throws JSONException {
    final JSONObject body = Partner.toJSON();
    final PandoraRequest request = new PandoraRequest("auth.partnerLogin", body, handler);
    Partner.setRequestSyncTime(System.currentTimeMillis());
    request.execute(JSON_URL + "auth.partnerLogin");
    String result = null;

    try {
        result = request.get();
    } catch (final InterruptedException e) {
        Log.w(TAG, "Connection interrupted for partnerLogin");
    } catch (final ExecutionException e) {
        Log.w(TAG, "Failed to execute partnerLogin task");
    }
    return Partner.parseLoginResponse(result);
}
public static JSONObject toJSON() {
    final JSONObject body = new JSONObject();
    try {
        body.put("username", "android");
        body.put("password", "AC7IBG09A3DTSYM4R41UJWL07VLN8JI7");
        body.put("deviceModel", "android-generic");
        body.put("version", Pandora.PROTOCOL_VERSION);
    }  catch (JSONException e) {
        Log.e(TAG, "toJSON failed: " + e.getMessage());
    }
    return body;
}

这是用户登录():

    public static boolean userLogin(final String username, final String password) {
    if (Partner.getPartnerAuthToken() != null) {
        User.setUsername(username);
        User.setPassword(password);

        final JSONObject body = User.toJSON();

        try {
            body.put("syncTime", Partner.getSyncTime());
            body.put("partnerAuthToken", Partner.getPartnerAuthToken());

            final PandoraRequest request = new PandoraRequest("auth.userLogin", body, true, handler);
            final String auth = URLEncoder.encode(Partner.getPartnerAuthToken(), "utf-8");
            final String loginURLMethod = String.format("&auth_token=%s&partner_id=%s", auth, Partner.getPartnerId());
            request.execute(JSON_URL + "auth.userLogin" + loginURLMethod);

            try {
                final String result = request.get();
                return User.parseLoginResponse(result);
            } catch (final InterruptedException e) {
                Log.w(TAG, "Connection interrupted for userLogin");
            } catch (final ExecutionException e) {
                Log.w(TAG, "Failed to execute userLogin task");
            }
        } catch (final UnsupportedEncodingException e) {
            Log.e(TAG, "Failed to encode partner auth token: " + Partner.getPartnerAuthToken());
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    return false;
}

这是我与 Pandora 通信的 AsyncTask:

protected String doInBackground(String... pandoraURL) {
    final StringBuilder result = new StringBuilder();

    for (final String element : pandoraURL) {
        try {
            //Log.e(TAG, "URL: " + element);
            final URL url = new URL(element);
            final HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setDoInput(true);
            urlConnection.setDoOutput(true);
            urlConnection.setRequestMethod("POST");
            urlConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");

            final OutputStream os = urlConnection.getOutputStream();
            if(encrypted) {
                final Encryption encryption = new Encryption();
                final String encrypted = encryption.encrypt(json.toString());
                os.write(encrypted.getBytes());
            } else {
                os.write(json.toString().getBytes());
            }
            os.flush();

            Log.i(TAG, "Response Code: " + urlConnection.getResponseCode());

            if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                final BufferedReader br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                String line;
                while ((line = br.readLine()) != null) {
                    result.append(line);
                }
                br.close();
            }
            os.close();
            urlConnection.disconnect();
        } catch (MalformedURLException e) {
            Log.e(TAG, "Bad URL: " + e.getMessage());
        } catch (IOException e) {
            Log.e(TAG, "Could not connect: " + e.getMessage());
        }
    }

    if(result.toString().contains("\"stat\":\"fail\"")) {
        parseFailureMessage(result.toString());
    }

    return result.toString();
}

现在,非官方 Pandora JSON api的错误 13 为“INSUFFICIENT_CONNECTIVITY。错误的同步时间?”

因此,根据 api 文档,我的同步时间被计算出来了:

public static long getSyncTime() {
    Encryption crypt = new Encryption();
    String decryptedSyncTime = crypt.decrypt(syncTime);
    final long time = System.currentTimeMillis() + Partner.getRequestSyncTime() - Long.valueOf(decryptedSyncTime);
    return time;
}

这一切都在大约一周前工作,我还没有更改 getSyncTime 函数。我尝试将所有内容恢复到它工作时的状态,但我仍然收到此错误。尝试在 WiFi 和 4G 上使用手机(以防万一。)我使用的凭据是正确的,因为错误的凭据将是不同的错误代码。

测试似乎表明 syncTime 在解密时会丢失几位数字(或首先没有得到它们):

例如,partnerLogin 响应有

"syncTime":"3fdb87fd2ca86037a263ab0ba76f77dc"

它存储为字符串。通过 decrypt() 运行它会产生:

1435335432

它不应该是“1435335432753”之类的东西,有 13 位数字,而不是 10 位,作为服务器时间戳等等?这里是解密:

    public String decrypt(final String encrypted) {
    try {
        final Cipher blowfishECB = Cipher.getInstance("Blowfish/ECB/PKCS5Padding");
        final SecretKeySpec blowfishKey = new SecretKeySpec(DECRYPT_PASSWORD.getBytes("UTF8"), "Blowfish");
        blowfishECB.init(Cipher.DECRYPT_MODE, blowfishKey);
        final byte[] decryptedBytes = blowfishECB.doFinal(decodeHex(encrypted.toCharArray()));

        // First 4 bytes are garbage according to specification (deletes first 4 bytes)
        final byte[] trimGarbage = Arrays.copyOfRange(decryptedBytes, 4, decryptedBytes.length);
        return new String(trimGarbage);
    } catch (final Exception e) {
        Log.e(TAG, "Failed to decrypt content", e);
        return null;
    }
}

这似乎工作正常,因为前 10 位数字是正确的。

4

1 回答 1

0

叹。显然我需要使用秒而不是毫秒。一切都必须是 10 位数字。

于 2015-06-26T19:17:21.547 回答