I'm trying to invoke the samsung knox SDK to access the TIMA keystore.
However, the device throws the following exception:
Caused by: java.lang.SecurityException: uid 10207 does not have com.samsung.android.knox.permission.KNOX_TIMA_KEYSTORE.
at android.os.Parcel.createException(Parcel.java:1966)
at android.os.Parcel.readException(Parcel.java:1934)
at android.os.Parcel.readException(Parcel.java:1884)
at com.samsung.android.knox.keystore.ITimaKeystore$Stub$Proxy.enableTimaKeystore(ITimaKeystore.java:253)
at com.samsung.android.knox.keystore.TimaKeystore.enableTimaKeystore(TimaKeystore.java:123)
at com.samsung.knox.example.knoxsdk.MainActivity.enableKeystore(MainActivity.java:163)
at com.samsung.knox.example.knoxsdk.MainActivity.onRequestPermissionsResult(MainActivity.java:157)
at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:7957)
at android.app.Activity.dispatchActivityResult(Activity.java:7779)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4615)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4664)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1960)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7094)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
What do I need to do to make it work?
I am working on a Samsung SM-A705FN and it does have knox on it
Sample code
private void enableTimaKeystore() {
activateLicense();
int checkKeystore = getApplicationContext().checkCallingOrSelfPermission(KNOX_KEYSTORE_PERMISSION);
int checkKeystorePerApp = getApplicationContext().checkCallingOrSelfPermission(KNOX_KEYSTORE_PERMISSION_PER_APP);
if (checkKeystore == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(), KNOX_KEYSTORE_PERMISSION + " is granted", Toast.LENGTH_LONG).show();
enableKeystore();
} else if (checkKeystorePerApp == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(), KNOX_KEYSTORE_PERMISSION_PER_APP + " is granted", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), KNOX_KEYSTORE_PERMISSION + " and " + KNOX_KEYSTORE_PERMISSION_PER_APP + " are not granted. You can't use TimaKeystorePerApp ", Toast.LENGTH_LONG).show();
requestPermissions(new String[]{KNOX_KEYSTORE_PERMISSION}, 100);
}
}
private void activateLicense() {
// Instantiate the EnterpriseLicenseManager class to use the activateLicense method
KnoxEnterpriseLicenseManager klmManager = KnoxEnterpriseLicenseManager.getInstance(this.getApplicationContext());
try {
// KPE License Activation TODO Add license key to Constants.java
klmManager.activateLicense(Constants.KPE_LICENSE_KEY);
mUtils.log(getResources().getString(R.string.activate_license_progress));
} catch (Exception e) {
mUtils.processException(e, TAG);
}
}
private void enableKeystore() {
/* get CCM Policy */
TimaKeystore mTimaKeyStorePolicyHandler = EnterpriseKnoxManager.getInstance(this).getTimaKeystorePolicy();
mTimaKeyStorePolicyHandler.enableTimaKeystore(true);
/* To enable TimaKeystore for all the apps on the device (both inside and outside container). */
boolean isEnabled = mTimaKeyStorePolicyHandler.isTimaKeystoreEnabled();
mUtils.log("is keystore enabled: " + isEnabled);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
enableKeystore();
}
And the manifest file
<?xml version="1.0" encoding="utf-8"?>
<!-- Permissions TODO List permissions used by application -->
<uses-permission android:name="com.samsung.android.knox.permission.KNOX_HW_CONTROL" />
<uses-permission android:name="com.samsung.android.knox.permission.KNOX_TIMA_KEYSTORE" />
<uses-permission android:name="com.samsung.android.knox.permission.KNOX_KEYSTORE_PER_APP" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name="com.samsung.knox.example.knoxsdk.MainActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- SampleAdminReceiver TODO Provide receiver for device admin receiver class -->
<receiver
android:name="com.samsung.knox.example.knoxsdk.SampleAdminReceiver"
android:description="#string/enterprise_device_admin_description"
android:label="#string/enterprise_device_admin"
android:permission="android.permission.BIND_DEVICE_ADMIN" >
<meta-data
android:name="android.app.device_admin"
android:resource="#xml/device_admin_receiver" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
<!-- Activate License TODO Provide receiver for Knox license activation results -->
<receiver android:name="com.samsung.knox.example.knoxsdk.SampleLicenseReceiver" >
<intent-filter>
<action android:name="com.samsung.android.knox.intent.action.KNOX_LICENSE_STATUS" />
</intent-filter>
</receiver>
</application>
Who would have thought that a public forum was the best place for questions like this. Maybe should listen to some John Lennon. Or a specific beatle
Related
I have registered "SMS received event" for the broadcast receiver but when i launch the app and send message to the emulator i do not see onReceive method of broadcast receiver getting triggered.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dev.code">
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<receiver android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="500">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</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>
</application>
</manifest>
MyReceiver.java
public class MyReceiver extends BroadcastReceiver {
private static final String TAG =
MyReceiver.class.getSimpleName();
#Override
public void onReceive(Context context, Intent intent) {
// Get the SMS message.
Log.v(TAG,"Message Received");
}
I think you need to check permission in code for SDK more or equal to M(Marshmallow) -
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission. RECEIVE_SMS) == PackageManager.PERMISSION_GRANTED) {
// you can receive sms
}
else
{
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission. RECEIVE_SMS}, 411);
}
}
else
{
// you can receive sms
}
}
And on result of user action-
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 411) {
if (grantResults.length == 0 || grantResults == null) {
// show dialog that you need access to go ahead
} else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Your code here permission granted
} else if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
// show dialog that you need access to go ahead
}
}
}
The android.permission.RECEIVE_SMS permission is a dangerous permission.
You should use ActivityCompat.requestPermissions to request it.
<permission android:name="android.permission.RECEIVE_SMS"
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="#string/permlab_receiveSms"
android:description="#string/permdesc_receiveSms"
android:permissionFlags="hardRestricted"
android:protectionLevel="dangerous" />
I want to ask users to agree with the disclaimer that I have provided in my application, and then if they agreed, next time they are using the app, we just re-show them the disclaimer for a few seconds without asking to click on anything and redirect them to the application. The best way I could have come up with it was, using a custom permission and however I did add permission commands to my manifest I could not figure out how to actually activate the permission in my code:
import java.util.jar.Manifest;
public class Language extends Activity {
Button engBut, fraBut;
// public static int j;
public void click (View view){
// j=1;
Intent intent = new Intent(getApplicationContext(),MainActivity.class);
startActivity(intent);
}
public void fraClick (View view){
// j=2;
Intent intent = new Intent(getApplicationContext(),MainActivity.class);
startActivity(intent);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_language);
ImageView logo = (ImageView) findViewById(R.id.logo);
ImageView montfortLogo = (ImageView) findViewById(R.id.montfortLogo);
montfortLogo.setImageResource(R.drawable.k);
logo.setImageResource(R.drawable.j);
engBut = (Button) findViewById(R.id.engBut);
engBut.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(Language.this);
builder.setCancelable(true);
builder.setTitle("DISCLAIMER");
builder.setMessage(R.string.result_disclaimer);
builder.setNegativeButton("Get me out of here.", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
builder.setPositiveButton("I agree.", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(getApplicationContext(),MainActivity.class);
intent.setAction("com.techideas4you.pharamacy.MyAction");
intent.addCategory("android.intent.category.DEFAULT");
startActivity(intent);
}
});
builder.show();
}
});
fraBut = (Button) findViewById(R.id.fraBut);
Log.i("Locale", String.valueOf(Locale.getDefault()));
}
}
This was my first page code.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="example.ex"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19" />
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE" />
<permission android:name="testDisclaimer" android:label="DISCLAIMER"
android:description="#string/result_disclaimer"/>
<uses-permission android:name="testDisclaimer"/>
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="#drawable/icon"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name=".MainActivity"
android:label="#string/app_name">
</activity>
<activity
android:name=".ActivityQuestion"
android:icon="#drawable/home"
android:label="Home"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
<activity
android:name=".ActivityResult"
android:icon="#drawable/home"
android:label="Home"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
<activity android:name=".Language">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter >
<action android:name="com.techideas4you.pharamacy.MyAction"
/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
and this is my manifest if anybody could help me out here I really appreciate it.
You have to add android:protectionLevel="dangerous" to the declaration of your permission else it will be granted automatically and users will not be presented with a dialog although you call requestPermission().
<permission android:name="your.package.name.permission.testDisclaimer" android:label="DISCLAIMER"
android:description="#string/result_disclaimer"
android:protectionLevel="dangerous"/>
<uses-permission android:name="your.package.name.permission.testDisclaimer"/>
In order to have the runtime show the disclaimer, you have to call
requestPermissions(new String[]{"your.package.name.permission.testDisclaimer"}, 42);
The result (whether user agreed) will be transmitted to you in onRequestPermissionsResult()
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults)
{
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 42 && grantResults != null){
Toast.makeText(this, "Permission " + permissions[0] + (grantResults[0] == PERMISSION_GRANTED ? "" : " NOT ") + " granted! ", Toast.LENGTH_LONG).show();
}
}
Please note that by using the permission system, you also have to cope with the fact that users will NOT be shown the permission-request-disguised-as-disclaimer if they
[...] turned down the permission request in the past and chose the
Don't ask again option in the permission request system dialog [...]
(quoted from documentation).
So maybe simply writing a flag to SharedPreferences will do the job just as well.
I am using the below code to obtain the location of a user
public class MainLocation extends Application implements LocationListener {
protected LocationManager locationManager;
protected LocationListener locationListener;
protected Context context;
String lat;
String provider;
protected String latitude, longitude;
protected boolean gps_enabled, network_enabled;
#Override
public void onCreate() {
super.onCreate();
Log.e("Location", "here");
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// public void requestPermissions(#NonNull String[] permissions, int requestCode)
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for Activity#requestPermissions for more details.
return;
}
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
#Override
public void onLocationChanged(Location location) {
Log.e("Location", "" + location.getLatitude());
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.e("Location Status", "" + provider + " " + status + " " + extras);
}
#Override
public void onProviderEnabled(String provider) {
Log.e("Location", "Enabled");
}
#Override
public void onProviderDisabled(String provider) {
Log.e("Location","Disabled"+provider);
}
}
but here the onLocationChanged function is never getting called, so i m not able fetch the location. So how can i get the location?
In the logcat, the info tab is showing the latitude and longitude under the title onLocationReceived".
This is the manifest,
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.krijjj.loginapp" >
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but are recommended.
-->
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:name=".Location.MainLocation"
android:allowBackup="true"
android:icon="#drawable/icon1"
android:label="#string/app_name"
android:theme="#style/AppTheme"
tools:replace="android:label" >
<activity
android:name=".Track"
android:label="Track" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Security.Lockscreen"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".Second"
android:label="#string/title_activity_second" >
<intent-filter>
<action android:name="com.example.krijjj.loginapp.Second" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name=".MainActivity"
android:label="#string/title_activity_mapactivity" >
</activity>
<activity
android:name=".Security.MainActivity"
android:label="#string/title_activity_mapactivity" >
</activity>
<!--
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" />
<activity
android:name=".MapsActivity"
android:label="#string/title_activity_maps" >
</activity>
</application>
</manifest>
The Google Play services location APIs are preferred over the Android framework location APIs (android.location) as a way of adding location awareness to your app.
You can find the example how to use it right here.
P.S. Don't forget to check if permissions granted on your device, if you added permissions into manifest file...
here i am really not getting why my code is not sending push from a user to another user ,i can send and receive pushes by sending through channels but problem is i get push notification to all user, not the specific user ,how can i send from a user to another user here below is my code please explain me what is my mistake ,or how to me it work
MY onClick of button where things must happen
ok.setOnClickListener(
new View.OnClickListener()
{
#Override
public void onClick(View v)
{
final String currentUserId = ParseUser.getCurrentUser().getObjectId();
ParseQuery<ParseUser> query = ParseUser.getQuery();
getPhone = phone.getText().toString();
//for not including myself
query.whereNotEqualTo("objectId", currentUserId);
query.whereEqualTo("username", getPhone);
query.getFirstInBackground(new GetCallback<ParseUser>()
{
public void done(final ParseUser user, ParseException e)
{
if (user == null)
{
Toast.makeText(Welcome.this, "couldnot connect to " + getPhone, Toast.LENGTH_SHORT).show();
Log.d("username", "problem retriving username");
}
else
{
ParseQuery pushQuery = ParseInstallation.getQuery();
pushQuery.whereEqualTo("email", "three");
final String name = user.getUsername();
String data = "{\n" +
"\"data\":{\n "+
"\"message\":\"Connection request\",\n" +
"\"title\":\"Connection\",\n" +
"\"from\":"+"\""+ParseUser.getCurrentUser().getUsername()+"\""+"\n "+
"}\n" +
"}";
JSONObject jsonObject = null ;
try
{
jsonObject = new JSONObject(data);
} catch (JSONException e1)
{
e1.printStackTrace();
}
ParsePush push = new ParsePush();
push.setQuery(pushQuery);
push.setData(jsonObject);
//push.setChannel("Giants");
push.sendInBackground(new SendCallback()
{
#Override
public void done(ParseException e)
{
if (e == null)
{
Toast.makeText(getApplicationContext(), "request send to "+name, Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(getApplicationContext(), "problem sending request to "+name+" due to "+e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}
);
Intent i = new Intent(Welcome.this, TestActivity.class);
Log.e("about user", "connected to " + user.getUsername());
retrivedUser = user.getUsername();
i.putExtra("number", retrivedUser);
startActivity(i);
}
}
});
My AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<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" />
<!--
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.example.chattapp.permission.C2D_MESSAGE" />
<application
android:name=".Chattapp"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name" />
<activity android:name=".DispatchActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".LoginActivity" />
<activity android:name=".SignUpActivity" />
<activity android:name=".Welcome" />
<activity android:name=".TestActivity"></activity>
<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 android:name="com.example.chattapp.CustomReceiver"
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.example.chattapp" />
</intent-filter>
</receiver>
</application>
here is the push image
push details
This is what I did for a chat app I made, every time a user sings up on your app, suscribe it to a channel with their user id. That way you will have an unique channel for every user and you can send individual pushes to them.
Here is a quick code I put up:
ParseUser user = new ParseUser();
user.setUsername("my name");
user.setPassword("my pass");
user.setEmail("email#example.com");
// other fields can be set just like with ParseObject
user.put("phone", "650-253-0000");
user.signUpInBackground(new SignUpCallback() {
public void done(ParseException e) {
if (e == null) {
String userID = user.getObjectId();
ParsePush.subscribeInBackground(userID});
} else {
// Sign up didn't succeed. Look at the ParseException
// to figure out what went wrong
}
}
});
After this you just need the userid of the receiver and that's it.
Is client push enabled in the parse application settings ?
It's disabled by default.
More infomation can be found at the parse blog:
http://blog.parse.com/learn/engineering/the-dangerous-world-of-client-push/
I recently upgraded my parse-*.jar files to version 1.10.0
After cleaning up my project at android studio and syncing with gradle, suddenly my app freezes at start... blackscreen, without any button working (I need to force-close the app)
I searched the net and this site for solutions, but couldn't find anything.
Any help will be much appreciated!
My Application class:
public class Application extends android.app.Application {
#Override
public void onCreate() {
super.onCreate();
Log.d("app", "reached1");
// Enable Local Datastore.
Parse.enableLocalDatastore(this);
Log.d("app", "reached2");
ParseObject.registerSubclass(FoodListItem.class);
Log.d("app", "reached3");
Parse.initialize(this, "STRING1", "STRING2");
Log.d("app", "reached4");
ParseInstallation.getCurrentInstallation().saveInBackground();
Log.d("app", "reached5");
ParsePush.subscribeInBackground("", new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.d("app", "successfully subscribed to the broadcast channel.");
} else {
Log.e("app", "failed to subscribe for push", e);
}
}
});
}
logcat:
08-17 21:46:58.554 17633-17633/il.ac.huji.freefood D/dalvikvm﹕ Late-enabling CheckJNI
08-17 21:46:58.594 17633-17633/il.ac.huji.freefood W/ActivityThread﹕ Application il.ac.huji.freefood can be debugged on port 8100...
08-17 21:46:58.604 17633-17633/il.ac.huji.freefood D/app﹕ reached1
08-17 21:46:58.604 17633-17633/il.ac.huji.freefood D/app﹕ reached2
08-17 21:46:58.614 17633-17633/il.ac.huji.freefood D/app﹕ reached3
Thanks in advance!
EDIT:
my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="il.ac.huji.freefood" >
<uses-sdk android:minSdkVersion="11" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<permission
android:name="il.ac.huji.freefood.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="il.ac.huji.freefood.permission.C2D_MESSAGE" />
<application
android:name="il.ac.huji.freefood.Application"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
>
<activity android:name=".activities_one_class.MainActivity" />
<activity android:name=".activities_one_class.NoFoodFoundActivity" />
<activity android:name=".activity_choose_food.ChooseFoodActivity" />
<activity android:name=".activity_add_food.AddFoodActivity" />
<activity android:name=".GPS_tracker_Activity" />
<activity android:name=".activities_one_class.SignUpActivity" />
<activity android:name=".activities_one_class.LoginActivity">
<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.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="il.ac.huji.freefood" />
</intent-filter>
</receiver>
<receiver
android:name="il.ac.huji.freefood.PushNotificationsReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.OPEN" />
<action android:name="com.parse.push.intent.DELETE" />
</intent-filter>
</receiver>
<meta-data
android:name="com.parse.push.notification_icon"
android:resource="#drawable/pooh_icon" />
<!--TODO once it was android:resource="#drawable/ic_launcher" />-->
</application>
</manifest>
Shouldn't you initialize the parse sdk before anything else
public class Application extends android.app.Application {
#Override
public void onCreate() {
super.onCreate();
Parse.initialize(this, "STRING1", "STRING2");
Parse.enableLocalDatastore(this);
ParseObject.registerSubclass(FoodListItem.class);
ParseInstallation.getCurrentInstallation().saveInBackground();
ParsePush.subscribeInBackground("", new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.d("app", "successfully subscribed to the broadcast channel.");
} else {
Log.e("app", "failed to subscribe for push", e);
}
}
});
}
To anyone who might be concerned, Apparently there was no Internet connection for the phone (because it automatically went into USB tethering and something went wrong over there) so that when parse got initialized it tried to connect to the server AT THE MAIN THREAD without success, causing the freeze effect.
The solution was to check for the phone's connectivity BEFORE starting parse, so my final solution was -
public class Application extends android.app.Application {
#Override
public void onCreate() {
super.onCreate();
Log.d("app", "reached1");
if (!connectedToInternet()) {
Log.e("app", "not connected to internet. exiting");
exitAppWithDialog(this);
}
....
}
I chose one of the methods to check connectivity which exist here -
How to check internet access on Android? InetAddress never times out
Have a good day!