Skip to main content
 首页 » 编程设计

android之使用 App Engine Python 的 C2DM 返回 401 错误

2025年05月04日23jiqing9006

我正在尝试向我的手机发送消息。通过浏览器,我调用执行此操作的方法,我记录了 registrationId、authToken 等。这是正确的,因为我在本地服务器中进行了测试,并且消息已使用这些 key 发送到我的手机。

但是,在 App Engine 上,我对“https://android.clients.google.com/c2dm/”的 urlfetch.fetch 结果出现 401 错误发送'。

或者如果这是身份验证的问题。我怀疑是不是上面的问题,因为方法被调用了,错误发生在我的 App Engine 服务器中方法的末尾。

以下是我向 C2DM 服务器发出请求的方式:

params = { 
          'registration_id':registrationId, 
          'collapse_key':0, 
          'data.payload':encoded_msg 
         } 
 
        paramsByte = urllib.urlencode(params) 
        logging.info(registrationId) 
 
        url = 'https://android.clients.google.com/c2dm/send' 
        logging.info(token) 
        result = urlfetch.fetch(url=url, 
                                payload=paramsByte, 
                                method=urlfetch.POST, 
                                headers={'Content-Type':'application/x-www-form-urlencoded', 
                                         'Authorization':'GoogleLogin auth='+token} 
                                ) 

如有任何帮助,我们将不胜感激。谢谢。


更新

Now the client is running in a hosting server as suggested, and the 401 error happens when contacting 'https://android.clients.google.com/c2dm/send'.

但是,当在具有相同 token 和 regId 的终端上使用以下命令时,它会起作用。

curl --header "Authorization: GoogleLogin auth=your_authenticationid" "https://android.apis.google.com/c2dm/send" -d registration_id=your_registration -d "data.payload=payload" -d collapse_key=0

客户端代码调用服务器中的方法:

$.getJSON('http://myapp.appspot.com/method?userId='+userId+'&message='+theMessage+'&callback=?',  
    function(data) 
    { 
        console.log(data); 
    }); 

服务器的完整方法代码:

class PushHandler(webapp.RequestHandler): 
 
    '''This method sends the message to C2DM server to send the message to the phone''' 
    def get(self): 
        logging.info('aqui dentro') 
        userId = self.request.get('userId') 
        message = self.request.get('message') 
        callback = self.request.get('callback') 
        token = getToken(self) #this is a method I've implemented to get the token from C2DM servers by passing the SenderId and Password 
        registrationId = '' 
        contactNumber = '' 
 
        # Get the registrationId to send to the C2DM server to know which  
        # device it may send the message 
        regQuery = C2DMUser.all() 
        regQuery.filter('userId =', int(userId)) 
        for k in regQuery: 
            registrationId = k.registrationId 
 
        # Builds the json to be sent to the phone 
        record_to_json = { 
                          'userId':userId, 
                          'message':message 
                          } 
        data = [] 
        data.append(record_to_json) 
        jsondata = simplejson.dumps(data) # Creates the json 
 
        # Encode the JSON String 
        u = unicode(jsondata, "utf-8") 
        encoded_msg = u.encode("utf-8") 
 
        params = { 
                  'registration_id':registrationId, 
                  'collapse_key':0, 
                  'data.payload':encoded_msg 
                  } 
 
        paramsByte = urllib.urlencode(params) 
 
        url = 'https://android.clients.google.com/c2dm/send' 
        logging.info(token) 
        result = urlfetch.fetch(url=url, 
                                payload=paramsByte, 
                                method=urlfetch.POST, 
                                headers={'Content-Type':'application/x-www-form-urlencoded', 
                                         'Authorization':'GoogleLogin auth='+token} 
                                ) 
 
        data = [] 
        params_key = { 'status_code':result.status_code } 
        data.append(params_key) 
        self.response.headers['Content-Type'] = 'application/json' 
        jsondata = simplejson.dumps(data) 
 
        if result.status_code == 200: 
            logging.info(result.status_code) 
            self.response.out.write('' + callback + '(' + jsondata + ')') # handle the JSONP 
        else: 
            logging.info(result.status_code) 
            self.response.out.write(result.status_code) 

请您参考如下方法:

您的代码包名称必须与您在注册​​ c2dm 帐户时提供的名称一致。对于 Java,如果您在注册时提供了 com.myapp,则您的 c2dm 调用必须在该包内进行。不过,不确定这如何转化为 Python。