Wednesday 1 July 2015

Debugging Android Apps on an Actual Device.

Hi!

Before I start to share my experience in setting up my Samsung Galaxy Note II with IntelliJ IDEA (my IDE), kindly find other resources which might help you connect your android device to your IDE.

http://developer.android.com/tools/device.html

http://developer.android.com/tools/extras/oem-usb.html

Here we go!

There are essentially 3 things you need to do:
  1. Enable Debugging Mode on your android phone.
  2. Install usb drivers for adb on your computer.
  3. Amend ApplicationManifest.xml file (IntelliJ IDEA) or build.gradle file (Android Studio)

Step 1 - Enabling Debugging Mode

The Developer options is required to enable Debugging Mode, however, in Android 4.2 and above it is hidden by default.

In Android 4.3, go to Settings > More > About device and tap Build number seven times to make the Developer options visible. Return to the previous screen to find the Developer options visible at the bottom.

Ensure the Developer options is ON and USB debugging enabled 

Step 2 - Install USB Driver

Kindly refer to the link http://developer.android.com/tools/extras/oem-usb.html for usb driver specific to your phone or check your manufacturers website.

In my case, although Samsung was listed on the developer.android.com page, I use Samsung Kies to install the required drivers.

Connect your phone to your computer through a usb cable and Windows would automatically install basic usb drivers.
Launch Samsung Kies on your computer then select Tools > Reinstall device driver to install the all drivers.
On your computer, click on the Start icon then type "Device Manager". Select Device Manager from the list.
Your device should be identified under the Portable Devices with no warning.

You may also find an RSA key message on your phone asking to allow debugging through this computer, just accept that.


Step 3 - Amend AndroidManifest

In the ApplicationManifest.xml file, add android:debuggable ="true" in the <application> element and suppress the warning by adding xmlns:tools="http://schemas.android.com/tools" in the <manifest> element.

In build.gradle file, the approach is slightly different (for those using Android Studio).

Kindly find an illustration below.


ApplicationManifest.xml file

<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="course.examples.maplocation" android:versionCode="1" android:versionName="1.0" > <application android:debuggable="true" ... >

Build.gradle file

android { buildTypes { debug { debuggable true }




That's it!

You should find your device listed when you try to run your application, however, ensure in your application configuration, the Target Device is either set to Show chooser dialog or USB device else your application would run on the default emulator.

A physical Samsung Note II device shown on the list of devices

Thanks for finding the time to read this.

If you find this article helpful, share it, follow me and drop a comment - you could also suggest other ways to improve our lives just in case I missed anything. :)

Hearty Regards

Thursday 25 June 2015

C Programming - FILE "rw+" Mode Not Working

Hi!

I have decided to share a project which I created in C language just for some demonstration.

There is a particular scenario addressed in this code, which has to do with overwriting some information in the existing filestream.

In C, you have the syntax as fopen("myfile", "rw+" ) - or "r+w" in other models - to open the file for Read and Write operation then you use the fseek() method to move the file pointer position in file and state the write size to overwrite that record.

However, I discovered that Visual Studio does not allow you to open a file in "rw+" mode and neither does Codeblocks. Probably earlier compilers supported this mode, which I did not experiment.

Should this be the end of the world as far as my project is concerned? Absolutely not!

Find a workaround below - I opened the FILE pointer in "a+" mode and modified the code to refer to the last corresponding record to my test criteria.

Kindly review, share and comment - we all will learn.


#include <stdio.h>
#include <string.h>
#define clrscr() system("cls")
struct customer {
 long no;
 char name[30];
 double bal;
};

struct transaction {
 char type;
 long custno;
 double amount;
 double prvbal;
};

void rectrans() {
 FILE *fp, *fpt;
 long custNumber, size = sizeof(struct customer), sizet = sizeof(struct transaction);
 double custBalance;
 char custName[30];
 struct customer cust;
 struct transaction trnx;
 char flag = 'y', transtype;
 unsigned int recordfound;
 double namount;


 if ((fp = fopen("customer", "a+")) == NULL) {
  printf("\nSorry, server cannot be accessed at this time.\n");
  fclose(fp);
  return;
 }

 if ((fpt = fopen("transaction", "a+")) == NULL) {
  printf("\nSorry, server cannot be accessed at this time.\n");
  fclose(fpt);
  return;
 }
 while (flag == 'y') {
  clrscr();

  recordfound = 0;
  printf("\nEnter customer account number: ");
  scanf(" %ld", &custNumber);

  while ((fread(&cust, size, 1, fp)) != NULL) {
   // set customer Balance and Name to the last matching record.
   if (custNumber == cust.no) {
    recordfound++;
    custBalance = cust.bal;
    strcpy(custName, cust.name);
   }
  }

  if (recordfound < 1) {
   printf("\nInvalid account number.");
  }
  else {
   // Print the customer details
   printf(" %-s \nBalance: %20.2lf\n", custName, custBalance);

   // Request transaction information
   do {
    printf("\nWithdrawal or Deposit? (w/d): ");
    scanf(" %c", &transtype);
    lcase(&transtype);
   } while (transtype != 'w' && transtype != 'd');

   printf("\nEnter transaction amount: ");
   scanf(" %lf", &namount);

   switch (transtype) {
   case 'd':
    printf("\n\Deposit processing ...");

    // preloading transaction data
    trnx.custno = custNumber;
    trnx.prvbal = custBalance;
    trnx.amount = namount;
    trnx.type = 'D';

    // preloading customer data
    cust.bal = custBalance + trnx.amount;
    strcpy(cust.name, custName);
    cust.no = custNumber;

    // write the customer transaction to transaction file
                                // and update customer file
    fseek(fp, -size, SEEK_CUR);
    fwrite(&cust, size, 1, fp);
    fwrite(&trnx, sizet, 1, fpt);
    break;
   case 'w':
    printf("\n\Withdrawal processing ...");
    if ((custBalance - namount) >= 200) {
     // retrieve information relevant for trnx from cust
     trnx.custno = custNumber;
     trnx.prvbal = custBalance;
     trnx.amount = namount;
     trnx.type = 'W';
     cust.bal = custBalance - trnx.amount;
     strcpy(cust.name, custName);
     cust.no = custNumber;

     // write the customer transaction to transaction file
                                        // and update customer file
                                        // (long)(-size) typecast -size to long. 
                                        // fseek() returns position to a struct 
                                        // size backward from the current (1) cursor position.  

     fseek(fp, -size, SEEK_CUR); 
     fwrite(&cust, size, 1, fp);
     fwrite(&trnx, sizet, 1, fpt);
    }
    else {
     printf("\nInsufficient fund in this account.");
    }
    break;
   }
  }

  // rewind customer file fp to start search over for the next account. 
  rewind(fp);
  flag = 'n'; // this line stops the loop.
 }
 // close all fp and fpt
 fclose(fp);
 fclose(fpt);
 return;
}