简体   繁体   中英

Parse Push “No Activity Found” on opening Push Notification

I made an app using Parse as backend. I am able to get the notification but when i tap on it, the app crashes.

Here are the java and XML files.

AndroidManifest.xml

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

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <permission
        android:name="chipset.lugmnotifier.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="chipset.lugmnotifier.permission.C2D_MESSAGE" />

    <application
        android:name=".resources.ParseInitApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <meta-data
            android:name="com.parse.push.notification_icon"
            android:resource="@drawable/ic_notification" />

        <activity
            android:name=".HomeActivity"
            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=".AdminActivity"
            android:label="@string/title_activity_admin"
            android:parentActivityName=".HomeActivity">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".HomeActivity" />
        </activity>

        <service android:name="com.parse.PushService" />

        <receiver android:name="com.parse.ParseBroadcastReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.USER_PRESENT" />
            </intent-filter>
        </receiver>
        <receiver
            android:name="com.parse.ParsePushBroadcastReceiver"
            android:exported="false">
            <intent-filter>
                <action android:name="com.parse.push.intent.RECEIVE" />
                <action android:name="com.parse.push.intent.DELETE" />
                <action android:name="com.parse.push.intent.OPEN" />
            </intent-filter>
        </receiver>
        <receiver
            android:name="com.parse.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="chipset.lugmnotifier" />
            </intent-filter>
        </receiver>
    </application>

</manifest>

ParseInitApplication.java

import android.app.Application;
import android.util.Log;

import com.parse.Parse;
import com.parse.ParseException;
import com.parse.ParseInstallation;
import com.parse.ParsePush;
import com.parse.SaveCallback;

import static chipset.lugmnotifier.resources.Constants.APPLICATION_ID;
import static chipset.lugmnotifier.resources.Constants.CLIENT_KEY;

public class ParseInitApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        Parse.initialize(this, APPLICATION_ID, CLIENT_KEY);
        ParsePush.subscribeInBackground("", new SaveCallback() {
            @Override
            public void done(ParseException e) {
                if (e != null) {
                    Log.d("com.parse.push", "successfully subscribed to the broadcast channel.");
                } else {
                    Log.e("com.parse.push", "failed to subscribe for push", e);
                }
            }
        });
        ParseInstallation.getCurrentInstallation().saveInBackground();
    }

}

HomeActivity.java

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.method.PasswordTransformationMethod;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListView;

import com.parse.FindCallback;
import com.parse.ParseAnalytics;
import com.parse.ParseException;
import com.parse.ParseObject;
import com.parse.ParseQuery;

import org.duncavage.swipetorefresh.widget.SwipeRefreshLayout;

import java.util.List;

import chipset.lugmnotifier.resources.Functions;
import chipset.lugmnotifier.resources.NotificationListViewAdapter;
import de.keyboardsurfer.android.widget.crouton.Crouton;
import de.keyboardsurfer.android.widget.crouton.Style;

import static chipset.lugmnotifier.resources.Constants.KEY_CLASS_NOTIFICATION;
import static chipset.lugmnotifier.resources.Constants.KEY_DETAIL;
import static chipset.lugmnotifier.resources.Constants.KEY_TITLE;
import static chipset.lugmnotifier.resources.Constants.PASSWORD;

public class HomeActivity extends Activity {


    ListView notificationsListView;
    SwipeRefreshLayout notificationSwipeRefreshLayout;
    Functions functions = new Functions();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        ParseAnalytics.trackAppOpened(getIntent());
        notificationSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.notificationSwipeRefreshLayout);
        notificationsListView = (ListView) findViewById(R.id.notificationListView);
        notificationSwipeRefreshLayout.setColorScheme(R.color.alizarin, R.color.emerald, R.color.peterRiver, R.color.sunFlower);
        notificationSwipeRefreshLayout.setActionBarSwipeIndicatorText(R.string.swipe_to_refresh);
        notificationSwipeRefreshLayout.setActionBarSwipeIndicatorRefreshingText(R.string.loading);
        notificationSwipeRefreshLayout.setActionBarSwipeIndicatorBackgroundColor(
                getResources().getColor(R.color.alizarin));
        notificationSwipeRefreshLayout.setActionBarSwipeIndicatorTextColor(
                getResources().getColor(R.color.clouds));
        notificationSwipeRefreshLayout.setActionBarSwipeIndicatorRefreshingTextColor(
                getResources().getColor(R.color.clouds));
        notificationSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                new FetchData().getNotifications();
            }
        });
        new FetchData().getNotifications();


    }

    private class FetchData {

        public void getNotifications() {
            if (functions.isConnected(getApplicationContext())) {
                notificationSwipeRefreshLayout.setRefreshing(true);
                ParseQuery<ParseObject> query = ParseQuery.getQuery(KEY_CLASS_NOTIFICATION);
                query.findInBackground(new FindCallback<ParseObject>() {
                    @Override
                    public void done(List<ParseObject> parseObjects, ParseException e) {
                        notificationSwipeRefreshLayout.setRefreshing(false);
                        final String[] title = new String[parseObjects.size()];
                        final String[] detail = new String[parseObjects.size()];
                        if (e == null) {
                            for (int i = 0; i < parseObjects.size(); i++) {
                                title[i] = parseObjects.get(i).getString(KEY_TITLE);
                                detail[i] = parseObjects.get(i).getString(KEY_DETAIL);
                            }
                            notificationsListView.setAdapter(new NotificationListViewAdapter(getApplicationContext(), title, detail));
                            notificationsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                                @Override
                                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                                    Crouton.showText(HomeActivity.this, title[i] + " - " + detail[i], Style.INFO);
                                }
                            });
                        } else {
                            Crouton.showText(HomeActivity.this, e.getMessage(), Style.ALERT);
                        }
                    }
                });
            } else {
                notificationSwipeRefreshLayout.setRefreshing(false);
                Crouton.showText(HomeActivity.this, "No internet connection", Style.ALERT);
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.

        getMenuInflater().inflate(R.menu.menu, menu);
        return true;

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_admin) {
            final EditText passwordEditText = new EditText(HomeActivity.this);
            passwordEditText.setTransformationMethod(PasswordTransformationMethod.getInstance());
            AlertDialog.Builder builder = new AlertDialog.Builder(HomeActivity.this);
            builder.setTitle("Admin Panel");
            builder.setMessage("Enter the admin password");
            builder.setView(passwordEditText);
            builder.setPositiveButton("LOGIN", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    if (passwordEditText.getText().toString().equals(PASSWORD)) {
                        startActivity(new Intent(HomeActivity.this, AdminActivity.class));
                    } else {
                        Crouton.showText(HomeActivity.this, "Incorrect Password", Style.ALERT);
                    }
                }
            });
            builder.setNeutralButton("CANCEL", null);
            builder.create();
            builder.show();
        }
        return super.onOptionsItemSelected(item);
    }
}

StackTrace (of the crash)

10:46:02.302  15739-15739/chipset.lugmnotifier E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: chipset.lugmnotifier, PID: 15739
    java.lang.RuntimeException: Unable to start receiver com.parse.ParsePushBroadcastReceiver: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat= flg=0x1000c000 (has extras) }
            at android.app.ActivityThread.handleReceiver(ActivityThread.java:2414)
            at android.app.ActivityThread.access$1700(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1272)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5001)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat= flg=0x1000c000 (has extras) }
            at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1632)
            at android.app.Instrumentation.execStartActivitiesAsUser(Instrumentation.java:1481)
            at android.app.ContextImpl.startActivitiesAsUser(ContextImpl.java:1080)
            at android.content.ContextWrapper.startActivitiesAsUser(ContextWrapper.java:344)
            at android.content.ContextWrapper.startActivitiesAsUser(ContextWrapper.java:344)
            at android.app.TaskStackBuilder.startActivities(TaskStackBuilder.java:221)
            at android.app.TaskStackBuilder.startActivities(TaskStackBuilder.java:232)
            at android.app.TaskStackBuilder.startActivities(TaskStackBuilder.java:208)
            at com.parse.TaskStackBuilderHelper.startActivities(TaskStackBuilderHelper.java:19)
            at com.parse.ParsePushBroadcastReceiver.onPushOpen(ParsePushBroadcastReceiver.java:202)
            at com.parse.ParsePushBroadcastReceiver.onReceive(ParsePushBroadcastReceiver.java:108)
            at android.app.ActivityThread.handleReceiver(ActivityThread.java:2407)
            at android.app.ActivityThread.access$1700(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1272)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5001)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method)

I want to open HomeActivity on notification tap. Any help will be appreciated. If any other file is required, please let me know I'll add it.

Quoting from below post by Ahmad Raza Exception when opening Parse push notification

You can extend ParsePushBroadcastReceiver and override onPushOpen method.

public class Receiver extends ParsePushBroadcastReceiver {

    @Override
    public void onPushOpen(Context context, Intent intent) {
        Log.e("Push", "Clicked");
        Intent i = new Intent(context, HomeActivity.class);
        i.putExtras(intent.getExtras());
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(i);
    }
}

Use it in manifest, (Instead of using ParsePushBroadcastReceiver)

<receiver
        android:name="your.package.name.Receiver"
        android:exported="false" >
    <intent-filter>
        <action android:name="com.parse.push.intent.RECEIVE" />
        <action android:name="com.parse.push.intent.DELETE" />
        <action android:name="com.parse.push.intent.OPEN" />
    </intent-filter>
</receiver>

After a long effort, it worked for me:

ParsePushApplication.java

public class ParsePushApplication extends Application {
@Override
public void onCreate(){
    super.onCreate();
    Parse.initialize(this, "App_Key", "Client_Key");
    ParseInstallation.getCurrentInstallation().saveInBackground();
   }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

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

    ParseAnalytics.trackAppOpenedInBackground(getIntent());
    try {
        Intent intent = getIntent();
        Bundle extras = intent.getExtras();
        if (extras != null) {
            String jsonData = extras.getString("com.parse.Data");
            JSONObject json;
            json = new JSONObject(jsonData);
            String pushStore = json.getString("alert");
            Toast.makeText(MainActivity.this, pushStore, Toast.LENGTH_LONG).show();
    } catch (JSONException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

Receiver.java

public class Receiver extends ParsePushBroadcastReceiver {

private static final String TAG = "MyNotificationsReceiver";

@Override
public void onPushOpen(Context context, Intent intent) {
    Log.e("Push", "Clicked");
    Intent i = new Intent(context, MainActivity.class);
    i.putExtras(intent.getExtras());
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(i);
    }
}

Manifest.xml

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

<!-- IMPORTANT: Change "your.package.name" to match your app's package name. -->

<application
    android:name=".ParsePushApplication"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <meta-data
        android:name="com.parse.push.notification_icon"
        android:resource="@drawable/push_icon"/>

    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

    </activity>
    <service android:name="com.parse.PushService" />

    <receiver android:name="com.parse.ParseBroadcastReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.USER_PRESENT" />
        </intent-filter>
    </receiver>
    <receiver
        android:name="your.package.name.Receiver"
        android:exported="false" >
        <intent-filter>
            <action android:name="com.parse.push.intent.RECEIVE" />
            <action android:name="com.parse.push.intent.DELETE" />
            <action android:name="com.parse.push.intent.OPEN" />
        </intent-filter>
    </receiver>

    <receiver android:name="com.parse.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" />

            <!--
              IMPORTANT: Change "your.package.name" to match your app's package name.
            -->
            <category android:name="your.package.name" />
        </intent-filter>
    </receiver>

</application>

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

<!--
  IMPORTANT: Change "your.package.name.permission.C2D_MESSAGE" in the lines below
  to match your app's package name + ".permission.C2D_MESSAGE".
-->
<permission android:protectionLevel="signature"
    android:name="your.package.name.permission.C2D_MESSAGE" />
<uses-permission android:name="com.zeeroapps.parsetutorial_cli.permission.C2D_MESSAGE" />

</manifest>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM