首页 \ 问答 \ GCM推送通知(GCM Push notification)

GCM推送通知(GCM Push notification)

我能够从GCM成功发送推送通知,但我无法从INTENT数据中捕获消息。 消息变量没有获取任何数据。

我的GCMIntentService类

protected void onMessage(Context context, Intent data) {
    String message;
    message = data.getExtras().getString("message");
    Log.i("message",data.toString());
    Intent intent = new Intent(this, GCMMessageView.class);
    intent.putExtra("message", message);
    PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent,
            PendingIntent.FLAG_UPDATE_CURRENT);

    Notification notification = new Notification.Builder(this)
            .setSmallIcon(R.drawable.ic_launcher)
            .setWhen(System.currentTimeMillis())
            .setContentTitle("Android GCM Tutorial")
            .setContentText(message).setContentIntent(pIntent)
            .build();
    notification.flags |= Notification.FLAG_AUTO_CANCEL;

    NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    manager.notify(R.string.app_name, notification);

}

我的有效载荷

{
"message": "Hi I am nutritown",
"registration_ids":["registrationId"]
}

来自GCM的响应{“multicast_id”:8633384191969300942,“success”:1,“failure”:0,“canonical_ids”:0,“results”:[{“message_id”:“0:1420884152153321%b49c80e8f9fd7ecd”}]}

我的android清单文件

<permission android:name="com.androidbegin.gcmtutorial.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.androidbegin.gcmtutorial.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<application
    android:allowBackup="false"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
        android:name=".GCMMainActivity"
        android:launchMode="singleTask" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".GCMMessageView" >
    </activity>

    <service android:name=".GCMIntentService" />

    <receiver
        android:name="com.google.android.gcm.GCMBroadcastReceiver"
        android:permission="com.google.android.c2dm.permission.SEND" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

            <category android:name="com.androidbegin.gcmtutorial" />
        </intent-filter>
    </receiver>
</application>

I am able to successfully send Push notification from GCM but I am not able to catch message from INTENT data. The message variable is not getting any data.

My GCMIntentService class

protected void onMessage(Context context, Intent data) {
    String message;
    message = data.getExtras().getString("message");
    Log.i("message",data.toString());
    Intent intent = new Intent(this, GCMMessageView.class);
    intent.putExtra("message", message);
    PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent,
            PendingIntent.FLAG_UPDATE_CURRENT);

    Notification notification = new Notification.Builder(this)
            .setSmallIcon(R.drawable.ic_launcher)
            .setWhen(System.currentTimeMillis())
            .setContentTitle("Android GCM Tutorial")
            .setContentText(message).setContentIntent(pIntent)
            .build();
    notification.flags |= Notification.FLAG_AUTO_CANCEL;

    NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    manager.notify(R.string.app_name, notification);

}

My Payload

{
"message": "Hi I am nutritown",
"registration_ids":["registrationId"]
}

Response from GCM {"multicast_id":8633384191969300942,"success":1,"failure":0,"canonical_ids":0,"results": [{"message_id":"0:1420884152153321%b49c80e8f9fd7ecd"}]}

My android manifest file

<permission android:name="com.androidbegin.gcmtutorial.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.androidbegin.gcmtutorial.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<application
    android:allowBackup="false"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
        android:name=".GCMMainActivity"
        android:launchMode="singleTask" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".GCMMessageView" >
    </activity>

    <service android:name=".GCMIntentService" />

    <receiver
        android:name="com.google.android.gcm.GCMBroadcastReceiver"
        android:permission="com.google.android.c2dm.permission.SEND" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

            <category android:name="com.androidbegin.gcmtutorial" />
        </intent-filter>
    </receiver>
</application>

原文:https://stackoverflow.com/questions/27875029
更新时间:2021-05-21 15:05

最满意答案

我会用三个组件来解决这个问题。 我重写了一些你的组件。 我删除了不必要的状态道具和代码。 您可以复制并粘贴然后尝试分析代码。 如果你有任何问题,我在这里

WeatherApp.js

import React, { Component } from 'react';
import { WeatherForm } from './WeatherForm';
import { WeatherCard } from './WeatherCard';

export class WeatherApp extends Component {
    constructor(props) {
      super(props);
        this.state = {
            lat: 0,
            long: 0,
        }
        this.onSubmit = this.onSubmit.bind(this);
    }

    onSubmit = (lat, long) => {
        this.setState({
          lat,
          long
        });
    }


    render() {
        return(
          <div>
            <WeatherForm onSubmit={this.onSubmit}/>
            <WeatherCard lat={this.state.lat} long={this.state.long}/>
          </div>

        )
    }
}

WeatherForm.js

import React, { Component } from 'react';

export class WeatherForm extends Component {

  constructor(props) {
      super(props);
      this.state = {
          lat: 0,
          long: 0,
      }
      this.onChangeLat = this.onChangeLat.bind(this);
      this.onChangeLong = this.onChangeLong.bind(this);
      this.onSubmit = this.onSubmit.bind(this);
  }

  onChangeLat = (e) => {

      let value = e.target.value;
      if(!isNaN(value) ){
        this.setState({
            lat: e.target.value
        });
      }
  }

  onChangeLong = (e) => {
    let value = e.target.value;
    if(!isNaN(value) ){
      this.setState({
          long: e.target.value
      });
    }
  }

  onSubmit = (e) => {
    e.preventDefault();
    if (this.state.lat.length == 0 || this.state.long.length == 0) {
        alert("You must enter something");
    }else{
      this.props.onSubmit(this.state.lat, this.state.long)
    }

  }

  render() {
      return(
          <div>
              <h1>Welcome to the Weather App!</h1>
              <form onSubmit={this.onSubmit}>
                  Enter the Latitude in decimal format: <input type="text" name="lat" value={this.state.lat} onChange={this.onChangeLat}/>
                  <br/>
                  Enter the Longitude in decimal format: <input type="text" name="long" value={this.state.long} onChange={this.onChangeLong}/>
                  <br/>
                  <button >Submit</button>
              </form>
          </div>
      )
  }
}

WeatherCard.js

import React, { Component } from 'react';
import ReactAnimatedWeather from 'react-animated-weather';


const defaults = [
  {
      icon: 'CLEAR_DAY',
      color: 'white',
      size: 175,
      animate: true
  },
  {
      icon: 'CLEAR_NIGHT',
      color: 'white',
      size: 175,
      animate: true
  },
  {
      icon: 'PARTLY_CLOUDY_DAY',
      color: 'white',
      size: 175,
      animate: true
  },
  {
      icon: 'PARTLY_CLOUDY_NIGHT',
      color: 'white',
      size: 175,
      animate: true
  },
  {
      icon: 'CLOUDY',
      color: 'white',
      size: 175,
      animate: true
  },
  {
      icon: 'RAIN',
      color: 'white',
      size: 175,
      animate: true
  },
  {
      icon: 'SLEET',
      color: 'white',
      size: 175,
      animate: true
  },
  {
      icon: 'SNOW',
      color: 'white',
      size: 175,
      animate: true
  },
  {
      icon: 'WIND',
      color: 'white',
      size: 175,
      animate: true
  },
  {
      icon: 'FOG',
      color: 'white',
      size: 175,
      animate: true
  }
];

function iconConverter(arg){
    switch (arg) {
        case 'clear-day': return 0;
            break;
        case 'clear-night': return 1;
            break;
        case 'partly-cloudy-day': return 2;
            break;
        case 'partly-cloudy-night': return 3;
            break;
        case 'cloudy': return 4;
            break;
        case 'rain': return 5;
            break;
        case 'sleet': return 6;
            break;
        case 'snow': return 7;
            break;
        case 'wind': return 8;
            break;
        case 'fog': return 9;
            break;

    }
}

const WCard = ({day, high, low, humidity, summary, sunrise, sunset, windspeed, time, rainProb, icon}) =>{
    return (
        <div>
            <p>{time}</p>
            <div id='wCardIcon'>

                <ReactAnimatedWeather

                    icon={defaults[iconConverter(icon)].icon}
                    color={defaults[iconConverter(icon)].color}
                    size={defaults[iconConverter(icon)].size}
                    animate={defaults[iconConverter(icon)].animate}
                  />
                <div>
                    <p>&#8679; {high}&#8457;</p>
                    <p>{low}&#8457; &#8681;</p>
                </div>
            </div>
            <p id="wCardSum">{summary}</p>
            <p>Humidity: {humidity}%</p>
            <p>Wind speed: {windspeed}mph</p>
            <p>Sunrise: {sunrise}</p>
            <p>Sunset: {sunset}</p>
            <p>Chance of rain: {rainProb}%</p>

        </div>
    )};

export class WeatherCard extends Component {
    constructor(props) {
        super(props)
        this.state = {
            requestFailed: false,
            info: undefined,
            latLongValue: this.props.latLong
        }
    }

    componentDidMount(){
      this.fetchData(this.props.lat, this.props.long);
    }

    componentWillReceiveProps(nextProps){
       this.fetchData(nextProps.lat, nextProps.long);
    }

    timeDateConverter(tempTime) {
        var time = tempTime *1000;
        var d = new Date(time);
        var formattedDate = (d.getMonth() + 1) + "/" + d.getDate() + "/" + d.getFullYear();

        return formattedDate
    }

    removeMilitary(hours){

        if (hours > 0 && hours <= 12) {
            hours = "" + hours;
        } else if (hours > 12) {
            hours = "" + (hours - 12);
        } else if (hours === 0) {
            hours= "12";
        }
        return hours;
    }

    timeConverter(tempTime) {
        var time = tempTime *1000;
        var d = new Date(time);
        var hours = d.getHours();
        if (hours>=12){                 //Adding endings
                var suffix = "P.M.";}
            else{
                suffix = "A.M.";}
        var minutes = (d.getMinutes() < 10) ? "0" + d.getMinutes() : d.getMinutes();

        hours = this.removeMilitary(hours);

        var formattedTime = hours + ":" + minutes + " " + suffix;

        return formattedTime;
    }

    fetchData(lat, long){
      const weatherRequest = `https://api.darksky.net/forecast/fbdca57e2ef5b4ac0f12e3d3779f090e/${lat},${long}`;
      console.log(weatherRequest);
      fetch(weatherRequest).then( data => data.json() ).then( data => {
            this.setState({
                info: data,
                requestFailed: true
            });
        }, () => {
            this.setState({
            requestFailed: true
            })
      })
    }


    render() {
        return(
            this.state.info ? (<div>
                <h1>The current temperature in {this.state.info.timezone} is: {this.state.info.currently.apparentTemperature}</h1>
                <h1>The 8 day forecast for {this.state.info.timezone}:</h1>
                <ul>
                    {this.state.info.daily.data.map((day, id) =>
                        <div key={'_' + Math.random().toString(36).substr(2, 9)} id="weatherCard">
                            <WCard time={this.timeDateConverter(day.time)}
                                high={day.temperatureHigh}
                                low={day.temperatureLow}
                                summary={day.summary}
                                icon={day.icon}
                                humidity={day.humidity}
                                sunrise={this.timeConverter(day.sunriseTime)}
                                sunset={this.timeConverter(day.sunsetTime)}
                                rainProb={day.precipProbability}
                                windspeed={day.windSpeed}
                            />
                        </div>
                    )}
                </ul>

                <a href="https://darksky.net/poweredby/">Powered by DarkSky</a>

            </div>
          ) : <div>Loading</div>
        )
    }
}

I would approach the problem with three components. I have re-write some of your components. I removed unnecessary state props and code. You can copy and paste then try to analyse the code. I am here if you have any question

WeatherApp.js

import React, { Component } from 'react';
import { WeatherForm } from './WeatherForm';
import { WeatherCard } from './WeatherCard';

export class WeatherApp extends Component {
    constructor(props) {
      super(props);
        this.state = {
            lat: 0,
            long: 0,
        }
        this.onSubmit = this.onSubmit.bind(this);
    }

    onSubmit = (lat, long) => {
        this.setState({
          lat,
          long
        });
    }


    render() {
        return(
          <div>
            <WeatherForm onSubmit={this.onSubmit}/>
            <WeatherCard lat={this.state.lat} long={this.state.long}/>
          </div>

        )
    }
}

WeatherForm.js

import React, { Component } from 'react';

export class WeatherForm extends Component {

  constructor(props) {
      super(props);
      this.state = {
          lat: 0,
          long: 0,
      }
      this.onChangeLat = this.onChangeLat.bind(this);
      this.onChangeLong = this.onChangeLong.bind(this);
      this.onSubmit = this.onSubmit.bind(this);
  }

  onChangeLat = (e) => {

      let value = e.target.value;
      if(!isNaN(value) ){
        this.setState({
            lat: e.target.value
        });
      }
  }

  onChangeLong = (e) => {
    let value = e.target.value;
    if(!isNaN(value) ){
      this.setState({
          long: e.target.value
      });
    }
  }

  onSubmit = (e) => {
    e.preventDefault();
    if (this.state.lat.length == 0 || this.state.long.length == 0) {
        alert("You must enter something");
    }else{
      this.props.onSubmit(this.state.lat, this.state.long)
    }

  }

  render() {
      return(
          <div>
              <h1>Welcome to the Weather App!</h1>
              <form onSubmit={this.onSubmit}>
                  Enter the Latitude in decimal format: <input type="text" name="lat" value={this.state.lat} onChange={this.onChangeLat}/>
                  <br/>
                  Enter the Longitude in decimal format: <input type="text" name="long" value={this.state.long} onChange={this.onChangeLong}/>
                  <br/>
                  <button >Submit</button>
              </form>
          </div>
      )
  }
}

WeatherCard.js

import React, { Component } from 'react';
import ReactAnimatedWeather from 'react-animated-weather';


const defaults = [
  {
      icon: 'CLEAR_DAY',
      color: 'white',
      size: 175,
      animate: true
  },
  {
      icon: 'CLEAR_NIGHT',
      color: 'white',
      size: 175,
      animate: true
  },
  {
      icon: 'PARTLY_CLOUDY_DAY',
      color: 'white',
      size: 175,
      animate: true
  },
  {
      icon: 'PARTLY_CLOUDY_NIGHT',
      color: 'white',
      size: 175,
      animate: true
  },
  {
      icon: 'CLOUDY',
      color: 'white',
      size: 175,
      animate: true
  },
  {
      icon: 'RAIN',
      color: 'white',
      size: 175,
      animate: true
  },
  {
      icon: 'SLEET',
      color: 'white',
      size: 175,
      animate: true
  },
  {
      icon: 'SNOW',
      color: 'white',
      size: 175,
      animate: true
  },
  {
      icon: 'WIND',
      color: 'white',
      size: 175,
      animate: true
  },
  {
      icon: 'FOG',
      color: 'white',
      size: 175,
      animate: true
  }
];

function iconConverter(arg){
    switch (arg) {
        case 'clear-day': return 0;
            break;
        case 'clear-night': return 1;
            break;
        case 'partly-cloudy-day': return 2;
            break;
        case 'partly-cloudy-night': return 3;
            break;
        case 'cloudy': return 4;
            break;
        case 'rain': return 5;
            break;
        case 'sleet': return 6;
            break;
        case 'snow': return 7;
            break;
        case 'wind': return 8;
            break;
        case 'fog': return 9;
            break;

    }
}

const WCard = ({day, high, low, humidity, summary, sunrise, sunset, windspeed, time, rainProb, icon}) =>{
    return (
        <div>
            <p>{time}</p>
            <div id='wCardIcon'>

                <ReactAnimatedWeather

                    icon={defaults[iconConverter(icon)].icon}
                    color={defaults[iconConverter(icon)].color}
                    size={defaults[iconConverter(icon)].size}
                    animate={defaults[iconConverter(icon)].animate}
                  />
                <div>
                    <p>&#8679; {high}&#8457;</p>
                    <p>{low}&#8457; &#8681;</p>
                </div>
            </div>
            <p id="wCardSum">{summary}</p>
            <p>Humidity: {humidity}%</p>
            <p>Wind speed: {windspeed}mph</p>
            <p>Sunrise: {sunrise}</p>
            <p>Sunset: {sunset}</p>
            <p>Chance of rain: {rainProb}%</p>

        </div>
    )};

export class WeatherCard extends Component {
    constructor(props) {
        super(props)
        this.state = {
            requestFailed: false,
            info: undefined,
            latLongValue: this.props.latLong
        }
    }

    componentDidMount(){
      this.fetchData(this.props.lat, this.props.long);
    }

    componentWillReceiveProps(nextProps){
       this.fetchData(nextProps.lat, nextProps.long);
    }

    timeDateConverter(tempTime) {
        var time = tempTime *1000;
        var d = new Date(time);
        var formattedDate = (d.getMonth() + 1) + "/" + d.getDate() + "/" + d.getFullYear();

        return formattedDate
    }

    removeMilitary(hours){

        if (hours > 0 && hours <= 12) {
            hours = "" + hours;
        } else if (hours > 12) {
            hours = "" + (hours - 12);
        } else if (hours === 0) {
            hours= "12";
        }
        return hours;
    }

    timeConverter(tempTime) {
        var time = tempTime *1000;
        var d = new Date(time);
        var hours = d.getHours();
        if (hours>=12){                 //Adding endings
                var suffix = "P.M.";}
            else{
                suffix = "A.M.";}
        var minutes = (d.getMinutes() < 10) ? "0" + d.getMinutes() : d.getMinutes();

        hours = this.removeMilitary(hours);

        var formattedTime = hours + ":" + minutes + " " + suffix;

        return formattedTime;
    }

    fetchData(lat, long){
      const weatherRequest = `https://api.darksky.net/forecast/fbdca57e2ef5b4ac0f12e3d3779f090e/${lat},${long}`;
      console.log(weatherRequest);
      fetch(weatherRequest).then( data => data.json() ).then( data => {
            this.setState({
                info: data,
                requestFailed: true
            });
        }, () => {
            this.setState({
            requestFailed: true
            })
      })
    }


    render() {
        return(
            this.state.info ? (<div>
                <h1>The current temperature in {this.state.info.timezone} is: {this.state.info.currently.apparentTemperature}</h1>
                <h1>The 8 day forecast for {this.state.info.timezone}:</h1>
                <ul>
                    {this.state.info.daily.data.map((day, id) =>
                        <div key={'_' + Math.random().toString(36).substr(2, 9)} id="weatherCard">
                            <WCard time={this.timeDateConverter(day.time)}
                                high={day.temperatureHigh}
                                low={day.temperatureLow}
                                summary={day.summary}
                                icon={day.icon}
                                humidity={day.humidity}
                                sunrise={this.timeConverter(day.sunriseTime)}
                                sunset={this.timeConverter(day.sunsetTime)}
                                rainProb={day.precipProbability}
                                windspeed={day.windSpeed}
                            />
                        </div>
                    )}
                </ul>

                <a href="https://darksky.net/poweredby/">Powered by DarkSky</a>

            </div>
          ) : <div>Loading</div>
        )
    }
}

相关问答

更多