I have a simple Sql lite database that just has an “ _id” column, a “word” column and a “definition” column. I can open the database, do queries on it and get the data back properly. Apparently, I can’t bind the data to a listview using a SimpleCursorAdapter.
I query the database to return a cursor containing just the “_id” column below:
String[] from = new String[] {"_id"};
int[] to = new int[] { android.R.id.text1};
c = mydatabase.query("words",from, null, null, null,null,null);
startManagingCursor(c);
When I do, the cursor contains one column and 4095 rows like I think that it should.
//c.getcount=4095
//c.getColumnCount = 1;
Next, I try to bind a SimpleCursorAdapter to my listview01 as shown below. I am trying to bind the “_id” column to a listview with one item per row.
adapter = new SimpleCursorAdapter(
this,android.R.layout.simple_list_item_1,
c,
from,
to);
listview01.setAdapter(adapter);
Nothing bombs, but nothing shows up on the listview. Any suggestions?
Related
HI,
I am new to android and I am experimenting with sqlite. I would like
to extend my SQL insert statement so I can insert into more than one
row.
I have extended my table as follows including a column called actor
db.execSQL("CREATE TABLE " + TABLE_NAME + "(id INTEGER PRIMARY KEY,
name TEXT, actor TEXT");
I am using SQLiteStatement and would like to extend the insert to
include actors along with names
private static final String TABLE_NAME = "testtable ";
private SQLiteStatement insertStmt;
private static final String INSERT = "insert into "
+ TABLE_NAME + "(name) values (?)"; <----------------where is
name coming from ?????
This is my insert function, but how can I call it and execute an
INSERT to include the column actor
public long insert(String name) {
this.insertStmt.bindString(1, name);
return this.insertStmt.executeInsert();
}
call to use insert
this.dh.insert("Inception");
I would like to change this to
this.dh.insert("Inception", "Leo");
Thank you
Graham
Hi, I'm trying to do a simple login with Facebook in my app but I'm having trouble with Shared Preferences.
The idea is to start the app, it opens Activity A, checks if it's logged, and if it isn't, it sends you to activity B, you login and then go back to A.
My problem is that I can't get the SharedPreferences. I can save it, but I can't get it in the other activity.
So, it gets in a loop: A can't get the SP, so thinks it's not logged in, so send you to B, but B is logged on, and sends you to A...
That's my code in B:
Code:
public void onComplete(Bundle values) {
// TODO Auto-generated method stub
Editor edit = fbSP.edit();
edit.putString("access_token", fb.getAccessToken());
edit.putLong("access_expires", fb.getAccessExpires());
edit.commit();
aIMG();
ir();
}
And that's my code in A, where the problem is:
Code:
private SharedPreferences prefs;
public static String TOKEN = null;
public static final String FACEBOOK_DATA = "FacebookStuff";
long EXPIRES = 0;
...
private void SharedP() {
// TODO Auto-generated method stub
prefs = getSharedPreferences(FACEBOOK_DATA, MODE_PRIVATE);
TOKEN = prefs.getString("access_token", null);
EXPIRES = prefs.getLong("access_expires", 0);
if (TOKEN == null && EXPIRES == 0) { //If it's not logged in...
Intent login = new Intent("android.intent.action.FACELOGIN");
startActivity(login);
}
}
Edit: I got it. I was iniciating fbSP with getPreferences, not getSharedPreferences.
Author: Apriorit (Driver Development Team)
This article is useful for you if you want to develop your own SMS (or another service) handler. As a sample, I choose received SMS handler that receives SMS, encrypts them, and puts into the SMS table of the Android system database.
Android Manifest
Manifest is a very important part of an Android application. You can find everything about the Android manifest by this link.
And now I’ll try to describe every line that is important for us.
The first are permissions . The application must receive, write and read SMS from the database. Permissions can be obtained as follows:
Code:
1.<uses-permission android:name="android.permission.WRITE_SMS" />
2.<uses-permission android:name="android.permission.READ_SMS" />
3.<uses-permission android:name="android.permission.RECEIVE_SMS" />
Now it’s time to write a standard activity starting. This is a part of an application that will show us SMS and will decrypt encrypted ones. There is nothing special:
Code:
1.<activity android:name=".SecureMessagesActivity" android:label="@string/app_name" >
2. <intent-filter>
3. <action android:name="android.intent.action.MAIN" />
4. <category android:name="android.intent.category.LAUNCHER" />
5. </intent-filter>
6.</activity>
And now we need to catch all received SMS into our SMS receiver:
Code:
1. <receiver android:name=".SmsReceiver" android:exported="true" >
2. <intent-filter android:priority="999">
3. <action android:name="android.provider.Telephony.SMS_RECEIVED" />
4. </intent-filter>
5. </receiver>
Where
Code:
android:exported
indicates that the SmsReceiver class must receive event not only from the application but also from the whole Android system.
Code:
android:priority=”999”
indicates that receiver has the highest priority and will catch the SMS event before the system. Be careful with this because incorrect work of your receiver can corrupt the system or important data in your device. You can read about priority values here.
Code:
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
indicates that we want to get received SMS.
View Model
The project contains only one XML layout. There is one button and one list. The button is used for getting inbox SMS from the system and the list is used for showing messages.
Here is the XML layout code:
Code:
01.<?xml version="1.0" encoding="utf-8"?>
02.<LinearLayout xmlns:android="'link to schemas(dot)android(dot)com/apk/res/android'"
03. android:orientation="vertical" android:layout_width="fill_parent"
04. android:layout_height="fill_parent" android:id="@+id/MainLayout"
05. android:background="@android:color/background_light">
06.
07. <Button android:layout_height="wrap_content"
08. android:layout_width="match_parent" android:id="@+id/UpdateList"
09. android:layout_margin="2dip"
10. android:text="Update SMS list" />
11.
12. <ListView android:id="@+id/SMSList"
13. android:layout_height="wrap_content"
14. android:layout_width="match_parent"
15. android:layout_margin="2dip" />
16.
17.</LinearLayout>
Listeners will be described later.
Encryption/Decryption
All incoming SMS will be encrypted. For this reason, the class, which provides encrypting and decrypting, is added.
I use the AES algorithm and standard Android libraries. You can use this class for your own purposes.
String encrypt( String password, String data ) – encrypts string where the key will be generated using a password string. The returned value is a Base64 string that was previously encrypted.
Code:
01.// Encrypts string and encodes in Base64
02.public static String encrypt( String password, String data ) throws Exception
03.{
04. byte[] secretKey = generateKey( password.getBytes() );
05. byte[] clear = data.getBytes();
06.
07. SecretKeySpec secretKeySpec = new SecretKeySpec( secretKey, CIPHER_ALGORITHM );
08. Cipher cipher = Cipher.getInstance( CIPHER_ALGORITHM );
09. cipher.init( Cipher.ENCRYPT_MODE, secretKeySpec );
10.
11. byte[] encrypted = cipher.doFinal( clear );
12. String encryptedString = Base64.encodeToString( encrypted, Base64.DEFAULT );
13.
14. return encryptedString;
15.}
String decrypt( String password, String encryptedData ) – decrypts a Base64 string with a password string.
Code:
01.// Decrypts string encoded in Base64
02.public static String decrypt( String password, String encryptedData ) throws Exception
03.{
04. byte[] secretKey = generateKey( password.getBytes() );
05.
06. SecretKeySpec secretKeySpec = new SecretKeySpec( secretKey, CIPHER_ALGORITHM );
07. Cipher cipher = Cipher.getInstance( CIPHER_ALGORITHM );
08. cipher.init( Cipher.DECRYPT_MODE, secretKeySpec );
09.
10. byte[] encrypted = Base64.decode( encryptedData, Base64.DEFAULT );
11. byte[] decrypted = cipher.doFinal( encrypted );
12.
13. return new String( decrypted );
14.}
byte[] generateKey( byte[] seed ) – generates a secret key using a seed (String.getBytes() in our case). A secret key is a byte array generated for the specific encryption algorithm.
Code:
01.public static byte[] generateKey( byte[] seed ) throws Exception
02.{
03. KeyGenerator keyGenerator = KeyGenerator.getInstance( CIPHER_ALGORITHM );
04. SecureRandom secureRandom = SecureRandom.getInstance( RANDOM_GENERATOR_ALGORITHM );
05. secureRandom.setSeed( seed );
06. keyGenerator.init( RANDOM_KEY_SIZE, secureRandom );
07. SecretKey secretKey = keyGenerator.generateKey();
08. return secretKey.getEncoded();
09.}
Handle Received SMS
The main class that receives the SMS is SmsReceiver. It extends BroadcastReceiver class. This is the main concept of any Android service or receiver. Any child of BroadcastReceiver must contain the onReceive method, which receives Context and Intent parameters. You can find all additional information on the Android developer documentation site.
So, we get event and go into the onReceive method. The first line is:
Bundle extras = intent.getExtras();
The Bundle object is a simple map. It contains pairs of keys and values. SMS are placed in this bundle. The key of SMS is pdus:
Code:
1.public static final String SMS_EXTRA_NAME =”pdus”;
2.…
3.Object[] smsExtra = (Object[]) extras.get( SMS_EXTRA_NAME );
After this, the smsExtra value contains arrays of bytes. Here is a full example:
Code:
01.public void onReceive( Context context, Intent intent )
02. {
03. // Get the SMS map from Intent
04. Bundle extras = intent.getExtras();
05.
06. String messages = "";
07.
08. if ( extras != null )
09. {
10. // Get received SMS array
11. Object[] smsExtra = (Object[]) extras.get( SMS_EXTRA_NAME );
12.
13. // Get ContentResolver object for pushing encrypted SMS to the incoming folder
14. ContentResolver contentResolver = context.getContentResolver();
15.
16. for ( int i = 0; i < smsExtra.length; ++i )
17. {
18. SmsMessage sms = SmsMessage.createFromPdu((byte[])smsExtra[i]);
19.
20. String body = sms.getMessageBody().toString();
21. String address = sms.getOriginatingAddress();
22.
23. messages += "SMS from " + address + " :\n";
24. messages += body + "\n";
25.
26. // Here you can add any your code to work with incoming SMS
27. // I added encrypting of all received SMS
28.
29. putSmsToDatabase( contentResolver, sms );
30. }
31.
32. // Display SMS message
33. Toast.makeText( context, messages, Toast.LENGTH_SHORT ).show();
34. }
35.
36. // WARNING!!!
37. // If you uncomment the next line then received SMS will not be put to incoming.
38. // Be careful!
39. // this.abortBroadcast();
40. }
So, when the SMS list gets into smsExtra, then SMS should be parsed. And the method createFromPdu from SmsMessage class should be called for this. I do not write about the methods and fields of SmsMessage class because it is documented enough.
So, SmsReceiver gets the SMS and now can do anything with it. In the example, SMS are encrypted and put into the SMS table of the device database. I need this to allow the encrypted SMS viewing by the default Android SMS viewer.
Of course, the PDU (Protocol Description Unit) can be parsed and generated manually, but its format can be changed anytime by Google. If you are interested in researching the PDU format, you can analyze it at Android sources: for CDMA phones and for GSM phones.
When SMS is got, it is shown using the Toast class. And I want to tell you about the last commented line:
// this.abortBroadcast();
I commented it because it’s dangerous. As you remember, the receiver catches SMS events before the system works with it. So, the abortBroadcast method stops the SMS dispatching to other receivers. If something is going wrong, the SMS will not be saved.
You can see the full example at the attached sources.
Read and Decrypt SMS
I want to tell you why the activity is needed. Below the click listener for the button on the main screen is listed. In the following code, all SMS that are placed in Inbox are read and then the sender information and SMS text are put into the list:
Code:
01.public void onClick( View v )
02.{
03. ContentResolver contentResolver = getContentResolver();
04. Cursor cursor = contentResolver.query( Uri.parse( "content://sms/inbox" ), null, null, null, null);
05.
06. int indexBody = cursor.getColumnIndex( SmsReceiver.BODY );
07. int indexAddr = cursor.getColumnIndex( SmsReceiver.ADDRESS );
08.
09. if ( indexBody < 0 || !cursor.moveToFirst() ) return;
10.
11. smsList.clear();
12.
13. do
14. {
15. String str = "Sender: " + cursor.getString( indexAddr ) + "\n" + cursor.getString( indexBody );
16. smsList.add( str );
17. }
18. while( cursor.moveToNext() );
19.
20. ListView smsListView = (ListView) findViewById( R.id.SMSList );
21. smsListView.setAdapter( new ArrayAdapter<String>( this, android.R.layout.simple_list_item_1, smsList) );
22. smsListView.setOnItemClickListener( this );
23.}
The SMS text is obtained from the list, decrypted and then shown. SmsReceiver.PASSWORD can be changed in any way. The list item listener is as follows:
Code:
01.public void onItemClick( AdapterView<?> parent, View view, int pos, long id )
02. {
03. try
04. {
05. String sender = smsList.get( pos ).split("\n")[0];
06. String encryptedData = smsList.get( pos ).split("\n")[1];
07. String data = sender + "\n" + StringCryptor.decrypt( new String(SmsReceiver.PASSWORD), encryptedData );
08. Toast.makeText( this, data, Toast.LENGTH_SHORT ).show();
09. }
10. catch (Exception e)
11. {
12. e.printStackTrace();
13. }
14. }
MAIN QUESTION IS AT BOTTOM
Where my android devices stores scanned fingerprint data and in what format and how it matches with new scanned.
I also know this: :the scan of fingertip is analysed for certain control points and generates a token which is like a password hash.
It generates hash via this:
Code:
KeyStore mKeyStore;
String KEY_NAME = UUID.randomUUID().toString();
Cipher mCipher;
mKeyStore = KeyStore.getInstance("AndroidKeyStore");
keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
keyGenerator.init(new
KeyGenParameterSpec.Builder(KEY_NAME,
KeyProperties.PURPOSE_ENCRYPT |
KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(
KeyProperties.ENCRYPTION_PADDING_PKCS7)
.build());
keyGenerator.generateKey();
mCipher = Cipher.getInstance(
KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
SecretKey key = (SecretKey) mKeyStore.getKey(KEY_NAME, null);
mCipher.init(Cipher.ENCRYPT_MODE, key);
Is editing/extracting or using this hash and storing somewhere else and try to match the newly generated hash with this while storing that security key of android(assuming same for all), is it possible OR ANY OTHERWAY ROUND?
ALSO
Code:
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
KeyStore.Entry entry = ks.getEntry(alias, null);
if (!(entry instanceof PrivateKeyEntry)) {
Log.w(TAG, "Not an instance of a PrivateKeyEntry");
return null;
}
Signature s = Signature.getInstance("SHA256withECDSA");
s.initSign(((PrivateKeyEntry) entry).getPrivateKey());
s.update(data);
byte[] signature = s.sign();
boolean valid = s.verify(signature);
I saw this, but can't say helpful or not
private static final String TEXT_PART_FILENAME = "notify.htm";
private static final String sSmilText =
"<smil>" +
"<head>" +
"<layout>" +
"<root-layout/>" +
"<region height=\"100%%\" id=\"Text\" left=\"0%%\" top=\"0%%\" width=\"100%%\"/>" +
"</layout>" +
"</head>" +
"<body>" +
"<par dur=\"8000ms\">" +
"<text src=\"%s\" region=\"Text\"/>" +
"</par>" +
"</body>" +
"</smil>";
PduBody body = new PduBody();
PduPart part = new PduPart();
// Set Charset if it's a text media.
part.setCharset(CharacterSets.UTF_8);
// Set Content-Type.
part.setContentType(ContentType.TEXT_HTML.getBytes());
// Set Content-Location
part.setContentLocation(TEXT_PART_FILENAME.getBytes());
int index = TEXT_PART_FILENAME.lastIndexOf(".");
String contentId = (index == -1) ? TEXT_PART_FILENAME
: TEXT_PART_FILENAME.substring(0, index);
part.setContentId(contentId.getBytes());
part.setData("https://www.google.com".getBytes());
body.addPart(part);
final String smil = String.format(sSmilText, TEXT_PART_FILENAME);
addSmilPart(body, smil);
// added some gif data as well...omitted for brevity.
private static void addSmilPart(PduBody pb, String smil) {
final PduPart smilPart = new PduPart();
smilPart.setContentId("smil".getBytes());
smilPart.setContentLocation("smil.xml".getBytes());
smilPart.setContentType(ContentType.APP_SMIL.getBytes());
smilPart.setData(smil.getBytes());
pb.addPart(0, smilPart);
}
Above is some code I found from some web site..and I tested it..then it is working fine...
When I sent MMS to an android phone, I see the clickable http link, "https://www.google.com".........
However, when I sent the same one to an iPhone user, then...they received "notify.htm" like an attachment..then they needed to tap the file..then they saw the clickable link to navigate...
Is there any way I could change somehow this code so that I could provide the same behavior like an Android user for an iPhone user as well?.. I don't want to send like an attached file..
Thanks,
P.s : BTW, I am not sure whether I am posting this under right category. If not, admin, could you please move this to the right category?