Parse push targeted notification - java

I'm trying to send a targeted notification via parse but it doesn't work. I use this code to receive
ParseInstallation installation = ParseInstallation.getCurrentInstallation();
// set the current user id
installation.put("device_id", id.getText().toString());
installation.saveInBackground();
and this one to send
ParseQuery query = ParseInstallation.getQuery();
// id is EditText to write the id of the targeted user manually
query.whereEqualTo("device_id", id.getText().toString());
ParsePush push = new ParsePush();
push.sendMessageInBackground("Hello", query);
I've also tried
push.setQuery(query);
push.setMessage("Hello");
push.sendInBackground();
the manifest has everything that parse said in its quickstart.
Permissions:
<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.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:protectionLevel="signature"
android:name="com.test.singleuserpush.permission.C2D_MESSAGE" />
<uses-permission android:name="com.test.singleuserpush.permission.C2D_MESSAGE" />
Services and Receivers
<service android:name="com.parse.PushService" />
<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="com.test.singleuserpush" />
</intent-filter>
</receiver>
None of those worked, any suggestions?

try this with push.setData instead of message
JSONObject data;
data = new JSONObject("{\"userName\": "+
"\""+"MyUserName"+"\""+
",\"profilePic\": "+
"\""+""+"\"}");
Log.e("Uber User customdata", data.toString());
JSONObject obj =new JSONObject();
obj.put("alert","New Alert Message");
obj.put("action","com.android.myappname");
obj.put("customdata",data); //send json
ParsePush push = new ParsePush();
push.setQuery(query);
push.setData(obj);
push.sendInBackground();

I solved the problem by enabling client push in App settings, push, enable client push.

Related

OnActivityResult always returns RESULT CANCELED (Code: 0) on Android 11

Sadly, Android 11 storage restrictions are too hard and confusing.
I'm trying to pick a document using the below code
fun onFile(activity: AppCompatActivity?, fragmentContext: Fragment?, isMultiple: Boolean?, pFileMimeTypes: Array<String>?): Intent {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
action = Intent.ACTION_OPEN_DOCUMENT
addCategory(Intent.CATEGORY_OPENABLE)
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, isMultiple ?: false)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
}
val fileMimeTypes = pFileMimeTypes ?: FileUtil.mimeTypes
intent.type = if (fileMimeTypes.size == 1) fileMimeTypes[0] else "*/*"
if (!fileMimeTypes.isNullOrEmpty()) {
intent.putExtra(Intent.EXTRA_MIME_TYPES, fileMimeTypes)
}
val list = activity?.packageManager?.queryIntentActivities(intent, PackageManager.MATCH_ALL)
if (list?.size!! > 0) {
if (fragmentContext == null) {
activity.startActivityForResult(
Intent.createChooser(
intent,
activity.getString(R.string.m_selectFile_txt)
), FILE_CODE
)
} else {
fragmentContext.startActivityForResult(
Intent.createChooser(
intent,
activity.getString(R.string.m_selectFile_txt)
), FILE_CODE
)
}
}
// returning intent is not being used anywhere else
return intent
}
Although I have all files access permission Environment.isExternalStorageManager() but still after selecting document(PDF) from the external storage (download or any folder), OnActvityResult is being called with result code 0. I need the Uri of the selected document to proceed further.
For any other reference, below is my manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="*****Hidden*******">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.READ_STORAGE_PERMISSION"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.CAMERA" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:requestLegacyExternalStorage="true"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:exported="true"
android:name=".Main2Activity"
android:launchMode="singleTask"
android:label="#string/title_activity_main2"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:theme="#style/AppTheme.NoActionBar">
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.attachmentmanager"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_provider"
tools:replace="android:resource" />
</provider>
</application>
<queries>
<intent>
<action android:name="android.intent.action.OPEN_DOCUMENT" />
<!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". -->
<data android:mimeType="*/*" />
</intent>
<intent>
<action android:name="android.intent.action.PICK" />
<!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". -->
<data android:mimeType="*/*" />
</intent>
</queries>
</manifest>
I must be missing some point. Everything is working fine below Android 11
Thanks in Advance.
startActivityForResult is deprecated
Refer this link
Use Activity Results API
Official Docs

Restart service on device reboot

I have a program with a service and if I reboot my device also the service should Restart. But this only works on the Emulator if I try this on my real device the service doesn't start at all.
Does someone know what I'm doing wrong or why it only works on Emulator?
BroadcastReviever:
#Override
public void onReceive(Context context, Intent intent) {
//we double check here for only boot complete event
if(intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED))
{
//here we start the service
Intent serviceIntent = new Intent(context, UploadService.class);
context.startService(serviceIntent);
}
}
Manifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.GET_ACCOUNTS_PRIVILEGED"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.READ_OWNER_DATA" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
<uses-permission android:name="android.permission.READ_OWNER_DATA" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="Upload FTP"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<receiver
android:name=".BootCompletedIntentReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<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=".UploadService"
android:isolatedProcess="false"
android:exported="true"
android:enabled="true"/>
</application>
The emulator is at API 23 and real device is API 27.
I'm Building for a min API Level 23 and max API Level 27
EDIT
Now I have also tried the program with a emulator and android API 27 and there when I start my program and then I restart the emulator, the emulator doesn't start any more. As soon as the emulaor has started he begins to reboot again and that in a endless loop. (Real device starts normal just doesn't restarts service)
try to use LOCKED_BOOT_COMPLETED receiver as follow:
<receiver
android:name=".BootReceiver"
android:directBootAware="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED"/>
<!-- For pre-N devices -->
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
don't forget permission
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
take a look here for more explanation
Now I fixed in on my own it was easier then i thought
public class BootCompletedIntentReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i=new Intent(context, YourClass.class);
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.O) {
context.startForegroundService(i);
}
else {
context.startService(i);
}
}
I had some weird experience if I don't put full URI,
for example .BootCompletedIntentReceiver would become com.company.BootCompletedIntentRecevier.
I know it sounds dumb but I had many weird regressions when not explicitly stating things on the Manifest with modern SDKs.

GCM 8.4.0 Connetion Failed due to Permission on Android 6

I want to add GCM to my application and register user device but I have weird problem:
W/GMPM: Service connection failed: ConnectionResult{statusCode=SERVICE_MISSING_PERMISSION, resolution=PendingIntent{c28038b: android.os.BinderProxy#6a00c68}, message=null}
The device can't register and I can't get the register token. How can I fix this?
My manifest file permissions:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.GET_ACCOUNTS"></uses-permission>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="ir.makbn.mashfood.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="ir.makbn.mashfood.permission.C2D_MESSAGE"/>
and my receiver class definition:
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
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="ir.makbn.mashfood.gcm" />
</intent-filter>
</receiver>
<service
android:name=".service.MyGcmListener"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service
android:name=".service.MyInstanceIDListener"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
All my receivers classes are same as in the Google GCM example and I use GCM 8.4.0.
In my shared preferences I found com.google.android.gcm.measurement.prefs that contains:
...name="health_monitor_value">1wc8487:service connection faild: _ ...
Based on the Official Google Documentation the error code used by GoogleApiClient.OnConnectionFailedListener.
Google Play Service doesn't have one or more required permissions. The client may call 'startResolutionForResult(Activity, int)' to prompt the user to fix the issue. After activity returns with 'RESULT_OK' further attempts to connect should succeed.
A Google Cloud Messaging (GCM) Android client is a client app that runs on an Android device. We recommend that you use the GoogleCloudMessaging API and Android Studio with Gradle.
There are requirements for running a GCM Android client, GCM implementation requires both client implementation and server implementation. For more details about GCM android client, check this: https://developers.google.com/cloud-messaging/android/start

Parse sending notifications in dashboard but Android device not receiving

I've successfully created a Parse app and I'm using the application keys in my Android app implementation. I've followed all the steps here https://www.parse.com/apps/quickstart?onboard=#parse_push/android/existing (registration required unfortunately, but it's an instant process) and when I send a test push notification it is dispatched from the dashboard and is even received by a virtual device I'd set up as a control but nothing happens on a physical device. I thought it might be a socket issue so I alternated between wifi and 3G connections with no success
Here's the code I'm using:
Main:
package com.wetu.chronicle;
import android.os.Bundle;
import org.apache.cordova.*;
import com.parse.Parse;
import com.parse.ParseAnalytics;
import com.parse.ParseInstallation;
import com.parse.PushService;
public class chronicle extends DroidGap
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
super.loadUrl(Config.getStartUrl());
Parse.initialize(this, "xxxxxxxxx", "yyyyyyyyyyyy");
PushService.setDefaultPushCallback(this, chronicle.class);
PushService.subscribe(this, "Newsfeed", chronicle.class);
ParseInstallation.getCurrentInstallation().saveInBackground();
}
}
Android Manifest:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<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" />
<!--
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.wetu.chronicle.permission.C2D_MESSAGE" />
<uses-permission android:name="com.wetu.chronicle.permission.C2D_MESSAGE" />
<application
android:debuggable="false"
android:hardwareAccelerated="true"
android:icon="#drawable/icon"
android:label="#string/app_name" tools:ignore="HardcodedDebugMode">
<activity android:name="chronicle" android:label="#string/app_name"
android:theme="#android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale">
<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.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.wetu.chronicle" />
</intent-filter>
</receiver>
</application>
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="19"/>
I'm available to clarify any questions you might have and/or post additional code.
Its most likely because your app isn't active in the background. A lot of my android apps have been struggling from this. A decent solution might be to make sure there is an alarm clock that wakes the app up. I've never dealt with parse though so this may not work, its worked for me in other scenarios though

GCM SERVICE_NOT_AVAILABLE error

I'm using GCM in my android application and when I try to register the device with GCM (with the command gcm.register(SENDER_ID)) I get the SEVICE_NOT_AVAILABLE error, I tried what someone suggested here (the accepted solution) and I did get the registration id.
Why is it like that?
Android manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.appspot.smartgan"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission
android:name="com.appspot.smartgan.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.appspot.smartgan.permission.C2D_MESSAGE" />
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/Theme.AppCompat.Light" >
<activity
android:name="com.appspot.smartgan.MainActivity"
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=".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.appspot.smartgan" />
</intent-filter>
</receiver>
<service
android:name=".GcmIntentService"
android:enabled="true" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name="com.appspot.smartgan.LoginActivity"
android:label="#string/title_activity_login"
android:windowSoftInputMode="adjustResize|stateVisible" >
</activity>
<activity
android:name="com.appspot.smartgan.ChildActivity"
android:label="#string/title_activity_child" >
</activity>
</application>
</manifest>
register method:
private void registerInBackground() {
new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
String message = "";
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(context);
}
regid = gcm.register(SENDER_ID);
message = "Device registered, registration ID=" + regid;
Log.d("SMARTGAN_PLAY", "register completed");
// send registration id to the server
sendRegistrationIdToServer();
// Persist the regID - no need to register again.
storeRegistrationId(context, regid);
} catch (IOException e) {
message = "Error:" + e.getMessage();
}
return message;
}
}.execute(null, null, null);
}
I think issue is regarding allowed IP addresses mentioned in your Google API project.
Please check details of the project and remove IP address if present under restrict use to IP address. I faced similar problem.
If you are receiving a Register ID it means you have registered the device successfully to the GCM.
Edit:
Here is a good tutorial for GCM: http://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/
<receiver
android:name="rockit.app.beardallstreetprimary.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="rockit.app.beardallstreetprimary" />
</intent-filter>
</receiver>
<service android:name="com.google.android.gcm.GCMIntentService" android:enabled="true" />
My GCM is set up based on the Tutorial i linked above so if you read through that aswell it should work for you it looks like your not far off. I will say the Manifest is very picky and you need to ensure that you link your Packages fully.
Also you dont need the Register Intent

Categories

Resources