Android - Parse push notification crashes on open - java

I have set up parse push notifications and I had my app crash when I tried to open it, now I found a work around my making a new java class and overriding onPushOpen like this:
public class Receiver extends ParsePushBroadcastReceiver {
#Override
public void onPushOpen(Context context, Intent intent) {
Intent i = new Intent(context, MainActivity.class);
i.putExtras(intent.getExtras());
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
But in order to still receive push notifications I still need this depreciated method in my MyApplication.java class PushService.setDefaultPushCallback(this, MainActivity.class);
How could I get rid of this depreciated method I have looked at this question where I got some help but it did not answer this part about the depreciated method. Exception when opening Parse push notification.
I was thinking that maybe this method could be over ridden but Im not sure if it acutely handles recvieving the push or more handles the push after it has been received?
#Override
public void onPushReceive(final Context c, Intent i) {
// Handle the received push
}
Thanks for the help in advance.

You are subclassing ParsePushBroadcastReceiver.
Then in manifest
<receiver
android:name=".Receiver " // your broadcastreceiver
android:exported="false" >
<intent-filter>
// youtr actions
</intent-filter>
</receiver>
In BroadCastReceiver
public class Receiver extends ParseBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
extras = intent.getExtras();
if(intent.hasExtra("com.parse.Data"))
{
try
{
json = new JSONObject(intent.getExtras().getString("com.parse.Data"));
int notificationtype = json.getInt("notificationtype"); // this is send on the sender side
switch(notificationtype)
{
case 1:
// show your custom notification. Refer android notification guide
break;
case 2:
//rest of the code
Note : If either "alert" or "title" are specified in the push, then a Notification is constructed using getNotification. So no alert and title on the sender side.
Read Managing Push Lifecycle #
https://www.parse.com/docs/push_guide#receiving/Android
Reference
https://www.parse.com/questions/how-suppress-push-notification-from-being-displayed

Related

Android using broadcastReceiver, but when I force close the app, I don't get anything in the Activity

Not sure how to get the receiver to work on the activity once the app is forced closed.
What am I missing to get this to work even if the app was forced closed? Any help would be appreciated.
I am getting the BroadcastReceiver service to work, Just not getting anything to pick up on the activity level.
I have my receiver (Service):
public class MyReceiver extends BroadcastReceiver {
public static final String SEND_NOTIFICATION_ACTION = "com.clover.sdk.app.intent.action.APP_NOTIFICATION";
#Override
public void onReceive(Context context, Intent intent) {
Log.i("MyReceiver", "Triggered MyReceiver");
String action = intent.getAction();
Bundle getIntent = intent.getExtras();
if (action.equals(SEND_NOTIFICATION_ACTION)) {
Log.i("MyReceiver Gotten", "Found");
intent = new Intent("broadCastName");
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("orderId", getIntent.getString("payload"));
Log.i("Receiver OrderID", getIntent.getString("payload"));
context.sendBroadcast(intent);
}
}
}
My Activity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
registerReceiver(broadcastReceiver, new IntentFilter("broadCastName"));
}
}
Then my broadcastReceiver in my activity:
// Add this inside your class
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("MyReceiver Gotten 2", "Found");
Bundle b = intent.getExtras();
Log.i("MyReceiver Gotten 3", b.getString("orderId"));
new SpecificOrderAsyncTask(MainActivity.this).execute(b.getString("orderId"));
}
};
Not sure how to get the receiver to work on the activity once the app is forced closed. What am I missing to get this to work even if the app was forced closed?
That's contradictory - you can't get a receiver to work in an Activity that registered it at runtime if that Activity that is hosting the receiver is killed. When you force close, every in the app process - including the Activity and the receiver you registered with it - disappears.
The point of calling registerReceiver is to listen for broadcasts only during a specific time frame or lifecycle.
If you want the receiver to work even when the app is closed, don't register it at runtime - register it in the manifest.
Simple,
Registering service in an activity is temporary, registering service in a manifest will run even after closing the application.
But the broadcast you use is a simple message transfer system, that won't work even after you register in manifest and close the application. You have to create a background service that runs always in background in android system and should awake listening to some events passed.

onReceive from BroadcastReceiver is not called

I have a music application in which I am trying to add some action button on the notification bar.
I tried something like this:
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
Intent onPreparedIntent=new Intent("MEDIA_PLAYER_PREPARED").putExtra("CURR_SONG",songposn);
LocalBroadcastManager.getInstance(this).sendBroadcast(onPreparedIntent);
Intent notintent = new Intent(this, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Notification.Builder builder=new Notification.Builder(this);
PendingIntent pendingIntent=PendingIntent.getActivity(this,0,notintent,PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent prevPendingIntent=PendingIntent.getActivity
(this,1,new Intent().setAction("PREVIOUS"),PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pausePendingIntent=PendingIntent.getActivity
(this,2,new Intent().setAction("PAUSE"),PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent nextPendingIntent=PendingIntent.getActivity
(this,3,new Intent().setAction("NEXT"),PendingIntent.FLAG_UPDATE_CURRENT);;
builder.setContentIntent(pendingIntent).setSmallIcon(R.drawable.playicon)
.addAction(R.drawable.back, "Previous", prevPendingIntent)
.addAction(R.drawable.playsmall, "Pause", pausePendingIntent)
.addAction(R.drawable.forw, "Next", nextPendingIntent)
.setTicker(songArtist)
.setOngoing(true).setContentTitle(songTitle).setContentText(songArtist);
Notification not=builder.build();
startForeground(MusicService.NOTIFY_ID,not);
}
I declared a NotificationReciever class inside this service
public class NotificationReciever extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Log.e("here","here");
String action=intent.getAction();
if(action!=null){
switch (action){
case "PREVIOUS":{
playPrev();
break;
}
case "PAUSE":{
pausePlayer();
LocalBroadcastManager.getInstance(MusicService.this).sendBroadcast(new Intent("STOP_THREAD"));
break;
}
case "NEXT":{
playNext();
break;
}
}
}
}
}
Structure looks something like this:
-MusicService extends Service
--NotificationReciever extends BroadcastReceiver
My manifest file contains reciever like this:
<receiver android:name=".MusicService$NotificationReciever">
<intent-filter>
<action android:name="PREVIOUS"/>
<action android:name="PAUSE"/>
<action android:name="NEXT"/>
</intent-filter>
</receiver>
When I run my music play, notification does come up with buttons but they don't seem to fire the onReceive function?
What am I missing here?
Update:
Followed hasif sayed answer and I seem to found an error
java.lang.RuntimeException: Unable to instantiate receiver com.example.tilak.imusicplay.MusicService$NotificationReciev‌​er: java.lang.InstantiationException:java.lang.Class has no zero argument constructor
Googling about it, I found that I have to use a static class or I have to register/unregister in the parent class.
So this is what I did:
public void onCreate() {
super.onCreate();
//
LocalBroadcastManager.getInstance(this).registerReceiver(
new NotificationReciever(),new IntentFilter("PREVIOUS"));
LocalBroadcastManager.getInstance(this).registerReceiver(
new NotificationReciever(),new IntentFilter("PAUSE"));
LocalBroadcastManager.getInstance(this).registerReceiver(
new NotificationReciever(),new IntentFilter("NEXT"));
}
PendingIntent prevPendingIntent=PendingIntent.getBroadcast
(this,1,new Intent().setAction("PREVIOUS"),PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pausePendingIntent=PendingIntent.getBroadcast
(this,2,new Intent().setAction("PAUSE"),PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent nextPendingIntent=PendingIntent.getBroadcast
(this,3,new Intent().setAction("NEXT"),PendingIntent.FLAG_UPDATE_CURRENT);
Now I don't get this above error but onReceive is not working again.
Actually the reason why your broadcast reciever is not called when you click on pause,previous and next button is because ,you have set the pending intent to fire an acitivity,instead you have to set the pending intent to fire a boradcast
instead of this code snippet
PendingIntent nextPendingIntent=PendingIntent.getActivity
(this,3,new Intent().setAction("NEXT"),PendingIntent.FLAG_UPDATE_CURRENT);;
you have to correct it like this
PendingIntent nextPendingIntent=PendingIntent.getBroadcast
(this,3,new Intent().setAction("NEXT"),PendingIntent.FLAG_UPDATE_CURRENT);;
make corrections in all the three pending intent code which you have written
UPDATE
The reason why you still not receiving the broadcast in your Broadcast Receiver is because you are programitically registering your Receiver as LocalBroadCast
When using with PendingIntent, LocalBroadcast will not receive the Broadcast
so please remove this Line
LocalBroadcastManager.getInstance(this).registerReceiver(
new NotificationReciever(),new IntentFilter("PREVIOUS"));
LocalBroadcastManager.getInstance(this).registerReceiver(
new NotificationReciever(),new IntentFilter("PAUSE"));
LocalBroadcastManager.getInstance(this).registerReceiver(
new NotificationReciever(),new IntentFilter("NEXT"));
Instead, you only have to register the receiver in the Manifest.xml file
or
programitically you can register in code as
NotificationReciever mReciever = new NotificationReciever();
this.registerReceiver(
mReciever,new IntentFilter("PREVIOUS"));
this.registerReceiver(
mReciever,new IntentFilter("PAUSE"));
this.registerReceiver(
mReciever,new IntentFilter("NEXT"));
but if you register this programitically, make sure you unregister it while service is getting destroyed. Otherwise you may LEAK the BroadcastReceiver Object

Service containing BroadCastReceiver not functioning correctly

Please see edits before answering!
I have an app which contains a BackgroundService class:
public class BackgroundService extends Service {
#Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter();
filter.addAction("com.spotify.music.playbackstatechanged");
filter.addAction("com.spotify.music.metadatachanged");
filter.addAction("com.spotify.music.queuechanged");
registerReceiver(receiver, filter);
Log.e("Playing:", "APP IS PLAYING");
Notification notification = new Notification();
startForeground(1, notification);
}
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
long timeSentInMs = intent.getLongExtra("timeSent", 0L);
String action = intent.getAction();
if (action.equals(BroadcastTypes.METADATA_CHANGED)) {
String trackId = intent.getStringExtra("id");
String artistName = intent.getStringExtra("artist");
String albumName = intent.getStringExtra("album");
String trackName = intent.getStringExtra("track");
int trackLengthInSec = intent.getIntExtra("length", 0);
// Do something with extracted information...
} else if (action.equals(BroadcastTypes.PLAYBACK_STATE_CHANGED)) {
boolean playing = intent.getBooleanExtra("playing", false);
Log.e("Playing:","TRUE");
}
}
};
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
static final class BroadcastTypes {
static final String SPOTIFY_PACKAGE = "com.spotify.music";
static final String PLAYBACK_STATE_CHANGED = SPOTIFY_PACKAGE + ".playbackstatechanged";
static final String METADATA_CHANGED = SPOTIFY_PACKAGE + ".metadatachanged";
}
}
and this is declared in my manifest:
<service
android:name=".BackgroundService"
android:enabled="true" >
<intent-filter>
<action android:name="com.spotify.music.playbackstatechanged" />
<action android:name="com.spotify.music.metadatachanged" />
<action android:name="com.spotify.music.queuechanged" />
</intent-filter>
</service>
So essentially my objective is to have my BackgroundService initialized when my app is opened, and to have it continue to run in the Background doing whatever I need it to do. As of now, I am using logs to determine whether my "setup" is working, but when I run my app, I am unable to see an logs even after I tested all actions that should have triggered my BroadCastReceiver. Furthermore, my persistent notification should have changed had my service been running, but it does not...
Edit::
So, I added logs to my BackgroundService's onCreate() and onReceive() methods, however, neither seem to be appearing. Im wondering, do I need to do something in my launcher activity to initialize the service? Furthermore, no notification is shown so I assume the Service is not being started for some reason...
Latest Edit:
So I added the following code to my Main activity to see if it would make a difference:
startService(new Intent(this,BackgroundService.class));
And after debugging my app, I began to see the following error:
java.lang.RuntimeException: Unable to create service com.aurum.mutify.BackgroundService: java.lang.SecurityException: Isolated process not allowed to call registerReceiver
pointing to my BroadCast Receiver class.
Intent services are designed for short tasks. And your intent handling method is empty.
If you need long running task in the background use standard service and call start foreground. This will minimize chance of system destroying your service.
To learn more go here
EDIT
Try overriding onStartCommand method. this method is called when service is started and usually you do all stuff here. Remember that there are 3 options to return.
Edit 2:
try something like this
in on create
PendingIntent pi;
BroadcastReceiver br;
Intent myIntent;
#Override
public void onCreate()
{
super.onCreate();
myIntent = new Intent("something")
if(Build.Version.SDK_INT >= 16) //The flag we used here was only added at API 16
myIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
//use myIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); if you want to add more than one flag to this intent;
pi = PendingIntent.getBroadcast(context, 1, myIntent, 0);
br = new BroadcastReceiver ()
{
public void onReceive (Context context, Intent i) {
new thread(new Runnable()
{
public void run()
{
//do something
}
}).start();
}
};
And then in on start command
this.registerReceiver(br, new IntentFilter("something"));

Starting service in android to read message after fixed interval

I am able to read message of user when the application gets installed. But what I want is that even after the application is closed, I should be able to read user message after a fixed interval of time. For example, application like Walnut that reads specific message and gives alerts automatically if any new message has come. How can I do the same.
Use Alarm manager and Pending Intent
Initiate Alarm manager here.
AlarmManager alarmMgr = (AlarmManager) this
.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
new Intent(this, AlarmReceiver_update.class),
PendingIntent.FLAG_CANCEL_CURRENT);
alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
0, yourTimeInterval, pendingIntent);
And in AlarmReceiver_update class:
public class AlarmReceiver_update extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
// Do whatever you want
}
}
And in Your AndroidManifest file register your receiver:
<receiver android:name="com.x.y.AlarmReceiver_update" >
<intent-filter>
<action android:name="android.test.BROADCAST" />
</intent-filter>
</receiver>
This is not complete just sample you have any doubt just comment.
You shuold use an alarm manager to set a repeating alarm.
Then you should setup a BroadcastReceiver Service that read the user messages onRecieve.
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Run the task to read the user messages
}
}
This is a good tutorial
Have a look at the below links to learn how to notify the user if you found new message.
http://javatechig.com/android/repeat-alarm-example-in-android#3-defining-alarm-broadcastreceiver
http://developer.android.com/training/notify-user/build-notification.html

Running background service through shortcut

So I want to launch a service from a shortcut. I know that this is not possible to do directly, so I've set up a activity with the sole purpose of starting the service.
The aim of my service is to send an intent to another app and then 5 seconds later send another so I've used a CountDownTimer to do this.
However, when I launch the Activity that starts the service from the shortcut (this is getting confusing) it launches the apps UI. I don't want this, as I want it to be a background service.
What am I doing wrong. I've only just got into development, so it could be something obvious, but I've been battling with this for a few days now.
For some reason when I run it from the service it just launches the app straight away...
When I run it straight from the invisible activity it runs properly for the 1st 5 seconds fine and then loads the app...
I can't figure out why it's loading the app at all.
I've included as much info as I can that would be relevant.
Any help is appreciated!
My service:
public class Pop1_5Service extends IntentService {
public Pop1_5Service() {
super("Pop1_5Service");
}
#Override
protected void onHandleIntent(Intent intent) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
new CountDownTimer(5000, 2500) {
public void onTick(long millisUntilFinished) {
Intent i = new Intent(INTENT_ACTION);
Bundle b = new Bundle();
b.putInt(BUNDLE_VERSION_CODE, 1);
b.putString(BUNDLE_STRING_NAME, "POP1");
b.putString(BUNDLE_STRING_VALUE, "1");
i.putExtra(BUNDLE_NAME, b);
sendBroadcast(i); }
public void onFinish() {
Intent i = new Intent(INTENT_ACTION);
Bundle b = new Bundle();
b.putInt(BUNDLE_VERSION_CODE, 1);
b.putString(BUNDLE_STRING_NAME, "POP1");
b.putString(BUNDLE_STRING_VALUE, "1");
i.putExtra(BUNDLE_NAME, b);
sendBroadcast(i); }
}
}.start();
}
}
Activity that launches service:
public class Pop1_5Activity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, Pop1_5Service.class);
startService(intent);
finish();
}
}
Subsection of Manifest:
<activity
android:name=".Pop1_5Activity"
android:theme="#android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".Pop1_5Service" />
And the 'Create a Shortcut' Activity:
public class CreateShortcutActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent shortcutintent = new Intent(this, Pop1_5Activity.class);
ShortcutIconResource iconResource = Intent.ShortcutIconResource.fromContext(this, R.drawable.ic_launcher);
Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutintent);
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "Pop1_5");
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource);
setResult(RESULT_OK, intent);
finish();
}
}
From the look of things, it looks like CreateShortcutActivity does nothing.
Your LAUNCHER is Pop1_5Activity, so when the user presses the app icon, this Activity will run, and it launches the Service.
All the code you have showed us are "invisible", the two Activities finish() themselves, and the Service is a Service.
You might want to look at how your BroadcastReceiver handles your broadcast. For instance, does it create another Activity through PendingIntent? Is the Activity created invisible?
Maybe you should try creating a pending Service instead of pending Activity in the BroadcastReceiver.

Categories

Resources