Sunday 7 December 2014

Dialog

In the Android tutorial, it gives some examples to Instantiate AlertDialog.Builder like this.
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
But getActivity() is a method of the Fragment class, can not apply to everywhere. 

The correct way to do it is use
AlertDialog.Builder builder = new AlertDialog.Builder(this);
or when calling from an inner class, use
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
MainActivity here is your main activity name.

This is one example how to build a single selection dialog.
    private String[]fruits = new String[]{"荔枝","葡萄","栗子","西瓜"};
    private TextView dia_schsres = null;
protected void onCreateDialog() {
                Dialog schDia = new AlertDialog.Builder(ExampleActivity.this);     //AlertDialog.Builder or AlertDialog or Dialog
                    schDia.setIcon(R.drawable.ic_launcher).setTitle("Background").
                        setItems(fruits,new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dia, int which) {
                                dia_schsres.setText(fruits[which]);
                            }
                        }).setNegativeButton("Cancel",new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dia, int which) {
                        dia.dismiss();
                    }
                }).create();
}

Call Camera or Gallery Intent to return a photo

1.1  Gallery
Step 1: Start Intent
Start from internal storage.
static final int GALLERY = 1;  // The request code
… 
private void pickPhoto() {
               Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setType("image/*");
                startActivityForResult(intent, GALLERY);
}

Or start from external storage.
                Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                intent.setType("image/*");
                startActivityForResult(intent, GALLERY);  

Step 2: Activity callback
  1. Method 1: Use MediaStore to get the image.
    protected void onActivityResult(int requestCode, int resultCode,
                                    Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        if (requestCode == GALLERY) {     //check the request code, to find the correct request
        if (resultCode == RESULT_OK) {
            Uri photoUri = intent.getData();
            if (photoUri != null) {
                try {
                    Bitmap m_bmOCRBitmap = MediaStore.Images.Media.getBitmap(this
                            .getContentResolver(), photoUri);
                    Drawable drawable = new BitmapDrawable(this.getResources(), m_bmOCRBitmap);
                    gridview.setBackground(drawable);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        }
    }
photoUri is something like this, “content://media/external/images/media/3951”or content://com.android.providers.media.documents/document/image:3951”(Android 4.4). It represents the photo, need to use ContentResolver to get the file.
Note: setBackground() is for API level 16 above, for API level less than 16, please use setBackgroundDrawable() instead.

Method 2: Use MediaStore to get the image.
                    String[] filePathColumn = {MediaStore.Images.Media.DATA};
                    Cursor cursor = getContentResolver().query(photoUri, filePathColumn, null, null, null);
                    cursor.moveToFirst();
                    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                    String filePath = cursor.getString(columnIndex);
                    cursor.close();
                    m_bmOCRBitmap = BitmapFactory.decodeFile(filePath);

Step 3: Get permission
Should get the permission to read from external memory.
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

1.2  Camera
Step 1: Start Intent
static final int CAMERA = 1337;  // The request code
                Intent cameraIntent = new Intent(
                        android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(cameraIntent, CAMERA);

If want to save the captured file or want to crop the file, it needs to start as below.
    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
    /*create instance of File with name img.jpg*/
    File file = new File(Environment.getExternalStorageDirectory()+File.separator + "img.jpg");
    /*put uri as extra in intent object*/
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
    /*start activity for result pass intent as argument and request code */
    startActivityForResult(intent, CAMERA);

Step 2: Activity callback
    protected void onActivityResult(int requestCode, int resultCode,
                                    Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        if (requestCode == CAMERA) {     //check the request code, to find the correct request
            if (resultCode == RESULT_OK) {
                try {
                    Bitmap photo = (Bitmap) intent.getExtras().get("data");
                    //ByteArrayOutputStream stream = new ByteArrayOutputStream();
                    //photo.compress(Bitmap.CompressFormat.PNG, 100, stream);
                    //byte[] byteArray = stream.toByteArray();
                    //strAttachmentCoded = new String(byteArray);
                    Drawable drawable = new BitmapDrawable(this.getResources(), photo);
                    gridview.setBackground(drawable);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
Note: setBackground() is for API level 16 above, for API level less than 16, please use setBackgroundDrawable() instead.

Step 3: AndroidManifest.xml
Enable camera and get permission.
    <uses-permission android:name="android.permission.CAMERA" />

    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />



1.3  Croping image for small size return data
Step 1: Start Intent
                        static final int CROP = 3;  // The request code
                        Intent cropIntent = new Intent("com.android.camera.action.CROP");
                        cropIntent.setDataAndType(photoUri, "image/*");
                        cropIntent.putExtra("outputX", 96);
                        cropIntent.putExtra("outputY", 96);
                        cropIntent.putExtra("aspectX", 1);
                        cropIntent.putExtra("aspectY", 1);
                        cropIntent.putExtra("scale", true);
                        cropIntent.putExtra("return-data", true);   // For small size photo only
                        startActivityForResult(cropIntent, CROP);

Step 2: Activity callback
    protected void onActivityResult(int requestCode, int resultCode,
                                    Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        if (requestCode == CROP) {     //check the request code, to find the correct request
            if (resultCode == RESULT_OK) {
                try {
                    Bitmap photo = (Bitmap) intent.getExtras().get("data");
                    Drawable drawable = new BitmapDrawable(this.getResources(), photo);
                    gridview.setBackground(drawable);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
Note: setBackground() is for API level 16 above, for API level less than 16, please use setBackgroundDrawable() instead.

1.3  Croping image for large size return data
Step 1: Create a new file and get the Uri

    private Uri getTempUri() {
        return Uri.fromFile(getTempFile());
    }

    private File getTempFile() {
        if (isSDCARDMounted()) {
            File f = new File(Environment.getExternalStorageDirectory(),"Picture.jpg");   //Path should be the existing folder path
            try {
                f.createNewFile();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                Log.v("log_tag", "get file failed!");
            }
            return f;
        } else {
            return null;
        }
    }

    private boolean isSDCARDMounted(){
        String status = Environment.getExternalStorageState();
        if (status.equals(Environment.MEDIA_MOUNTED))
            return true;
        return false;
    }

Step 2: Start Intent
                        static final int CROP = 3;  // The request code
                        Intent cropIntent = new Intent("com.android.camera.action.CROP");
                        cropIntent.setDataAndType(photoUri, "image/*");
                        cropIntent.putExtra("scale", true);
                        cropIntent.putExtra("return-data", false);   // For large size photo
                        cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
                        cropIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
                        startActivityForResult(cropIntent, CROP);

Step 3: Activity callback
    protected void onActivityResult(int requestCode, int resultCode,
                                    Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        if (requestCode == CROP) {     //check the request code, to find the correct request
            if (resultCode == RESULT_OK) {
                File tempFile = getTempFile();
                String temppath = tempFile.getPath();
                //FileInputStream fileis = null;
                Log.v("log_tag", "File path:" + temppath);
                try {
                    //fileis = new FileInputStream(tempFile);
                    Bitmap m_bmp = BitmapFactory.decodeFile(temppath);   // Get bmp from file path
                    //Bitmap m_bmp = BitmapFactory.decodeStream(fileis);   // Get bmp from file input stream
                    Drawable drawable = new BitmapDrawable(this.getResources(), m_bmp);
                    Log.v("log_tag", "first image : "+ m_bmp);
                    gridview.setBackground(drawable);
                    Log.v("log_tag", "Change background");
                    //Now you can upload this bitmap to server or do something else.
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
Note: setBackground() is for API level 16 above, for API level less than 16, please use setBackgroundDrawable() instead.

Step 4: AndroidManifest.xml
Enable camera and get permission.

   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


Environment setup for Internal/Private APIs

Internal APIs are located in package com.android.internal. 
When you are developing using Android SDK you reference one very important jar file called android.jar. It’s located in Android SDK platform directory SDK_DIR/platforms/platform-X/android.jar (where X is API level, it can be 5 or 10 or any other number). This android.jar has all classes from com.android.internal removed, and all classes, enums, fields and methods marked with @hide removed as well.
There are several ways to use internal APIs. 
1. Get Internal APIs
Method 1: Get from open source
Here is the link where to download all versions of android source code.
http://grepcode.com/project/repository.grepcode.com/java/ext/com.google.android/android/
For example download, android-4.4.2_r1.jar, go to step 3.

Method 2: Get from device
https://devmaze.wordpress.com/2011/01/18/using-com-android-internal-part-2-hacking-around/

2. Creating classes.jar
(1) Zip the code to classes.zip (Don’t MAC OS native compression tools, use Betterzip)
(2) Change the extension to .jar.

3. Add to ADT
(1) Project properties->Java Build Path->Libraries->Add External JARs
(2) Order and Export, move the external Jar up than android.jar

Reference:

Some open source launcher:
https://github.com/CyanogenMod/android_packages_apps_Trebuchet/tree/cm-10.2
https://github.com/tjlian616/Android-Launcher2-Standalone
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android-apps/4.0.1_r1/com/android/launcher2/Launcher.java

https://github.com/AnderWeb/android_packages_apps_Launcher