Pushes not received after the app is closed - java

Before labeling this as a duplicate:
I've read at least 15 similar threads and each and every one is either using the old Parse code (the now deprecated setDefaultPushCallback) or the problem was a result of calling Parse.initialize(...) in an activity and not in the Application class. But this is not applicable to my case. The official example (which I'm using) is evidently doing it right, so the code is already in the Application class.
I've downloaded the Push Starter example from Parse's official guides and tried it out on an emulator. I receive pushes only while the app is running. The moment's it's closed (removed from the "recent apps" list, not force killed), I no longer get pushes. Which makes the entire feature rather useless... I tried with and without GCM, the behavior is the same.
Any clues what could possible be wrong? All classes are the stock example ones, nothing overridden or added by me (except for the id/key and the ParsePush.subscribeInBackground call which I copied from the guide). Weirdly enough, the example code did not contain ParsePush.subscribeInBackground and the QuickStart does not mention it. It even gives a Test button that supposedly sends a push which I never receive, with or without subscribeInBackground. The only way I've been able to get a push so far was with subscribeInBackground and sending a push manually though the web console, and only so if the app is running. The web console also keeps telling there's 2 registered devices... which is untrue.
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.parse.starter"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="21"/>
<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 "com.parse.starter.permission.C2D_MESSAGE" in the lines below
to match your app's package name + ".permission.C2D_MESSAGE".
-->
<permission android:protectionLevel="signature"
android:name="com.parse.starter.permission.C2D_MESSAGE" />
<uses-permission android:name="com.parse.starter.permission.C2D_MESSAGE" />
<application
android:name=".ParseApplication"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:allowBackup="true">
<activity
android:name=".ParseStarterProjectActivity"
android:label="#string/app_name" >
<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="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" />
<!--
IMPORTANT: Change "com.parse.starter" to match your app's package name.
-->
<category android:name="com.parse.starter" />
</intent-filter>
</receiver>
</application>
</manifest>
ParseApplication:
package com.parse.starter;
...
public class ParseApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
// Initialize Crash Reporting.
ParseCrashReporting.enable(this);
// Enable Local Datastore.
Parse.enableLocalDatastore(this);
ParseUser.enableAutomaticUser();
// Add your initialization code here
Parse.initialize(this, "***", "***");
ParseACL defaultACL = new ParseACL();
// Optionally enable public read access.
// defaultACL.setPublicReadAccess(true);
ParseACL.setDefaultACL(defaultACL, true);
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);
}
}
});
}
}

Just to clarify why you are seeing this behaviour, Parse has two different ways for delivering push notifications:
"Parse way": the Parse SDK has a component running in your app, which keeps a connection to the Parse backend servers. This will only work when your app is actually running, because killing it breaks the connection with the Parse backend.
GCM "Google" push notifications: This works via Google Play Services, an app which is always running in the background and that can start your app when needed. This will always work, unless you force stop the application.
In your case you are there is a package name conflict: com.parse.starter is the package name that was actually included in the example. This causes GCM not to work, because it already knows the package under a different signature. Changing your package name to something unique like com.parse.kaqqao should solve the trick.

There are a few reasons for this:
There are two BroadcastReceiver viz the "com.parse.ParsePushBroadcastReceiver" and "com.parse.GcmBroadcastReceiver". I believe that the first receiver is getting prioritized over the GCMBroadcastReceiver and thus the behavior is not affected by removing or keeping this receiver. It could also be due to action "com.parse.push.intent.RECEIVE", which might be handling the push messages RECEIVE action. If both the receiver perform the same task of parsing the Push message (starting the same service in background), then include the intent-filter inside one receiver and let it handle all kinds of push messages. Since GCMBroadcastReceiver holds the C2DM permission.
Try changing the order of the two broadcast receiver tags in the manifest. (Keep GCMBroadcastReceiver before the ParsePushBroadcastReceiver)
It could be due to android:exported="false", maybe it prevents the Receiver from listening to the push messages sent by server. Try changing to true.

Related

How to add the <queries> tag in the manifest?

I have this code and I was told that for Android 11 I need to add the queries tag in manifest:
final PackageManager pm = getPackageManager();
Intent main = new Intent(Intent.ACTION_MAIN, null);
main.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> packages = pm.queryIntentActivities(main, 0); //get a list of installed apps.
I was told it should be this:
<queries>
<intent>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent>
</queries>
Problem is I cannot add the <category> tag. Android Studio says that the element is not allowed there. I can only add the <action> and <data> tags inside <intent>. And it seems other people on SO have this problem too. It's strange because Android's own documentation instructs us to use the <category> tag there.
The <queries> section is introduced in API 30, so be sure you use it only if you target such version upward.
It is indeed needed when, for instance, you want to launch some other apps from yours, knowing only their package name. Otherwise, using the package manager will return you some null when using functions like packageManager.getLaunchIntentForPackage("com.yyy"). You can find more information here: Package visibility in Android 11
In your case, you can just write the section like this:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xxx">
...
<queries>
<intent>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent>
</queries>
...
</manifest>

Strange behavior related to FusedLocationApi.requestLocationUpdates()

I'm writing a Android app and there's a strange behavior related to FusedLocationApi.requestLocationUpdates() that I've searched on SO and none of the other related questions solved my problem.
Apparently the requestLocationUpdates do not trigger the onLocationChanged() method all the times; I'm saying this because I'm cleaning my app's data on emulator for each run and sometimes the onLocationChanged() is triggered, sometimes not (most of under some conditions like run the app for the second time w/o cleaning the app's data or after making a user data's wipe i.e)
Below you can find my code (links from pastebin, I don't want to create any visual overload here)
Main Activity: http://pastebin.com/XiRrcR11
MapHandler: http://pastebin.com/HELnhaxy
Another problem is, oddly enough, if I use a anonymous inner class in the MapHandler in the method displayLocation(), the app works, but if I use a external class who extends LocationListener the app do not behave correctly
I know the expected question levels in SO are high but I'm starting my studies about Android development and this issue is taking my sleep away
Btw here is my AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.trackit.app.track_it_v002">
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the 'MyLocation' functionality.
-->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<!--
The API key for Google Maps-based APIs is defined as a string resource.
(See the file "res/values/google_maps_api.xml").
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name=".MapsActivity"
android:label="#string/title_activity_maps">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Can you guys give me a hand here?
EDIT: after some debugging I've seen the requestLocationUpdates is not returning a non null object and not triggering onLocationChanged(), anyone have a idea why? =S
I encountered this issue. The mGoogleApiClient object, which needs to be connected at the time of requestLocationUpdates. This was resolved by requestingLocationUpdates from onConnected callback.
/*
* Called first time google client is connected
*/
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.v(LOG_TAG,"DetectDrivingService - onConnected");
// Create
try {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
catch(SecurityException se){
}
}

Permission Denial With Broadcast Receiver

I am trying to create an app which enters a log message when I make an outgoing call.
However, when I run the code, I get a permission denial, despite the fact that I have entered in the permissions.
Denial Log:
"09-04 02:35:50.535 1294-1666/? W/BroadcastQueue﹕ Permission Denial: receiving Intent { act=android.intent.action.NEW_OUTGOING_CALL flg=0x10000010 (has extras) } to samples.varma.packagecom.testreceive2/.CallReceiver requires android.permission.PROCESS_OUTGOING_CALLS due to sender android (uid 1000)"
Manifest Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="samples.varma.packagecom.testreceive2" >
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:enabled="true"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".CallReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
</application>
</manifest>
And here is the code for my receiver:
package samples.varma.packagecom.testreceive2;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.util.Log;
public class CallReceiver extends BroadcastReceiver {
public CallReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (state == null) {
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Log.i("TAG", "Outgoing Number: " + number);
} else if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Log.i("TAG", "Incoming Number: " + number);
}
}
}
I am very new to this so there is a good chance that there are several errors or I am completely off base. Regardless I would greatly appreciate any guidance. Would anyone know why I am getting this denial?
Thanks
Edit:
It is also giving me these permission denials even though I have added the phone state permission.
The privileged phone-state permission is a system permission so I cannot add.
09-04 04:36:03.249 1294-1440/? W/BroadcastQueue﹕ Permission Denial: receiving Intent { act=android.intent.action.PHONE_STATE flg=0x10 (has extras) } to samples.varma.packagecom.testreceive2/.CallReceiver requires android.permission.READ_PRIVILEGED_PHONE_STATE due to sender android (uid 1000)
09-04 04:36:03.271 1294-1308/? W/BroadcastQueue﹕ Permission Denial: receiving Intent { act=android.intent.action.PHONE_STATE flg=0x10 (has extras) } to samples.varma.packagecom.testreceive2/.CallReceiver requires android.permission.READ_PHONE_STATE due to sender android (uid 1000)
1294-1308/? W/BroadcastQueue﹕ Permission Denial: receiving Intent { act=android.intent.action.PHONE_STATE flg=0x10 (has extras) } to samples.varma.packagecom.testreceive2/.CallReceiver requires android.permission.READ_PHONE_STATE due to sender android (uid 1000)
I have launched the same application on Android emulator and nothing helped, even
android:enabled="true"
android:exported="true"
The solution was to go to Settings->Apps -> MyApplication -> Permissions -> Toggle Phone Permission on.
Android Phone Permission for Application
I got it to work by following this link closely Intercepting outgoing call - what am I missing? (thanks ajit)
I ended up taking off the PHONE_STATE permission, adding android:enabled="true" and android:exported="true" to my receiver in the manifest, relocating the NEW_OUTGOING_CALL permission to below application(not sure if this is necessary), taking away the intended sdk versions and basically copying the receiver from the link.
Updated manifest code from receiver tag to manifest tag is:
<receiver
android:name=".testreceive3"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>-->
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />>-->
</manifest>
U need to apply the runtime permission int your code when your code running on Android 6.0 or above.
You should add the following thing in your Manifest receiver
<service android:name=".CallReceiver"
android:enabled="true"
android:exported="false" >
</service>
Use permission CALL_PHONE instead of OUTGOING
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Best solution is when you run the code activate usb debugging, make sure you select disable permissions monitor settings in developer settings ! App wont be asked for permissions by the OS anymore. Happy helping :)
This will work without changing anything in manifest!

Go back to launcher android programmatically

I use the following code to set my app as the default program. Press the home key to go to my app...
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.HOME" />
It also boots with DISABLE_KEYGUARD directly into my app, without needing to unlock the phone.
How can I change back to the default launcher programmatically? Meaning, how can I go back to android home screen?
I tried using System.exit(0) however it doesn't work - it just goes back to my app instead of the android home screen.
The following is my code.
It goes back to my APP automatically.
Please tell any problem in the code.
TesthomeActivity.java
public class TesthomeActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btn = (Button)findViewById(R.id.button1);
btn.setOnTouchListener(exitappTouchListener);
}
OnTouchListener exitappTouchListener= new OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent arg1) {
// TODO Auto-generated method stub
if(arg1.getAction() == MotionEvent.ACTION_DOWN){
}
if(arg1.getAction() == MotionEvent.ACTION_UP ){
Intent i = new Intent();
i.setAction(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_HOME);
TesthomeActivity.this.startActivity(i);
finish();
System.exit(0);
}
return false;
}
};
}
StartupReceiver.java
public class StartupReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent)
{
Intent activityIntent = new Intent(context, TesthomeActivity.class);
activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(activityIntent);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.inno.testhome"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="10" />
<application android:icon="#drawable/icon" android:label="#string/app_name" android:theme="#android:style/Theme.Black.NoTitleBar.Fullscreen">
<activity android:name=".TesthomeActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</activity>
<receiver android:name="StartupReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
read this Is quitting an application frowned upon?
or use this
Intent i = new Intent();
i.setAction(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_HOME);
yourActivity.this.startActivity(i);
finish();
I think this will help you
If your app is set as the default launcher, the Android system will automatically restart your app whenever it quits. It no longer has any concept of the original home screen - as far as the operating system is concerned, your app is the home screen now.
This is why you are unable to get back to the default launcher by quitting your app.
The only way to achieve the result you want is to change the default launcher.
You need to query the PackageManager for the apps that respond to the Home intent.
You can then launch the correct one as you would start any other activity. Be sure to remove your app from the list before processing...
For useful info on that, I suggest #Commonsware's Launchalot sample app, which shows how to enumerate a list of apps that respond to a certain intent.
Check his code on github here.

AndroidManifest.xml errors

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android">
<application android:icon="#drawable/ic_launcher" android:label="#string/app_name">
<activity android:name=".hba1c" android:label="#string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
I'm trying to learn Java and need some help with AndroidManifest.xml
My little hello world project is working code-wise, but I'm confused with making changes to the manifest. Specifically, in the code above package name is "com.android" and in data/app my app shows up as com.android-1.apk. When I try to change it to something like com.jocala or com.jocala.hba1c I get package R does not exist errors through my compile, which fails.
What changes do I need to make? Anything else here that is glaringly bad?
I am working using Ant, VI and the Linux console, no Eclipse.
You should change the package of the java code, let it in accordance with the package which you defined in the manifest file.
The manifest holds meta-data corresponding to your android application. Hence, if you needs changes in the package name, make the changes in the java files, change the package name there, there is no sense making a change here. The only changes that are majorly done in the manifest are activity related(for beginners). Have a read here.

Categories