简体   繁体   中英

Contact Ringtone not setting in Cordova for Android

I'm looking to create a plugin for setting ringtones to contacts using Cordova / Android, but I haven't had any luck after messing around with the following code for a while:

package com.mypackage.contactringtone;

import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.PhoneLookup;
import android.provider.ContactsContract.CommonDataKinds;
import android.provider.ContactsContract.CommonDataKinds.*;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.LOG;
import org.json.JSONArray;
import org.json.JSONException;
import java.lang.Object;
import android.net.Uri;
import java.io.File;
import android.content.Context;
import android.content.ContentValues;
import android.database.Cursor;
import android.provider.MediaStore;

public class ContactRingtone extends CordovaPlugin {

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        if ("set_ringtone".equals(action)) {
            String contact_id = args.getString(0);
            String phone_number = args.getString(1);
            String ringtone_path = args.getString(2);

            int my_contact_id = Integer.parseInt(contact_id);

        Context context = cordova.getActivity();
            Uri contact_data = ContactsContract.Contacts.CONTENT_URI;
            File ringtone_file = new File(ringtone_path);

            String[] projection = new String[] {
                ContactsContract.Contacts._ID,
                ContactsContract.Contacts.DISPLAY_NAME,
                ContactsContract.Contacts.HAS_PHONE_NUMBER
            };

            String selection = ContactsContract.CommonDataKinds.Phone._ID + "='" + my_contact_id + "'";

            Cursor local_cursor = context.getContentResolver().query(contact_data, projection, selection, null, null);
            local_cursor.move(1);

            String this_id = local_cursor.getString(local_cursor.getColumnIndexOrThrow("_id"));
            Uri local_uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, this_id);
            ContentValues local_content_values = new ContentValues();

            local_content_values.put(ContactsContract.Data.RAW_CONTACT_ID, my_contact_id);
            local_content_values.put(ContactsContract.Data.CUSTOM_RINGTONE, ringtone_file.getAbsolutePath() + "/" + contact_id + ".ogg");
            context.getContentResolver().update(local_uri, local_content_values, null, null);

            callbackContext.success("Ringtone set for: " + my_contact_id + " - " + phone_number + " - " + ringtone_path);
            return true;
        }

        callbackContext.error("Invalid action: " + action);
        return false;
    }
}

Basically, I'm using the following plugins to get contact data and ringtone path:

cordova-plugin-contacts cordova-plugin-RingtoneSelector

Once I get the contact ID and ringtone path, I send them to my custom plugin as arguments. Contact ID example is "1". Ringtone path example is "content://media/internal/audio/media/34".

I am not seeing any errors returned and the success callback returns the data from the Java function correctly, so I'm assuming I'm just not querying something correctly.

I'm fairly new to Java, so this code is becoming a mess. What needs to be updated in the above code to be able to set a ringtone to a contact properly? Thanks in advance.

Few issues I find here:

  1. contact-id is a Long not an Integer on Android, so Integer.parseInt(contact_id) is wrong.
  2. CommonDataKinds.Phone._ID is not the contact-id, it's the id of the Data row of a phone number, so selection is wrong.
  3. new File(ringtone_path) make sure you have permission to access this path, especially if you're using Runtime-permissions on Marshmallow+ devices.
  4. Data.RAW_CONTACT_ID is the ID of a RawContact , not Contact .

Here's the part of the Contacts update code that should work:

Long myContactId = Long.parseLong(contact_id);
final String ringtoneUri = Uri.fromFile(ringtone_file).toString();

ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Contacts.CONTENT_URI)
        .withSelection(ContactsContract.Contacts._ID + " = '" + myContactId + "'")
        .withValue(ContactsContract.Contacts.CUSTOM_RINGTONE, ringtoneUri)
        .build());

try {
    resolver.applyBatch(ContactsContract.AUTHORITY, ops);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM