I'm trying to add my app icon in contact details, to work like a shortcut, i manage to show a title and subtitle but the app icon doesn't appear and i don't understand how to show him and how to add the event to navigate to an specific page after click in the custom cell.
someone can help me?
i have the following code on my contact manager:
public static void addContact(Context context, MyContact contact) {
ContentResolver resolver = context.getContentResolver();
// add condition that you want to check
ContentValues contentValues = new ContentValues();
contentValues.put(ContactsContract.Data.RAW_CONTACT_ID,
Integer.parseInt(contact.id));
contentValues.put(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE);
contentValues.put(ContactsContract.CommonDataKinds.Im.TYPE,
ContactsContract.CommonDataKinds.Im.TYPE_CUSTOM);
contentValues.put(ContactsContract.CommonDataKinds.Im.LABEL, "Title");
contentValues.put(ContactsContract.CommonDataKinds.Im.PROTOCOL,
ContactsContract.CommonDataKinds.Im.PROTOCOL_CUSTOM);
contentValues.put(ContactsContract.CommonDataKinds.Im.CUSTOM_PROTOCOL,
"Title");
contentValues.put(ContactsContract.CommonDataKinds.Im.DATA, "TransferĂȘncia");
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation
.newInsert(ContactsContract.Data.CONTENT_URI)
.withValue(Data.MIMETYPE, MIMETYPE)
.withValues(contentValues).build());
try {
resolver.applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
String ex = e.getMessage();
}
}
`
and the following service on android manifest
<service
android:name="com.[appPackage].SyncService"
android:exported="true" >
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data android:name="android.content.SyncAdapter" android:resource="#xml/syncadapter" />
<meta-data android:name="android.provider.CONTACTS_STRUCTURE" android:resource="#xml/contacts" />
</service>
someone can help me? Thx
First of all, each RawContact on the Contacts DB was synced by a particular app, so if that's not already the case for you, I would suggest you have your app insert its own RawContacts, and not mangle with RawContacts existing on the device, as they can be deleted, edited, reset by the controlling app at any time.
Now to get your app's "actions" displayed on the native contacts app, you need to declare your contacts custom mimetype and related fields, you do this with a special xml file called contacts.xml that you declare in your manifest which maps different DataKinds to Data columns like DATA1, DATA2, etc.
You then need to have an activity to catch the intent that will be fired when the user clicks on your custom row.
You declare the intent in the contacts.xml file as well, and you then need to set a similar intent-filter in your activity's manifest block so Android will know which activity to launch.
Here's official documentation: https://developer.android.com/guide/topics/providers/contacts-provider.html#CustomData & here: https://developer.android.com/guide/topics/providers/contacts-provider.html#SocialStreamDataKind
Here's a tutorial: https://medium.com/#stephen.cty/android-account-sync-adapter-and-contacts-contract-database-983281be4847
Again, try to make sure that the myRawContactId value in that tutorial is pointing to a RawContact your app had created, that will prevent future bugs with Google messing with your custom data rows
Related
Some hidden settings require to type codes like *#06# in dialer.
Is it possible to create an app that does something when it detects a specific code like that ?
If you are trying to create a USSD based application then below link can help.
Read USSD messages in Android
However, if you want to simply dial a USSD content add respective permission in AndroidManifest.xml file as below and try :
<uses-permission android:name="android.permission.CALL_PHONE" />
private void dialUSSD(String uriString) {
Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse(uriString));
startActivity(callIntent);
}
I am developing an android based note taking application with categories.I am supposed to create notes shortcuts on home screen. When user click on the shortcut the relevant activity should be open and the specific data should be set in Edit-texts i.e Its title and description.I unable to understand the logic to do that.
I tried all possible solutions that come into my mind. I passed Id of note in shortcut intent but when it launch from shortcut the fields are still empty.
This is my snippet of code to create shortcut:
Function to create shortcut:
private void createShortcutOfActivity() {
Intent shortcutIntent = new Intent(getApplicationContext(),
TextNotes.class);
shortcutIntent.setAction(Intent.ACTION_MAIN);
Intent addIntent = new Intent();
addIntent
.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, editTitle.getText().toString());
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
Intent.ShortcutIconResource.fromContext(getApplicationContext(),
R.mipmap.ic_launcher));
addIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
addIntent.putExtra("duplicate", false); //may it's already there so don't duplicate
getApplicationContext().sendBroadcast(addIntent);
}
This function is called when user click on option to create shortcut.
In Menifest use permission:
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
Also add intent filter and exported property in non launching activity:
<activity
android:name=".TextNotes"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.CREATE_SHORTCUT"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
The activity receive data from intent when open a note from another activity:
Intent newInt=getIntent();
isDoubleClicked=newInt.getBooleanExtra("Chk",false);
Cat=newInt.getStringExtra("Category");
Id=newInt.getIntExtra("Id",0);
String title=newInt.getStringExtra("Message");
String description=newInt.getStringExtra("Message2");
check=newInt.getStringExtra("Check");
editTitle.setText(title);
editText.setText(description);
I also tried to use this id in the shortcut intent of the function but having no change in result.
shortcutIntent.putExtra("key_primary",Id);
I want to keep the data when open using shortcut.For example for different note shortcut the rspected data should be set in fields just like in whatsapp the chat shortcuts of different contacts can be craeted . But unfortunately I am unable to understand that how should it be done because everytime I open using shortcut its fields become empty. Where should I pass id and how to set data when it launch from shortcut.
If you use shortcutIntent.putExtra("key_primary",Id); then you need to retrieve it using
Id=newInt.getIntExtra("key_primary",0);
That is the first parameter (key_primary) is the key that is used to identify the specific Intent Extra. Thus, the key value must match the key value used when putting the Intent Extra for a value (other than the default) to be retrieved.
As such coding Id=newInt.getIntExtra("Id",0); without using the matching/paired shortcutIntent.putExtra("Id",Id); will always result in 0 as the Intent Extra doesn't exist so the default value is returned.
I am developing an app for commercial use with a background service that is getting transponder numbers (of animals) from an RFID reader via bluetooth.
After processing the received number I would like to send it to the clipboard and paste it in the focused text field of whatever application is currently in front which in my case is a browser app.
I already found a similar question from 2013 but with no accepted answer by now. All answers to the question just explained how to use ClipboardManager to copy and paste code within the developed application but that has not been meant by the problem as he clarified in a comment.
The simplest scenario that I could imagine is to just simulate a paste action on the android device. I would prefer not to need to install a third party app.
Just to add to Kirill's answer and assuming the app has Accessibility permission,
Create a class extending AccessibilityService and override onAccessibilityEvent method.
public class SampleAccessibilityService extends AccessibilityService {
#Override
public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
AccessibilityNodeInfo source = accessibilityEvent.getSource();
if (source != null) {
AccessibilityNodeInfo rowNode = getRootInActiveWindow();
if (rowNode != null) {
for (int i = 0; i < rowNode.getChildCount(); i++) {
AccessibilityNodeInfo accessibilityNodeInfo = rowNode.getChild(i);
if (accessibilityNodeInfo.isEditable() && accessibilityNodeInfo.isFocused()) {
accessibilityNodeInfo.performAction(AccessibilityNodeInfoCompat.ACTION_PASTE);
return;
}
}
}
}
}
#Override
public void onInterrupt() {
}
}
accessibilityNodeInfo.performAction(AccessibilityNodeInfoCompat.ACTION_PASTE) will paste the text that is copied to clipboard.
Also make sure you have right accessibility configuration.
config.xml
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityFlags="flagDefault"
android:accessibilityEventTypes="typeViewClicked|typeViewFocused"
android:accessibilityFeedbackType="feedbackGeneric"
android:notificationTimeout="0"
android:canRetrieveWindowContent="true"
android:description="#string/testing" />
Here android:accessibilityEventTypes="typeViewClicked|typeViewFocused" will filter the events to view click or view focus.
You can also the events based on the packages using "android:packageNames" (so that your service won't get called often)
Finally declare the service in manifest,
<service android:name=".SampleAccessibilityService"
android:label="#string/app_name"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService"/>
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="#xml/config" />
</service>
If you want your app to interact with an app that isn't yours (the browser) you will have to give this app accessibility permissions. those are special kind of permission that allow apps to interact with something that is a bit more senstive.
there are accessibility actions, the one that you are looking for is the
AccessibilityNodeInfoCompat.ACTION_PASTE it allows you to preform a paste into a focused field.
Note that I'd recommend you to replace the browser with a inapp WebView, and inject the values with javascript this will be much more robust solution for your automation. you can find more info on how to run JS on a webview here: How to get return value from javascript in webview of android?
I wrote an Android app with an appwidget.
I want to do this in my code:
if (widget_is_used_by_user)
Is there any way for me to know whether the user placed the widget on the home screen?
If You want to know if the Widget is installed, put som e Log, or whatever You want to do inside onEnabled():
public void onEnabled(Context context){
super(context);
Log.d("WIDGET","WIDGET ENABLED);
}
Also, sometimes it is required to set actions inside the receiver in manifest. I saw some posts about that, but in my widget I also get message without setting action:
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.APPWIDGET_ENABLED" />
<action android:name="android.appwidget.action.APPWIDGET_DELETED" />
<action android:name="android.appwidget.action.APPWIDGET_DISABLED" />
</intent-filter>
If you don't want to keep track of them on your own like Opiatefuchs suggests, unfortunately there's no sure way.
You can query the AppWidgetManager to get a list of available appwidget IDs like this:
ComponentName widgetProvider = new ComponentName(this, "appwidget_class_name");
int[] appWidgetIds = AppWidgetManager.getInstance(this).getAppWidgetIds(widgetProvider);
for (int awId : appWidgetIds) {
// If there is any appwidget on the home screen, its ID should be in the list
}
I'm saying there's no sure way because the problem of phantom appwidget IDs (IDs created by the AppWidgetHost that have no "real" widget present on the home screen) is still a reality, even with recent Android versions.
I currently have an Android application that has an intent-filter to receive images from the Gallery. It is important that the images are received in the same order that the user selected them in. This seems to be the default behavior on most devices, however on some devices (so far I've seen this on Motorola's running Android 4.x) the order seems undefined. Does anyone know a way to declare in the intent that the images should be received in order? Or a way once the images are recieved to determine the selected order?
Here is relevant code from the manifest
<activity
android:label="#string/app_name"
android:name=".activities.ImportImagesActivity" >
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
</activity>
And from ImportImagesActivity
private List<Uri> parseIncomingData() {
List<Uri> uriList = null;
Intent intent = this.getIntent();
if(intent != null) {
String action = intent.getAction();
//Single Image
if (action.equalsIgnoreCase("android.intent.action.SEND")) {
//removed for brevity
}
}
//Multiple Images
else if (action.equalsIgnoreCase("android.intent.action.SEND_MULTIPLE")) {
uriList = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
}
}
//more code - at this point images have been recieved
return uriList;
}
EDIT
To give a little context, let me explain the general flow of the app.
The user opens the Gallery and selects images. They choose to 'Share' them with my app. My application receives a list of Uri's which are then displayed using an internal gallery backed by a custom Adapter class. The images display correctly based on the Uri list, the issue is the order of the List<Uri> is sometimes incorrect. It is important to my users that the images appear in the same order they select them in.
Clarification
When I use the term Gallery I am referring to the built in Android app Gallery.
When I use the term 'Share' I am referring to the the Share button within the Gallery app. This allows the user to select from a list of services such as Facebook, Email, and in this case my app.
For Example
imagine a Gallery with 3 images, displayed in an arbitrary order: A, B, and C. The user selects first C then A then B and chooses to share them with my app. On most phones my list will be correctly ordered {C, A, B}, on offending phones this order seems random.
I cannot use the creation timestamp because the creation time is generally irrelevant to the selection order. Adding custom meta data doesn't help either because I don't know the correct initial order.
My observation is that Android gallery displays images in accordance to their recency.
For the devices where you're unable to determine the order, you can import the images from the gallery and check their creation time. Here's a way to do that. Or you could use a metadata extractor app, many jars can be found.
Now, you could just arrange the images in the order of recency and you should be done.
[EDIT]
I have a question. You said they may be selected in any order, so are they "uploading" it onto a server by "sharing"?
If so, then one way is to check which image was uploaded or if you want the order of selection, you could do this. Edit the metadata of the images, there's bound to be a useless tag, select one and edit it on touch. So, if I select image A it changes to 1 and then I select image B it becomes 2. But if I unselect image A now then image B should become 1. So, you could use nodes here. This is the first in first out (FIFO) method. Upon un-selection, A is thrown out of the list and B replaces it.
Is this what you wanted?
EDIT
Sorry, I don't think you can do this without creating your own gallery. Why don't you just import the android gallery into a grid view in your app?
Yeah, I just faced the same problem right now. I am also using Fedor's lazy loading concept.I am not sure how far this will be helpful and whether this is the right approach. But still it solved the problem for me.
I had to do a little modification in the getView(),
#Override
public View getView(int position, View convertView, ViewGroup parent) {
System.gc();
ImageView view;
if(convertView == null) {
view = new ImageView(context);
view.setScaleType(ImageView.ScaleType.FIT_CENTER);
view.setLayoutParams(new GridView.LayoutParams(screenWidth/4, screenHeight/4));
view.setAdjustViewBounds(false);
view.setPadding(2, 2, 2, 2);
System.gc();
}else {
view = (ImageView) convertView;
}
if(view!=null)
{
imageLoader.DisplayImage(urlList.get(position), view);
notifyDataSetChanged(); //Calling this helped to solve the problem.
}
System.gc();
return view;
}