This is error, it says index out of bounds, but i couldn't how can i solve it, there are some Turkish words but they aren't important, i think:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.burhanozen.nothesaplama, PID: 26919
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.example.burhanozen.nothesaplama/com.example.burhanozen.nothesaplama.MainActivity}: android.database.CursorIndexOutOfBoundsException: Index 1 requested, with a size of 1
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at ........
I was trying to store some kind of student information. I have these errors, and I share codes below.
This is my MainActivity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar = findViewById(R.id.toolbar) as Toolbar
setSupportActionBar(toolbar)
val fab = findViewById(R.id.fab) as FloatingActionButton
fab.setOnClickListener {
val intent = Intent(this#MainActivity,NotEkrani::class.java)
startActivity(intent) }
val studentsArray = ArrayList<String>()
val arrayAdapter = ArrayAdapter(this,android.R.layout.simple_list_item_1,studentsArray)
listView.adapter= arrayAdapter
try{
val myDatabase = this.openOrCreateDatabase("student", Context.MODE_PRIVATE,null)
myDatabase.execSQL("CREATE TABLE IF NOT EXISTS students (isim TEXT," +
" dersbir TEXT, dersbirkredi TEXT, dersbirort TEXT," +
" dersiki TEXT, dersikikredi TEXT, dersikiort TEXT) ")
val cursor = myDatabase.rawQuery("select * from students",null)
val nameIx = cursor.getColumnIndex("isim")
val dersbirIx = cursor.getColumnIndex("dersbir")
val dersbirkrediIx = cursor.getColumnIndex("dersbirkredi")
val dersbirortIx = cursor.getColumnIndex("dersbirort")
val dersikiIx = cursor.getColumnIndex("dersiki")
val dersikikrediIx = cursor.getColumnIndex("dersikikredi")
val dersikiortIx = cursor.getColumnIndex("dersikiort")
cursor.moveToNext()
while (cursor != null){
studentsArray.add(cursor.getString(nameIx))
studentsArray.add(cursor.getString(dersbirIx))
studentsArray.add(cursor.getString(dersbirkrediIx))
studentsArray.add(cursor.getString(dersbirortIx))
studentsArray.add(cursor.getString(dersikiIx))
studentsArray.add(cursor.getString(dersikikrediIx))
studentsArray.add(cursor.getString(dersikiortIx))
cursor.moveToNext()
arrayAdapter.notifyDataSetChanged()
}
while (cursor!=null){
cursor!!.close()
}
}catch (e:SQLException){
}
And this is my second Activity Page, i couldn't any error here, but may be this can help. I wrote database codes here.
fun kaydet(view:View){
val isim = isim.text.toString()
val dersbir = dersbir.text.toString()
val dersbirkredi = dersbirkredi.text.toString()
val dersbirort = dersbirort.text.toString()
val dersiki = dersiki.text.toString()
val dersikikredi = dersikikredi.text.toString()
val dersikiort = dersikiort.text.toString()
try {
val myDatabase = openOrCreateDatabase("student", Context.MODE_PRIVATE,null)
myDatabase.execSQL("CREATE TABLE IF NOT EXISTS students (isim TEXT," +
" dersbir TEXT, dersbirkredi TEXT, dersbirort TEXT," +
" dersiki TEXT, dersikikredi TEXT, dersikiort TEXT) ")
val sqlString = "INSERT INTO students (isim,dersbir,dersbirkredi,dersbirort,dersiki,dersikikredi,dersikiort) VALUES(?,?,?,?,?,?,?)"
val statement = myDatabase.compileStatement(sqlString)
statement.bindString(1,isim)
statement.bindString(2,dersbir)
statement.bindString(3,dersbirkredi)
statement.bindString(4,dersbirort)
statement.bindString(5,dersiki)
statement.bindString(6,dersikikredi)
statement.bindString(7,dersikiort)
statement.execute()
}catch (e:SQLException){
}
val intent = Intent(this,MainActivity::class.java)
startActivity(intent)
}
Change your while loop to look like this:
while (cursor.moveToNext()){
studentsArray.add(cursor.getString(nameIx))
...
}
(Remove all the other cursor.moveToNext() from your code)
You are checking for cursor != null in your while loop condition, but it won't become null after you read all the rows from cursor.
In the above code, cursor.moveToNext returns true if there is a row next. Otherwise returns false and the loop terminates.
And, just noticed, you should change this from,
while (cursor!=null){
cursor!!.close()
}
to an if check:
if (cursor!=null){
cursor.close()
}
Or, as Todd suggested in the comments, you can use the Higher order function use which automatically closes the cursor, which is simlar to Java 7 try-with-resources.
cursor.use {
while (cursor.moveToNext()){
studentsArray.add(cursor.getString(nameIx))
...
}
}
You are getting this error because your cursor size is 1. There is only one record in your database. But you are querying database more than 1 time. That is the reason of your Error.
First of all your complete code of execution is wrong.
You are creating a database in your activity. If you do you can't manage your database properly and efficiently.
First, you have to create a SqliteOpenHelper database in a separate class. Then you have to create a table there. Then write helper methods there to get and insert values from it.
Your database class should be like the below example.
class DbHelper(context: Context) : SQLiteOpenHelper(context, "example.db", null, 4) {
val TAG = javaClass<DbHelper>().getSimpleName()
val TABLE = "logs"
companion object {
public val ID: String = "_id"
public val TIMESTAMP: String = "TIMESTAMP"
public val TEXT: String = "TEXT"
}
val DATABASE_CREATE =
"CREATE TABLE if not exists " + TABLE + " (" +
"${ID} integer PRIMARY KEY autoincrement," +
"${TIMESTAMP} integer," +
"${TEXT} text"+
")"
fun log(text: String) {
val values = ContentValues()
values.put(TEXT, text)
values.put(TIMESTAMP, System.currentTimeMillis())
getWritableDatabase().insert(TABLE, null, values);
}
fun getLogs() : Cursor {
return getReadableDatabase()
.query(TABLE, arrayOf(ID, TIMESTAMP, TEXT), null, null, null, null, null);
}
override fun onCreate(db: SQLiteDatabase) {
Log.d(TAG, "Creating: " + DATABASE_CREATE);
db.execSQL(DATABASE_CREATE)
}
override fun onUpgrade(p0: SQLiteDatabase, p1: Int, p2: Int) {
}
}
Since you are using Kotin database is very easy with Anko-Sqlite. By this library storing and retrieving data from the database is so easy. You can check it here.
https://github.com/Kotlin/anko/wiki/Anko-SQLite#using-anko-sqlite-in-your-project
Related
I am struggling to find an anwser to this question : how do I create a List with data from a SQL database in Java ? (I am using Android Studio)
I need to create :
lists for dropdown menus and autoCompleteTextView. For these, I need all the values of a specific column, not the whole line ("what are the different brands that exist in my table ?")
lists for all objects sharing the same attribute ("which objects have the same brand ?")
Here is my constructor for the database :
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + TABLE_NAME + "(id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"favori TEXT, " +
"type TEXT, " +
"marque TEXT, " +
"nom TEXT, " +
"nomGenerique TEXT, " +
"image BLOB, " +
"prix TEXT, " +
"codeBarres TEXT, " +
"quantite TEXT, " +
"quantiteRestante TEXT, " +
"notes TEXT)");
}
And this is my data model (in a Modele.class) - I have all the getters and setters after this - :
public InventaireAlcool(int id, Boolean favori, String type, String marque,
String nom, String nomGenerique, byte[] image, int prix,
int codeBarres, int quantite, int quantiteRestante, String notes) {
this.id = id;
this.favori = favori;
this.type = type;
this.marque = marque;
this.nom = nom;
this.nomGenerique = nomGenerique;
this.image = image;
this.prix = prix;
this.codeBarres = codeBarres;
this.quantite = quantite;
this.quantiteRestante = quantiteRestante;
this.notes = notes;
}
I have an activity (AjoutReference) where I fill a form and when I click on the save button, this is what it does :
Boolean get_favori = favori.isChecked();
String get_type = autoCompleteType.getText().toString();
String get_marque = autoCompleteMarque.getText().toString();
String get_nom = editTextNom.getText().toString();
String get_nomGenerique = editTextNomGenerique.getText().toString();
String get_prix = editTextPrix.getText().toString();
String get_code = editTextCode.getText().toString();
String get_quantite = quantite.getText().toString();
String get_quantiteRestante = String.valueOf(sliderQuantite.getValue());
String get_notes = editTextNotes.getText().toString();
boolean res = inventaireDb.ajoutInventaire(get_favori, get_type, get_marque,
get_nom, get_nomGenerique, ImageToByte(imageView), get_prix, get_code, get_quantite, get_quantiteRestante, get_notes);
if (res == true){
Toast.makeText(AjoutReference.this, "Reference added", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(AjoutReference.this, MainActivity.class);
startActivity(intent);
}
else {
Toast.makeText(AjoutReference.this, "Error", Toast.LENGTH_SHORT).show();
}
The data from the database is then displayed on a RecyclerView with this code (in a RecyclerViewAdapter class):
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.nomGenerique.setText(inventaireAlcoolList.get(position).getNomGenerique());
holder.marque.setText(inventaireAlcoolList.get(position).getMarque());
holder.type.setText(inventaireAlcoolList.get(position).getType());
Glide.with(this.context).load(inventaireAlcoolList.get(position).getImage()).into(holder.image);
holder.quantite.setText(String.valueOf(inventaireAlcoolList.get(position).getQuantite()));
I could not find any specific documentation or answer clear enough to help :-(
Any advice would be very much welcome!
And if you wonder what I will use this app for : it is to handle my alcohol stock. I currently have an excel table with more than 120 lines and it is a pain to maintain and keep updated (and, no, I'm not a bartender, just a whisky, gin and rhum enthusiast).
The app should allow me to know how many bottles I have, in which condition ("remaining quantity" is a slider that lets me specify how much is left in a bottle and, when I'm out shopping, I can make sure I buy a refill :-) ), the lowest price I got, to create a "favorites" list...
Edit :
I found the solution thanks to the link provided by Int'l Man of Coding Mystery.
I created methods inside my database class to provide me with lists of column contents. Here is the code, hoping it might help someone else.
public ArrayList getTypeExtract(){
SQLiteDatabase db = this.getReadableDatabase();
ArrayList<String> arrayList = new ArrayList<>();
Cursor cursor = db.rawQuery("SELECT type FROM " + TABLE_NAME, null);
while (cursor.moveToNext()){
String typeExtract = cursor.getString(0);
arrayList.add(typeExtract);
}
return arrayList;
}
I also learned that :
"SELECT type FROM " returns the type column from the database. I can add other columns just by adding their name : "SELECT type, marque FROM " for instance.
cursor.getString(0) the 0 is the column index for the extraction. I have only one column in my example so it has to be 0 (and not column 2, the column index inside the database)...
Thanks for the help!
I know that sounds weird.
So in my MainActivity am declaring an Array of the object SongInfo which looks like this:
class SongInfo {
lateinit var title: String
lateinit var contentId: String
lateinit var filepath: String
}
This is how I am declaring the Array in my MainActivity:
lateinit var songInfo: Array<SongInfo?>
So, now when I press a button, the listener of this button executes this:
searchButton.setOnClickListener {
val cursor = contentResolver.query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
arrayOf(
"_id",
"_data",
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.DURATION
),
"is_music == 1",
null, null
)
songInfo = arrayOfNulls(cursor!!.count)
for (index in songInfo.indices) {
songInfo[index] = SongInfo()
Log.d(tag, "searchButton: $index")
}
adapter = listMusicService.listMusic(cursor)
adapter.notifyDataSetChanged()
}
The ListMusicService class looks like this:
class ListMusicService(val context: Context, private var adapter: ArrayAdapter<Any>) {
private val tag = "MusicShare/ListMusicService"
fun listMusic(cursor: Cursor): ArrayAdapter<Any> {
val activity = MainActivity()
adapter.clear()
val songInfo = arrayOfNulls<SongInfo>(cursor.count)
var duration: Double
var index = 0
while (cursor.moveToNext()) {
duration = ((cursor.getDouble(4) / 600).roundToInt() / 100).toDouble()
adapter.add(cursor.getString(3) + ": " + cursor.getString(2) + " (" + duration + ")")
val filepath = File(cursor.getString(1))
Log.d(tag, "searchMusic: writing songInfo")
songInfo[index] = SongInfo()
songInfo[index]!!.title = filepath.name
songInfo[index]!!.filepath = filepath.absolutePath
activity.songInfo[index]!!.filepath = filepath.absolutePath
songInfo[index]!!.contentId = cursor.getString(0)
index++
}
return adapter
}
}
Pressing the searchButton now causes a kotlin.UninitializedPropertyAccessException: lateinit property songInfo has not been initialized.
But I don't understand why because in the listener method of searchButton I'm initializing every object of the array. Does anybody know why this happens and maybe what goes wrong?
EDIT: Creating the ListMusicService:
val listMusicService = ListMusicService(this, adapter)
You are creating a new object of MainActivity
val activity = MainActivity()
which is just an empty object, instead you need to pass this as an instance of MainAcitiy to listMusic method and use it.
ListMusicService class already taking a context object so seems like you are passing the activity's instance (no code about it), use the existing adapter instance of MainAcitivty.
// somewhere in main activity
val listMusicService = ListMusicService(this, adapter)
// inside searchButton.setOnClickListener
adapter = listMusicService.listMusic(cursor)
adapter.notifyDataSetChanged()
In ListMusicService
fun listMusic(cursor: Cursor): ArrayAdapter<Any> {
adapter.clear()
val songInfo = arrayOfNulls<SongInfo>(cursor.count)
var duration: Double
var index = 0
while (cursor.moveToNext()) {
duration = ((cursor.getDouble(4) / 600).roundToInt() / 100).toDouble()
adapter.add(cursor.getString(3) + ": " + cursor.getString(2) + " (" + duration + ")")
val filepath = File(cursor.getString(1))
Log.d(tag, "searchMusic: writing songInfo")
songInfo[index] = SongInfo()
songInfo[index]!!.title = filepath.name
songInfo[index]!!.filepath = filepath.absolutePath
activity.songInfo[index]!!.filepath = filepath.absolutePath
songInfo[index]!!.contentId = cursor.getString(0)
index++
}
return adapter
}
I am new to developing apps with android studio, and I decided to make an app to edit the phone numbers of my phone contacts as my first test app.
I use a class to get information about all the contacts that I have on my cell phone, then I have created a listview where I show the contact's name, ID, avatar and registered phone numbers.
The information has been gotten from the ContactsContract.Contacts table. This all works fine, so far.
But now I have to edit the phone numbers of all the contacts, but I don't know exactly how to do it. I've been going through the Android devs documentation but I can't get anything that can help me. I don't want to use Intent in this case.
I have this kotlin class that I use to get the information of all contacts is this:
#file:Suppress("unused")
package com.example.uimx
import android.Manifest
import android.content.ContentUris
import android.content.Context
import android.net.Uri
import android.provider.ContactsContract
import androidx.annotation.RequiresPermission
#RequiresPermission(Manifest.permission.READ_CONTACTS)
fun Context.isContactExists(
phoneNumber: String
): Boolean {
val lookupUri = Uri.withAppendedPath(
ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
Uri.encode(phoneNumber)
)
val projection = arrayOf(
ContactsContract.PhoneLookup._ID,
ContactsContract.PhoneLookup.NUMBER,
ContactsContract.PhoneLookup.DISPLAY_NAME
)
contentResolver.query(lookupUri, projection, null, null, null).use {
return (it?.moveToFirst() == true)
}
}
#RequiresPermission(Manifest.permission.READ_CONTACTS)
#JvmOverloads
fun Context.retrieveAllContacts(
searchPattern: String = "",
retrieveAvatar: Boolean = true,
limit: Int = -1,
offset: Int = -1
): List<ContactData> {
val result: MutableList<ContactData> = mutableListOf()
contentResolver.query(
ContactsContract.Contacts.CONTENT_URI,
CONTACT_PROJECTION,
if (searchPattern.isNotBlank()) "${ContactsContract.Contacts.DISPLAY_NAME_PRIMARY} LIKE '%?%'" else null,
if (searchPattern.isNotBlank()) arrayOf(searchPattern) else null,
if (limit > 0 && offset > -1) "${ContactsContract.Contacts.DISPLAY_NAME_PRIMARY} ASC LIMIT $limit OFFSET $offset"
else ContactsContract.Contacts.DISPLAY_NAME_PRIMARY + " ASC"
)?.use {
if (it.moveToFirst()) {
do {
val contactId = it.getLong(it.getColumnIndex(CONTACT_PROJECTION[0]))
val name = it.getString(it.getColumnIndex(CONTACT_PROJECTION[2])) ?: ""
val hasPhoneNumber = it.getString(it.getColumnIndex(CONTACT_PROJECTION[3])).toInt()
val phoneNumber: List<String> = if (hasPhoneNumber > 0) {
retrievePhoneNumber(contactId)
} else mutableListOf()
val avatar = if (retrieveAvatar) retrieveAvatar(contactId) else null
result.add(ContactData(contactId, name, phoneNumber, avatar))
} while (it.moveToNext())
}
}
return result
}
private fun Context.retrievePhoneNumber(contactId: Long): List<String> {
val result: MutableList<String> = mutableListOf()
contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
"${ContactsContract.CommonDataKinds.Phone.CONTACT_ID} =?",
arrayOf(contactId.toString()),
null
)?.use {
if (it.moveToFirst()) {
do {
result.add(it.getString(it.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)))
} while (it.moveToNext())
}
}
return result
}
private fun Context.retrieveAvatar(contactId: Long): Uri? {
return contentResolver.query(
ContactsContract.Data.CONTENT_URI,
null,
"${ContactsContract.Data.CONTACT_ID} =? AND ${ContactsContract.Data.MIMETYPE} = '${ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE}'",
arrayOf(contactId.toString()),
null
)?.use {
if (it.moveToFirst()) {
val contactUri = ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI,
contactId
)
Uri.withAppendedPath(
contactUri,
ContactsContract.Contacts.Photo.CONTENT_DIRECTORY
)
} else null
}
}
private val CONTACT_PROJECTION = arrayOf(
ContactsContract.Contacts._ID,
ContactsContract.Contacts.LOOKUP_KEY,
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,
ContactsContract.Contacts.HAS_PHONE_NUMBER
)
data class ContactData(
val contactId: Long,
val name: String,
val phoneNumber: List<String>,
val avatar: Uri?
)
I have a button prepared that receives the click event and calls a function that would have the script to replace all the phone numbers of all the contacts, for new phone numbers that I will define for each contact.
I have this next code that I got on the internet but I can't get it to work in my app.
private int updateContactPhoneByID(long rawContactId)
{
int ret = 0;
ContentResolver contentResolver = getContentResolver();
// Update data table phone number use contact raw contact id.
if(rawContactId > -1) {
// Update mobile phone number.
updatePhoneNumber(contentResolver, rawContactId, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE, "66666666666666");
// Update work mobile phone number.
updatePhoneNumber(contentResolver, rawContactId, ContactsContract.CommonDataKinds.Phone.TYPE_WORK_MOBILE, "8888888888888888");
// Update home phone number.
updatePhoneNumber(contentResolver, rawContactId, ContactsContract.CommonDataKinds.Phone.TYPE_HOME, "99999999999999999");
ret = 1;
}else
{
ret = 0;
}
return ret;
}
/* Update phone number with raw contact id and phone type.*/
private void updatePhoneNumber(ContentResolver contentResolver, long rawContactId, int phoneType, String newPhoneNumber)
{
// Create content values object.
ContentValues contentValues = new ContentValues();
// Put new phone number value.
contentValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, newPhoneNumber);
// Create query condition, query with the raw contact id.
StringBuffer whereClauseBuf = new StringBuffer();
// Specify the update contact id.
whereClauseBuf.append(ContactsContract.Data.RAW_CONTACT_ID);
whereClauseBuf.append("=");
whereClauseBuf.append(rawContactId);
// Specify the row data mimetype to phone mimetype( vnd.android.cursor.item/phone_v2 )
whereClauseBuf.append(" and ");
whereClauseBuf.append(ContactsContract.Data.MIMETYPE);
whereClauseBuf.append(" = '");
String mimetype = ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE;
whereClauseBuf.append(mimetype);
whereClauseBuf.append("'");
// Specify phone type.
whereClauseBuf.append(" and ");
whereClauseBuf.append(ContactsContract.CommonDataKinds.Phone.TYPE);
whereClauseBuf.append(" = ");
whereClauseBuf.append(phoneType);
// Update phone info through Data uri.Otherwise it may throw java.lang.UnsupportedOperationException.
Uri dataUri = ContactsContract.Data.CONTENT_URI;
// Get update data count.
int updateCount = contentResolver.update(dataUri, contentValues, whereClauseBuf.toString(), null);
}
How to make the above script work to update the correct contact table with the information I have.
I think you have a confusion about contactId and rawContactId.
When you read all the contacts from the device, you're getting the contactId of that contact, but the updateContactPhoneByID method you're trying to use is expecting a rawContactId which is different.
In a nutshell, every Contact in the ContactsContract.Contacts table is comprised out of multiple RawContacts each is usually synced by some different app or account (e.g. one RawContact from your personal Google account, another RawContact from your work Google account, another one from Whatsapp, and one from Yahoo), the details from ALL these RawContacts are join to make up a single contact profile.
I'm not sure how you want the edit to work, if a contact has multiple phone numbers, do you want to replace ALL those phones with a single new phone number, or do you allow the user to type multiple phones in your edit screen?
Anyway, here's a small kotlin function that takes a contactId and an existing phone number X and replaces that single number with a new one.
I hope you can adapt it to your needs.
private fun updatePhone(contactId:Long, existingNumber:String, newNumber:String) {
val contentValues = ContentValues()
contentValues.put(Phone.NUMBER, newNumber)
val where = Data.CONTACT_ID + "=?" + " AND " + Data.MIMETYPE + "=?" + " AND " + Phone.NUMBER + "=?"
val whereArgs = arrayOf<String>((contactId).toString(), Phone.CONTENT_ITEM_TYPE, existingNumber)
contentResolver.update(Data.CONTENT_URI, contentValues, where, whereArgs)
}
Note that the existingNumber param must match the string in the ContactsContract DB exactly.
so I'm new to realm data base and I'm trying to show the data that the user wrote throw an Edit text and show it in a Textview..
My realm class
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
import io.realm.annotations.RealmClass
#RealmClass
open class GoodStudents : RealmObject(){
#PrimaryKey
var id: Long = 0
var name : String? = null
var grade : Int? = null
}
Main activity code
Realm.init(this)
val convig = RealmConfiguration.Builder()
.name("GoodStudents").build()
val realm = Realm.getInstance(convig)
realm.beginTransaction()
count = realm.where(GoodStudents::class.java).findAll().size
val goodStudents = realm.createObject(GoodStudents::class.java, count+1)
goodStudents.name = name.text.toString()
goodStudents.grade
realm.commitTransaction()
val readData = realm.where(GoodStudents::class.java).findAll()
saveButton.setOnClickListener {
Toast.makeText(this,"Data is saved", Toast.LENGTH_LONG).show()
var text = text.text
readData.forEach { save ->
save.name = text as String?
}
}
P.C. Java code is acceptable..
so I found out that writing this code will work
saveButton.setOnClickListener {
val convig = RealmConfiguration.Builder()
.name("GoodStudents").build()
val realm = Realm.getInstance(convig)
realm.beginTransaction()
count = realm.where(GoodStudents::class.java).findAll().size
val goodStudents = realm.createObject(GoodStudents::class.java, count+1)
goodStudents.name = name.text.toString()
goodStudents.grade = grade.text.toString().toInt()
val readData = realm.where(GoodStudents::class.java).findAll()
readData.forEach { save ->
text.text = "" + save.name + ": " + goodStudents.grade
}
realm.commitTransaction()
}
What I'm trying to achieve is to add shortcut to my app in android book contact details, similar to what whatsapp is doing.
I've been following this tutotial: http://blogs.quovantis.com/syncing-contacts-with-an-android-application-2/ and it works well but the author doesn't show how to pass data from contact details to ViewingActivity: https://github.com/ajkh35/ContactsDemo/blob/master/app/src/main/java/com/example/ajay/contacts_4/ViewingActivity.java
There was some comments below the article but no specific answer from the author, can't find anything useful in
Uri data = getIntent().getData(); //content://com.android.contacts/data/1169
List<String> params = data.getPathSegments();
String first = params.get(0);
String second = params.get(1);
there is some number passed in second param but it's not CONTACT_ID or RAW_CONTACT_ID. Any help?
Ok, so it seems the Uri you're getting from the Contacts app is a Data uri.
Data rows contain info about a specific data-item (like a phone number or an email) of a specific RawContact, so a single Data row "belongs" to a single RawContact which "belongs" to a single Contact.
Luckily, the ContactsContract API allows for implicit joins when querying the Data table, so you can do something like this:
Uri dataUri = getIntent().getData(); //content://com.android.contacts/data/1169
String[] projection = new String[]{
Data.CONTACT_ID,
Data.RAW_CONTACT_ID,
Data.DISPLAY_NAME,
Data.MIMETYPE,
Data.DATA1};
Cursor cur = getContentResolver().query(dataUri, projection, null, null, null);
cur.moveToFirst(); // there should always be exactly one result, since we have a specific data uri here
Log.i("Contact Info", "Got info: id=" + cur.getLong(0) + ", raw-id=" + cur.getLong(1) + ", " + cur.getString(2) + ", " + cur.getString(3) + ", " + cur.getString(4));
cur.close();
I know this is a very late response but checkout the following code.
class MessageActivity : AppCompatActivity() {
private val TAG: String = javaClass.simpleName
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_message)
if(intent != null && intent.data != null) {
Log.e(TAG, intent.data.toString())
var contactName = ""
val cursor = contentResolver.query(intent.data!!,
arrayOf(ContactsContract.Data.DATA1,ContactsContract.Data.DATA2,ContactsContract.Data.DATA3),
null,null,null)
if(cursor != null && cursor.moveToFirst()) {
do{
Log.e(TAG, cursor.getString(cursor
.getColumnIndexOrThrow(ContactsContract.Data.DATA1)))
contactName = cursor.getString(cursor
.getColumnIndexOrThrow(ContactsContract.Data.DATA2))
Log.e(TAG, contactName)
Log.e(TAG, cursor.getString(cursor
.getColumnIndexOrThrow(ContactsContract.Data.DATA3)))
}while (cursor.moveToNext())
cursor.close()
}
messaging_text.text = getString(R.string.messaging) + " $contactName"
}
}}
So when you register a contact you set some Data1, Data2 and Data3 values. Data3 is what gets displayed in the contacts. You can set Data1 and Data2 some value you like and then retrieve it like in the code I mentioned above.
You can also checkout my blog here. Look for the "Sync Service" section, towards the end you will find the MessageActivity.
Thanks & regards