I have a question about JobScheduler and would be very happy if someone could solve my problem. I have a Trigger-based Job watching for changes in the Contact photo on an android phone:
static {
JobInfo.Builder builder = new JobInfo.Builder(JobIds.PHOTOS_CONTENT_JOB,
new ComponentName("com.android.agent", AgentService.class.getName()));
builder.addTriggerContentUri(new JobInfo.TriggerContentUri(
ContactsContract.DisplayPhoto.CONTENT_URI,
JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS));
builder.setTriggerContentMaxDelay(1000);
JOB_INFO = builder.build();
}
I get a reaction from the phone and a URI, the problem I have is the only URI information I get is: content://com.android.contacts
What I need is some kind of information on what Contact just changed or what Id the photo just added have.
If someone could help, many thanks in advance.
(Not the same question as Android - Get only newest contacts that were added but the same answer)
Starting with API level 18, you can use Contacts.CONTACT_LAST_UPDATED_TIMESTAMP, so it's possible to query for all contacts that had been modified (or created) recently, and compare only those to your last cache of contact ids, and the delta would be the contacts created/modified since the last time your code ran.
Related
EDIT
FYI, The trick which consists in extracting RawContactID from lookupKey (similar to "1450iSkype_288") does not work anymore.
Summary
I am able to obtain 'Skype ID' / 'Skype user name' , but my solution does not always work because it seems the contact DB of the Skype app does not always contain (expose?) 'all' the data.
Let me explain the situation before asking my question:
1 - Gathering info from Skype apk
Skype App (apk) contains /res/xml/contacts.xml which contains
<ContactsDataKind
android:icon="#ref/0x7f0e0004"
android:mimeType="vnd.android.cursor.item/com.skype4life.audio"
android:summaryColumn="data3"
android:detailColumn="data4" />
<ContactsDataKind
android:icon="#ref/0x7f0e0004"
android:mimeType="vnd.android.cursor.item/com.skype4life.video"
android:summaryColumn="data3"
android:detailColumn="data4" />
<ContactsDataKind
android:icon="#ref/0x7f0e0004"
android:mimeType="vnd.android.cursor.item/com.skype4life.message"
android:summaryColumn="data3"
android:detailColumn="data4" />
<ContactsDataKind
android:icon="#ref/0x7f0e0004"
android:mimeType="vnd.android.cursor.item/com.skype4life.phone"
android:summaryColumn="data3"
android:detailColumn="data4" />
The important data here is these 4 Skype mimeTypes:
"vnd.android.cursor.item/com.skype4life.phone"
"vnd.android.cursor.item/com.skype4life.message"
"vnd.android.cursor.item/com.skype4life.audio"
"vnd.android.cursor.item/com.skype4life.video"
Note:
It looks like these have been added around Augustus 2018 (see here http://www.skaip.org/skype-8-27-0-88-for-android )
One more usefull info is that the ContactsContract.RawContacts.ACCOUNT_TYPE of Skype is "com.skype.raider"
2 - Querying Content provider
Using info obtained in point 1, I could query the Skype ContentProvider (using selection ContactsContract.Data.MIMETYPE+ "= ? " and selectionArgs "com.skype.raider" ) and obtain data which must be 'interpreted' according to the mimeType (one of the 4 Skype mimeTypes obtained in point 1).
2.1 - For mimeType vnd.android.cursor.item/com.skype4life.message, I obtain something like this:
mimetype = vnd.android.cursor.item/com.skype4life.message
_id = 2773
lookup = 1450iSkype_288
contact_id = 1601
display_name = <Skype User DISPLAY Name HERE>
raw_contact_id = 515
mimetype = vnd.android.cursor.item/com.skype4life.message
data1 = 8:<skype.user.name.value.here>
data2 = null
data3 = Skype
is_primary = 0
data5 = null
Where
<Skype User DISPLAY Name HERE> is an actual Display Name
<skype.user.name.value.here> is an actual Skype user name / Skype ID
<skype.user.name.value.here> is the data I want, so this is good!
Important note:
EDIT: this trick does not work anymore ->
The lookup = 1450iSkype_288 can be parsed to obtain 288 which is the RawcontactId of some other contact!
If this rawContact has a contactId, then this allows me to find the original Contact (vs RawContact)
It does even sometimes refer some contact which is NOT a Google contact, but, for example, a WhatsApp contact!
Enjoy this important info ;-)
<- this trick does not work anymore
2.2 - Similar data for theses 2 mimeTypes:
"vnd.android.cursor.item/com.skype4life.audio"
"vnd.android.cursor.item/com.skype4life.video"
So I am also able to obtain <skype.user.name.value.here>. Again, this is good!
2.3 - the Phone mimeType
"vnd.android.cursor.item/com.skype4life.phone"
does not contain Skype ID (in field data1), but instead the phone number, which makes sense.
3 - The Problem
So, all this works fine an I decided to test my code on some other devices, where I installed Skype and used it with same Skype account + same Google account and, BOOM, here is the problem:
The Skype Content Provider only has data for mimeType
"vnd.android.cursor.item/com.skype4life.phone" // <- contains Skype user's phone number, NOT Skype user name / Skype ID
and has NO data for these 3 mimeTypes
"vnd.android.cursor.item/com.skype4life.message" // <- contains Skype username / ID
"vnd.android.cursor.item/com.skype4life.audio" // <- contains Skype username / ID
"vnd.android.cursor.item/com.skype4life.video" // <- contains Skype username / ID
Skype Phone Numbers are only usefull to pass phone call using Skype, but that's not what I want to do: I want to pass 'Internet Skype audio / video' calls, not 'regular cell phone' calls.
4 - Question
Why is the Skype app sometimes storing all 4 'phone/message/audio/video' mimeTypes data and sometimes, only 'phone' mimeType?
In the latter case, I am not able to obtain Skype Ids / Skype user names, i.e. the <skype.user.name.value.here> I mentioned above.
I understand my solution is the result of some kind of 'reverse-engineering-like method' and is not 'official' at all, but maybe someone else did the same kind of investigation I did and could find a solution?
Maybe there is some 'Skype sync settings' which should be activated within the Skype app or Within Android?
I already force contacts re-sync for Google and Skype accounts, but this did not help.
Thanks for your help.
What a great research! I got here because I stumbled upon the same problem. I also want to get skype username, but only mimetype "vnd.android.cursor.item/com.skype4life.phone" is present in the address book.
If I look at your link, where you mention these com.skype4life.* are added, I also see the addition of:
sync_adapter_account_type:
= com.skype4life
sync_adapter_authority:
= com.android.contacts
So they added this together. Maybe we should sync it in one way or another?
The mere problem is, that you don't have com.skype.raider.permission.ACCOUNT.
So you can only query them through ContentProvider or build an index to look them up.
For example:
How to get Skype info from the Android contact list?
Get Skype name from Contacts list
Intent strings alike com.skype.android.skypecall.action might not exist anymore, because com.skype.raider/com.skype4life obviously is not the same application.
I'm trying to update a field on the Watson DB but I'm not able to, I do not get any error. I think that I properly setted up since I got several records with value on the field Mobile User Id and I got all the Push notifications I sent.
So far, I'm using the following lines to try to update the fields, where myField is the exact name on the Watson DB.
StringAttribute attribute = new StringAttribute("myField", "New Value");
List<Attribute> attributes = new ArrayList<(1);
attributes.add(attribute);
MceSdk.getQueuedAttributesClient().updateUserAttributes(getApplicationContext(), attributes);
Should this be enough to perform the update or should I add something else?
At the end, I setup again the service following all the process step by step of the following URL:
https://developer.ibm.com/customer-engagement/tutorials/configuring-basic-push-services-for-android-apps/
And was able to perform updates to the DB using the code from the following URL:
https://developer.ibm.com/customer-engagement/docs/watson-marketing/ibm-engage-2/mobile-push/mobile-push-android/advanced-push-attributes-for-android/
I changed the device too, and I started to get updates on the BD.
Trying to call number with name.It is possible to make name with number calling.
I successfully calling following code:
Intent callIntentp2 = new Intent(Intent.ACTION_CALL);
callIntentp2.setData(Uri.parse("tel: 55555555");
startActivity(callIntentp2);
It's Output looks like
55555555 Dialing
But I want to call with name just like you saved on contact list on your sim.but i have data in manually not from sim.
John 55555555 Dialing
Is that possible.
ACTION_CALL is a native Android intent. When you call it, Android performs background processes that bring up the default call view. There are ways you could chop together some broadcast receiver to overlay an activity on top of the native call screen, but you are asking for trouble on that end. Without a rooted device, this is a difficult process. This question is actually very similar to:
Replace native outgoing call Screen by custom screen android
I haven't read through the link or anything, but I am pretty sure they are going to say the same thing. Without doing some weird, iffy work-around you aren't likely to achieve this.
You could (theoretically) take the time prior to calling to add the number with the attached name to your contacts list. When the call is made, it will show the name and the number (since the name is listed as a contact and that is Android's default action). Once the call is done you could delete the contact so that it doesn't get stuck in a persons contact list that doesn't want it.
A bit of code for example:
ContentValues contactValues = new ContentValues();
contactValues.put(Data.RAW_CONTACT_ID, 001);
contactValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
contactValues.put(Phone.NUMBER, "555-555-5555");
contactValues.put(Phone.TYPE, Phone.TYPE_CUSTOM);
contactValues.put(Phone.LABEL, "John");
Uri dataUri = getContentResolver().insert(
android.provider.ContactsContract.Data.CONTENT_URI, contactValues);
Don't forget to add write contact permission to your applications manifest. Again, this is just an option (the only one I can really think of off the top of my head)
I've, to the best of my knowledge, successfully integrated Google Aanlytics tracking in an Android app. When viewing the results web, section Conversions - eCommerce - Transactions, the tracked transactions appear correctly, save for the item quantity, which is always zero. However, when debugging my code, the quantity stored in the transaction object is correct. I've also waited several days (about a week), in case the results would update themselves, to no avail. Is there anything "special" I should do to track the item quantity of a transaction? Could this be a bug in the Android GA SDK?
I'm attaching the code I'm using, just in case:
tracker.addTransaction(new Transaction.Builder(orderPK, totalPrice).setStoreName("").setTotalTax(totalTax).setShippingCost(shipping).build());
Item.Builder builder = new Item.Builder(orderPK, productPK, price, quantity);
builder.setItemCategory(category);
Item item = builder.build();
tracker.addItem(item);
tracker.trackTransactions();
tracker.dispatch();
tracker.clearTransactions();
Am giving a working code which has worked for me. please try this code
tracker = GoogleAnalyticsTracker.getInstance();
tracker.addTransaction(new Transaction.Builder("3000",25000).setStoreName("MarIoS").setTotalTax(3.23).setShippingCost(10.44).build());
Item.Builder builder = new Item.Builder("3000", "Mobile",5000,5);
builder.setItemCategory("Electronics");
builder.setItemName("SamsunG");
Log.d("json","In Transaction");
Item item = builder.build();
tracker.addItem(item);
tracker.trackTransactions();
tracker.dispatch();
It's been a while, but I found the problem, so I'm leaving it posted here.
It turns out there is a field of the item, the name, which is mandatory, though it's not listed anywhere as such (other than in the JS API, where I found it).
So the solution is to add the following line:
builder.setItemName(name);
Hi
I wan to create a contact, so here is my code:
Intent addPersonIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
addPersonIntent.putExtra(Insert.NAME, "asd");
addPersonIntent.setType(Contacts.People.NAME);
addPersonIntent.putExtra(Insert.PHONE_TYPE, Contacts.Phones.TYPE_WORK);
addPersonIntent.putExtra(Insert.PHONE, Uri.decode("123"));
addPersonIntent.putExtra(Insert.PHONE_TYPE, Contacts.Phones.TYPE_MOBILE);
addPersonIntent.putExtra(Insert.PHONE, Uri.decode("123"));
addPersonIntent.setType(Contacts.Phones.CONTENT_ITEM_TYPE);
...
startActivity(addPersonIntent);
Why the only thing that is created is the mobile number, I never got the "work" number?
You're thinking of "putExtra" as adding to the end of an array - Your problem will be clearer if you think of it as setting name/value pairs in a hashtable. Basically, you're setting PHONE_TYPE to "work", PHONE to 123, PHONE_TYPE to "mobile" (overwriting when it was set to work), and PHONE to "123" again.
What you want to do is set either the "mobile" or "work" phone data using SECONDARY_PHONE and SECONDARY_PHONE_TYPE - Details here.
Also, keep in mind that all this follows the old version of the Contacts API, which is deprecated as of Android 2.0+. There's a handy resource on migrating your code to use the new contacts API here.
here is the next problem, when I add:
addPersonIntent.putExtra(Insert.NOTES, "asdkjhaskh");
the note data never appears in the activity, why?
The whole idea is to start the EditContactActivity.java with loaded data and for now I loaded phones, names and companies. For some reason I cant load notes, and another problem is how to set in the intent information for the IM? For example I tryed with:
addPersonIntent.putExtra(Insert.IM_HANDLE, "mySkype");
addPersonIntent.putExtra(Insert.IM_PROTOCOL, Uri.decode("skype"));
but it is not working.