Tapping a Notification from OneSignal does not ope

2020-06-22 05:45发布

问题:

Now I know there are lot of questions on this, but I have faced no luck at all and thought to ask a question here.

I have an application which just runs a splashscreen followed by a MainActivity(Which is just a WebView) Now I integrated this with OneSignal for receiving push notifications.

Everything works good, I mean I get a notification when sent through the onesignal website to my phone - but the thing I am facing is, tapping the notification does not get my ResultActivity(Just a activity displaying a Toast of message).

My code snippets looks as below:

splashscreen.java:

public class splashscreen extends Activity {
@Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.splash);
      Thread splashThread = new Thread() {
         @Override
         public void run() {
            try {
               int waited = 0;
               while (waited < 5000) {
                  sleep(100);
                  waited += 100;
               }
            } catch (InterruptedException e) {
               // do nothing
            } finally {
               finish();
               Intent i = new Intent();
               i.setClassName("com.google",
                              "com.google.Main");
               startActivity(i);
            }
         }
      };
      splashThread.start();
   }
   @Override
   protected void onPause() {
       super.onPause();
       OneSignal.onPaused();
   }
   @Override
   protected void onResume() {
       super.onResume();
       OneSignal.onResumed();
   }
} 

Main.java:

@SuppressLint("SetJavaScriptEnabled") public class Main extends Activity     {
    /** Called when the activity is first created. */

    WebView web;
    private static Activity currentActivity;

    Intent resultIntent = new Intent(this, ResultActivity.class);


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        currentActivity = this;

        web = (WebView) findViewById(R.id.my_webview);
        web.setWebViewClient(new myWebClient());
        web.getSettings().setJavaScriptEnabled(true);
        web.loadUrl("http://google.com");

        OneSignal.init(this, "xxxxxxx", "xxx-xxx-xxxx-xxxx-xxxxxx", new ExampleNotificationOpenedHandler());

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu){
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main, menu);
        return true;
        }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
        case R.id.exit:
            finish();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    public class myWebClient extends WebViewClient
    {
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            // TODO Auto-generated method stub
            super.onPageStarted(view, url, favicon);
        }

        public boolean shouldOverrideUrlLoading(WebView view, String url) {

            String url2="http://google.com";
             // all links  with in ur site will be open inside the webview 
             //links that start with your domain example(http://www.example.com/)
            if (url != null && url.startsWith(url2)){
                return false;
                } 
           // all links that points outside the site will be open in a normal android browser
          else  {
                view.getContext().startActivity(
                new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
                return true;
                }
        }
    }

    // To handle "Back" key press event for WebView to go back to previous screen.
   @Override
   public boolean onKeyDown(int keyCode, KeyEvent event)
  {
    if ((keyCode == KeyEvent.KEYCODE_BACK) && web.canGoBack()) {
        web.goBack();
        return true;
    }
    return super.onKeyDown(keyCode, event);
   }

   @Override
   protected void onPause() {
       super.onPause();
       OneSignal.onPaused();
   }
   @Override
   protected void onResume() {
       super.onResume();
       OneSignal.onResumed();
   }



// NotificationOpenedHandler is implemented in its own class instead of adding implements to MainActivity so we don't hold on to a reference of our first activity if it gets recreated.
private class ExampleNotificationOpenedHandler implements NotificationOpenedHandler {
  /**
   * Callback to implement in your app to handle when a notification is opened from the Android status bar or
   * a new one comes in while the app is running.
   * This method is located in this activity as an example, you may have any class you wish implement NotificationOpenedHandler and define this method.
   *
   * @param message        The message string the user seen/should see in the Android status bar.
   * @param additionalData The additionalData key value pair section you entered in on onesignal.com.
   * @param isActive       Was the app in the foreground when the notification was received.
   */
  @Override
  public void notificationOpened(String message, JSONObject additionalData, boolean isActive) {
    String messageTitle = "OneSignal Example" + isActive, messageBody = message;


    try {
      if (additionalData != null) {
        if (additionalData.has("title"))
          messageTitle = additionalData.getString("title");
        if (additionalData.has("actionSelected"))
          messageBody += "\nPressed ButtonID: " + additionalData.getString("actionSelected");

        messageBody = message + "\n\nFull additionalData:\n" + additionalData.toString();
      }
    } catch (JSONException e) { }
    /*
    new AlertDialog.Builder(Main.currentActivity)
                   .setTitle(messageTitle)
                   .setMessage(messageBody)
                   .setCancelable(true)
                   .setPositiveButton("OK", null)
                   .create().show();
    */
    NotificationCompat.Builder mBuilder =
       new NotificationCompat.Builder(Main.currentActivity)
            .setSmallIcon(R.drawable.cc)
            .setContentTitle(messageTitle)

            .setDefaults(
                        Notification.DEFAULT_SOUND
                                | Notification.DEFAULT_VIBRATE
                                | Notification.FLAG_AUTO_CANCEL)  

            .setContentText(messageBody);

    resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);



    PendingIntent resultPendingIntent =
            PendingIntent.getActivity(
            Main.currentActivity,
            0,
            resultIntent,
            PendingIntent.FLAG_UPDATE_CURRENT
            | PendingIntent.FLAG_ONE_SHOT
        );    


    mBuilder.setContentIntent(resultPendingIntent);

   NotificationManager mNotifyMgr = 
            (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

   mNotifyMgr.notify(001, mBuilder.build());

  }
}
}

ResultActivity.java:

    public class ResultActivity extends Activity {
        /** Called when the activity is first created. */
         @Override
         protected void onCreate(Bundle savedInstanceState) {
          // TODO Auto-generated method stub
          super.onCreate(savedInstanceState);
          /*
          ImageView image = new ImageView(this);
          image.setImageDrawable(getResources().getDrawable(R.drawable.ic_launcher));
          setContentView(image);
          Toast.makeText(getApplicationContext(), 
            "Do Something NOW", 
            Toast.LENGTH_LONG).show();
            */
          super.onCreate(savedInstanceState);
          setContentView(R.layout.splash);
          }
    }

Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.google"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <uses-permission android:name="android.permission.INTERNET" />

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



    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >

        <meta-data android:name="com.google.android.gms.version"
           android:value="@integer/google_play_services_version" />
        <activity android:name="com.onesignal.NotificationOpenedActivity"  android:theme="@android:style/Theme.NoDisplay">
            </activity>


        <receiver
         android:name="com.onesignal.GcmBroadcastReceiver"
         android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <category android:name="com.google" />
            </intent-filter>
        </receiver>
        <service android:name="com.onesignal.GcmIntentService" />

        <activity android:name=".splashscreen" android:label="@string/app_name">
                <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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


        <activity android:name=".Main" android:label="@string/app_name" > 

        </activity>


        <activity android:name=".ResultActivity"
           android:label="@string/app_name"
           android:exported="true">
        </activity>



         <receiver
            android:name="com.google.OneSignalBackgroundDataReceiver"
            android:exported="false">
            <intent-filter>
            <action android:name="com.onesignal.BackgroundBroadcast.RECEIVE" />
            </intent-filter>
         </receiver>


    </application>

</manifest>

I have tried all these answers but none worked:

Notification Not open Acivity onCLick

Android Status Bar Notifications - Opening the correct activity when selecting a notification

Android :Tap on Push Notification does not open Application

Android click on notification does not open the attached Activity

It is painfull to modify one line and test it on device! Since onesignal allows only testing in device. Please help or atleast guide me how to debug.

Device on which the apk was tested : Samsung Galaxy S4 running Lolipop.

回答1:

Take a look at this link: https://documentation.onesignal.com/docs/android-customizations#section-background-data-and-notification-overriding (Search : "Changing the open action of a notification" in the page to go to the exact paragraph).

And this is an example: http://androidbash.com/android-push-notification-service-using-onesignal/

I don't have time to read your code carefully, but seems like it has some problems:

  1. You initialize OneSignal in the wrong place.

    "Make sure you are initializing OneSignal with setNotificationOpenedHandler in the onCreate method in your Application class. You will need to call startActivity from this callback" (OneSignal's document).

  2. You don't need any other receivers in AndroidManifest to catch intent and open your target activity, OneSignal.NotificationOpenedHandler already handle this. But don't forget this line to prevent OneSignal open your launcher activity:

<application ...>
   <meta-data android:name="com.onesignal.NotificationOpened.DEFAULT"  android:value="DISABLE" />
</application>

I use this solution in my app and it works fine. Because it's the way it is.



回答2:

OneSignal.init must be called from your launcher Activity, you will need to move it to your splashscreen Activity. This will get your ExampleNotificationOpenedHandler to fire when you open a OneSignal notification.

Make sure to also copy the calls to OneSignal.onPaused(); and OneSignal.onResumed(); into your splashscreen Activity. These need to be called in every Activity in the onPuase() and onResume() methods.