2015年12月27日 星期日

Center text on a bitmap

Reference:

http://www.skoumal.net/en/android-how-draw-text-bitmap/

Code snippet:

Bitmap cloneMarkerBitmap = oriMarkerBitmap.copy(Bitmap.Config.ARGB_8888,true);
Canvas canvas = new Canvas(cloneMarkerBitmap);
Paint textPaint = new Paint();
textPaint.setColor(mResources.getColor(R.color.white));
textPaint.setTextSize(convertDpToPixel(12));
textPaint.setTextAlign(Paint.Align.CENTER);
textPaint.setTypeface(Typeface.DEFAULT_BOLD);

// draw text to the Canvas center
String markerNumber = Integer.toString(number);
Rect bounds = new Rect();
textPaint.getTextBounds(markerNumber, 0, markerNumber.length(), bounds);
int x = (cloneMarkerBitmap.getWidth())/2;
int y = (cloneMarkerBitmap.getHeight() + bounds.height())/2;
canvas.drawText(markerNumber, x, y, textPaint);

...............

    public float convertDpToPixel(float dp) {
        DisplayMetrics metrics = mResources.getDisplayMetrics();
        float px = dp * metrics.density;
        return px;
    }

Multi-line in EditText

Reference:
http://stackoverflow.com/questions/4233626/allow-multi-line-in-edittext-view-in-android

Code snippet:
<EditText
    android:inputType="textMultiLine" <!-- Multiline input -->
    android:lines="8" <!-- Total Lines prior display -->
    android:minLines="6" <!-- Minimum lines -->
    android:gravity="top|left" <!-- Cursor Position -->
    android:maxLines="10" <!-- Maximum Lines -->
    android:layout_height="wrap_content" <!-- Height determined by content -->
    android:layout_width="fill_parent" <!-- Fill entire width -->
    android:scrollbars="vertical" <!-- Vertical Scroll Bar -->
/>

Send SMS message and get the result

Code snippet:
public void sendSmsMessage(String phoneNumber,String message){
        SmsManager smsManager = SmsManager.getDefault();
        ArrayList<String> messageList = smsManager.divideMessage(message);
        PendingIntent mPI = PendingIntent.getBroadcast(MainEntryActivity.this, 0, new Intent("SMS_SENT"), PendingIntent.FLAG_UPDATE_CURRENT);
        ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>();
        for(int i=0;i<messageList.size();i++){
            sentIntents.add(mPI);
        }
        registerReceiver(smsSentReceiver, new IntentFilter("SMS_SENT"));
        smsManager.sendMultipartTextMessage (phoneNumber, null, messageList, sentIntents, null);
}

private BroadcastReceiver smsSentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String result = "";
            switch(getResultCode()) {
                case Activity.RESULT_OK:
                    result = "Transmission successful";
                    break;
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                    result = "Transmission failed";
                    break;
                case SmsManager.RESULT_ERROR_RADIO_OFF:
                    result = "Radio off";
                    break;
                case SmsManager.RESULT_ERROR_NULL_PDU:
                    result = "No PDU defined";
                    break;
                case SmsManager.RESULT_ERROR_NO_SERVICE:
                    result = "No service";
                    break;
            }
            Log.d(TAG, "send sms result: " + result);
        }
};

@Override
protected void onDestroy() {
        try{
            unregisterReceiver(smsSentReceiver);
        } catch(IllegalArgumentException iae){
            Log.d(TAG,"Receiver not registered");
            iae.printStackTrace();
        }
}

2015年12月16日 星期三

Install fail: Failure [INSTALL_FAILED_OLDER_SDK] for KitKat device

Reference:

https://www.reddit.com/r/androiddev/comments/297xli/howto_use_the_v21_support_libs_on_older_versions/
http://moonlightbox.logdown.com/posts/2015/09/01/android-finished-with-non-zero-exit-value-3
http://stackoverflow.com/questions/31605291/gradle-finished-with-non-zero-exit-value-3
https://www.dotblogs.com.tw/newmonkey48/2015/11/02/153771

Steps:


1. Change minSdkVersion to 19 (for KitKat) in all build.gradle files
2. If Studio show some error messages like below one, you can add dexOptions in the app/build.gradle to fix the error.
Error message:
java.lang.OutOfMemoryError: GC overhead limit exceeded​

Error:org.gradle.process.internal.ExecException: Process 'command 'C:\Program Files\Java\jdk1.7.0_67\bin\java.exe'' finished with non-zero exit value 3

Solution:
app/build.gradle

android {
   ............
    dexOptions {
        javaMaxHeapSize "4g"
    }
}

2015年12月11日 星期五

How to stop a thread

Reference:

http://sp-tech.blogspot.tw/2012/11/java-java.html

Code snippet:

public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
        private boolean isRunning = true;
private Thread mThread;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);

mThread = new Thread(new MyTask());
                mThread.start();
        }

private class MyTask implements Runnable{

        @Override
        public void run() {
Log.d(TAG,"Thread starts");
            while(isRunning){
try{
//do something
Log.d(TAG,"Sleeping...");
Thread.sleep(5000);
} catch(InterruptedException e){
Log.d(TAG,"Thread was inturrupted");
} catch(Exception e) {
//handle error
e.printStackTrace();
}  
}
Log.d(TAG,"Thread ends");
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        isRunning = false; // make the thread leave
        mThread.interrupt();
    }
}

2015年12月8日 星期二

Get boundary coordinates of visible region on Google Map

Reference:

http://stackoverflow.com/questions/14700498/android-google-maps-get-boundary-co-ordinates

Code snippet:

LatLngBounds curScreen = googleMap.getProjection().getVisibleRegion().latLngBounds;

2015年12月3日 星期四

Display the keyboard automatically on AlertDialog with EditText

Reference:

http://stackoverflow.com/questions/12997273/alertdialog-with-edittext-open-soft-keyboard-automatically-with-focus-on-editte
Updated 2016/1/15:
http://stackoverflow.com/questions/8785023/how-to-close-android-soft-keyboard-programatically

Code snippet:

Builder builder = new Builder(this);
final EditText input = new EditText(this);
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
builder.setTitle(R.string.dialog_title_addsubject)
                .setMessage(R.string.dialog_addsubject)
                .setView(input)
                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int which) {
                        .......
                        imm.hideSoftInputFromWindow(input.getWindowToken(), 0);
                        /* updated 2016/1/15
                         * to hide it, call the method again
                         * imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
                         */
                        
                    }
                })
                .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int which) {
                        imm.hideSoftInputFromWindow(input.getWindowToken(), 0);
                        /* updated 2016/1/15
                         * to hide it, call the method again
                         * imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
                         */
                    }

                });
builder.show();
input.requestFocus();
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);

2015年12月2日 星期三

Create an AlertDialog with custom layout/view

Reference:
http://android--code.blogspot.tw/2015/08/android-alertdialog-custom-view.html

Code snippet:
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
View dialogView = getLayoutInflater().inflate(R.layout.alertdialog_custom_view,null);
builder.setView(dialogView);
builder.setTitle(R.string.dialog_title);
// Use AlertDialog default button instead of customized button
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                    ......
            }
});
builder.setNegativeButton(R.string.cancel,new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                ......
            }
});
builder.show();