2016年4月30日 星期六

Read text from raw file

目的

從android raw中取出文字資料

方法

使用org.apache.commons.io中的IOUtils功能

** org.apache.commons.io.Charsets.UTF_8 已經 deprecated
** 可以改用 java.nio.charset.StandardCharsets.UTF_8 ,但至少要 API 19


java

1
2
3
InputStream is = cxt.getResources().openRawResource(R.raw.car_type_list);
String content = IOUtils.toString(is, Charsets.UTF_8);
IOUtils.closeQuietly(is); // don't forget to close your streams


gradle

1
2
3
dependencies {
    compile 'commons-io:commons-io:2.5'
}


reference:
http://stackoverflow.com/a/13566950

http://mvnrepository.com/artifact/commons-io/commons-io

2016年4月21日 星期四

使用android:Theme.Holo.Dialog設定最小寬度

目的

使用 DialogFragment 添加 AlertDialog,並自訂內容畫面設計,直接設定最小畫面寬度

方法

PhotoDialogFragment.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class PhotoListDialogFragment extends DialogFragment {

    private String img;

    public PhotoListDialogFragment(String img) {
        this.img = img;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the Builder class for convenient dialog construction

        View content = LayoutInflater.from(getContext()).inflate(R.layout.photo_list_dialog_content, null, false);
        TextView iv = (TextView) content.findViewById(R.id.photoListDialogIV);
        iv.setText(img);

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.DialogStyle);
        builder.setView(content)
                .setPositiveButton(R.string.dialog_ok, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        // FIRE ZE MISSILES!
                    }
                });
        // Create the AlertDialog object and return it

        return builder.create();
    }
}

style.xml

1
2
3
4
5
6
<resources>
    <style name="DialogStyle" parent="android:Theme.Holo.Dialog">
        <item name="android:windowMinWidthMajor">90%</item>
        <item name="android:windowMinWidthMinor">90%</item>
    </style>
</resources>




reference:
http://stackoverflow.com/a/28519059

2016年2月13日 星期六

Swift Class, Structure, Function

Some difference between classes and structs

ClassStructure
inheritanceO
passed by valueO
passed by referenceO
createclass CRectangle {
    var width = 200
}
struct SRectangle {
    var width = 200
}
constructvar cRet = CRectangle()
// class 不能直接用 CRectangle(width:300) 必需要定義一個 constructor
cRect.width // 為 200
var sRect = SRectangle(width:300)
sRect.width //  為 300
memoryvar cRect = CRectangle()
var cRect2 = cRect // copy reference

cRect2.width // 目前值是 200
cRect2.width = 500
cRect.width // cRect.width 也改變成了 500
var sRect = SRectangle()
var sRect2 = sRect // copy memory

sRect2.width // 目前值是 200
sRect2.width = 500
sRect.width // 不受 sRect2 影響還是 200
immutablelet cRect = CRectangle()
cRect.width = 500 
let sRect = SRectangle()
sRect.width = 500 // 會造成錯誤
mutating functionextension CRectangle {
    func changeWidth(width:Int){
        self.width = width
    }
}
extension SRectangle {
    mutating func changeWidth(width:Int){
        self.width = width
    }
}

Structures and Enumerations Are Value Types

A value type is a type whose value is copied when it is assigned to a variable or constant, or when it is passed to a function.

You’ve actually been using value types extensively throughout the previous chapters. In fact, all of the basic types in Swift—integers, floating-point numbers, Booleans, strings, arrays and dictionaries—are value types, and are implemented as structures behind the scenes.

All structures and enumerations are value types in Swift. This means that any structure and enumeration instances you create—and any value types they have as properties—are always copied when they are passed around in your code.

Assignment and Copy Behavior for Strings, Arrays, and Dictionaries

In Swift, many basic data types such as String, Array, and Dictionary are implemented as structures. This means that data such as strings, arrays, and dictionaries are copied when they are assigned to a new constant or variable, or when they are passed to a function or method.

This behavior is different from Foundation: NSString, NSArray, and NSDictionary are implemented as classes, not structures. Strings, arrays, and dictionaries in Foundation are always assigned and passed around as a reference to an existing instance, rather than as a copy.

Constant and Variable Parameters

Function parameters are constants by default. Trying to change the value of a function parameter from within the body of that function results in a compile-time error. This means that you can’t change the value of a parameter by mistake.

However, sometimes it is useful for a function to have a variable copy of a parameter’s value to work with. You can avoid defining a new variable yourself within the function by specifying one or more parameters as variable parameters instead. Variable parameters are available as variables rather than as constants, and give a new modifiable copy of the parameter’s value for your function to work with.

Define variable parameters by prefixing the parameter name with the var keyword:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
func alignRight(var string: String, totalLength: Int, pad: Character) -> String {
    let amountToPad = totalLength - string.characters.count
    if amountToPad < 1 {
        return string
    }
    let padString = String(pad)
    for _ in 1...amountToPad {
        string = padString + string
    }
    return string
}
let originalString = "hello"
let paddedString = alignRight(originalString, totalLength: 10, pad: "-")
// paddedString is equal to "-----hello"
// originalString is still equal to "hello"


In-Out Parameters

Variable parameters, as described above, can only be changed within the function itself. If you want a function to modify a parameter’s value, and you want those changes to persist after the function call has ended, define that parameter as an in-out parameter instead.




 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
func swapTwoInts(inout a: Int, inout _ b: Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// prints "someInt is now 107, and anotherInt is now 3"



reference:
http://iosdevelopersnote.blogspot.tw/2014/12/swift-struct-class.html
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html#//apple_ref/doc/uid/TP40014097-CH13-ID88
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html#//apple_ref/doc/uid/TP40014097-CH13-ID93
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html#//apple_ref/doc/uid/TP40014097-CH10-ID172
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html#//apple_ref/doc/uid/TP40014097-CH10-ID173

2016年2月12日 星期五

Compiler error: Method with Objective-C selector conflicts with previous declaration with the same Objective-C selector

使用相同函式,不同方法,會造成error

error code:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import UIKit

import UIKit

class ViewController: UIViewController
{
    func perform(operation: (Double) -> Double) {
    }

    func perform(operation: (Double, Double) -> Double) {
    }
}


complier error:
1
Method 'performOperation' with Objective-C selector 'performOperation:' conflicts with previous declaration with the same Objective-C selector


解決函式重載問題


加入@nonobjc即可

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import UIKit

import UIKit

class ViewController: UIViewController
{
    func perform(operation: (Double) -> Double) {
    }

    @nonobjc
    func perform(operation: (Double, Double) -> Double) {
    }
}


Using Swift with Cocoa and Objective-C (Swift 2.1)





reference:

2016年1月14日 星期四

ListView中使用多種版面

問題

ListView中使用多種版面時,需要使用getItemViewType()以及getViewTypeCount()

getItemViewType():default 0,用來判斷需要使用哪種版面

getViewTypeCount():default 1,有幾種版面

**getItemViewType() 必須 小於 getViewTypeCount() **


若 getItemViewType() >= getViewTypeCount(),將會發生 ArrayIndexOutOfBoundsException!!!

2016年1月3日 星期日

Android GCM permission GET_ACCOUNTS

On Android devices, GCM uses an existing connection for Google services. For pre-3.0 devices, this requires users to set up their Google accounts on their mobile devices. A Google account is not a requirement on devices running Android 4.0.4 or higher.

reference:

http://stackoverflow.com/a/18444343

https://developers.google.com/cloud-messaging/android/client

2016年1月1日 星期五

android 6.0 permission check

問題:

在android 6.0(Marshmallow)開始添加了權限控管的功能,用戶可以隨心所欲的在設定中,將APP的權限進行「允許」或「拒絕」,因此在功能使用之前,都必須檢查該功能是否處於「允許」的狀態下

步驟:

  1. 在 AndroidManifest.xml中必須添加該權限的聲明
    1
    <uses-permission android:name="android.permission.CAMERA" />
    
  2. 當該裝置的版本為android 6.0後續的版本才需要進行後續權限的處理
    1
    2
    3
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)  {
    //...進行權限檢查的後續處理
    }
    
  3. 使用檢查「checkSelfPermission()」進行檢查是否擁有該權限,若權限處於「拒絕」狀態(有可能第一次安裝後),則必須先進行允許權限的步驟
    1
    2
    3
    4
    5
    6
    7
    // Check if the Camera permission is already available.
    if ( ActivityCompat.checkSelfPermission( this, Manifest.permission.CAMERA ) == PackageManager.PERMISSION_GRANTED ) {
        // already available
    } else {
        // asking whether to allow permission...
        requestCameraPermission() ;
    }
    
  4. 當權限處於「拒絕」狀態,此時會使用到「shouldShowRequestPermissionRationale()」和「requestPermissions()」
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    /**
     * Requests the Camera permission.
     * If the permission has been denied previously, a SnackBar will prompt the user to grant the
     * permission, otherwise it is requested directly.
     */
    private void requestCameraPermission() {
        Log.i( TAG, "CAMERA permission has NOT been granted. Requesting permission." ) ;
    
        /**
         * shouldShowRequestPermissionRationale 回傳的規則如下:
         * 1.true:用戶在先前權限詢問的選項中,選擇了「拒絕」,但沒有勾選「不再詢問」
         * 2.false:第一次安裝APP後進入該功能
         * 3.false:用戶在先前權限詢問選項中,選擇了「允許」
         * 4.false:用戶在先前權限詢問的選項中,選擇了「拒絕」,但勾選「不再詢問」
         * 5.false:用戶在「設定」裡頭選擇「允許或拒絕」
         * 
         * 呼叫requestPermissions後,是否會跳出詢問視窗,規則如下:
         * 1.不會:用戶在先前權限詢問選項中,選擇了「允許」
         * 2.不會:用戶在先前權限詢問的選項中,選擇了「拒絕」,但勾選「不再詢問」,在後續onRequestPermissionsResult當中一律回傳PERMISSION_DENIED
         * 3.會:第一次安裝APP後進入該功能(第一次跳出不會有「不再詢問」的選項可以勾選)
         * 4.會:用戶在先前權限詢問的選項中,選擇了「拒絕」
         * 5.會:用戶在「設定」裡頭選擇「允許或拒絕」
         * 
         * 當呼叫requestPermissions後,不管用戶選擇允許或拒絕,又或者沒有跳出詢問視窗,後續都會進入onRequestPermissionsResult執行後續動作,規則如下:
         * 1.PERMISSION_GRANTED(允許):用戶選擇「允許」選項、設定中直接選擇「允許」
         * 2.PERMISSION_DENIED(拒絕):用戶選擇「拒絕」選項、設定中直接選擇「拒絕」
         */
        if ( ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.CAMERA ) ) {
            // Provide an additional rationale to the user if the permission was not granted
            // and the user would benefit from additional context for the use of the permission.
            // For example if the user has previously denied the permission.
            Log.i( TAG, "Displaying camera permission rationale to provide additional context." ) ;
            
            // 「R.string.permission_camera_rationale」的內容可以多加一些說明提醒使用戶該功能必須允許該權限才可以使用
            Snackbar.make( mLayout, R.string.permission_camera_rationale, Snackbar.LENGTH_INDEFINITE ).setAction( R.string.ok, new View.OnClickListener() {
                @Override
                public void onClick( View view ) {
                    ActivityCompat.requestPermissions( MainActivity.this, new String[] { Manifest.permission.CAMERA }, REQUEST_CAMERA ) ;
                }
            } ).show() ;
        } else {
            // Camera permission has not been granted yet. Request it directly.
            ActivityCompat.requestPermissions( this, new String[] { Manifest.permission.CAMERA }, REQUEST_CAMERA ) ;
        }
    }
    
  5. 呼叫requestPermissions後,後續會有Callback繼續處理
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    /**
     * Callback received when a permissions request has been completed.
     */
    @Override
    public void onRequestPermissionsResult( int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults ) {
        if ( requestCode == REQUEST_CAMERA ) {
            // Received permission result for camera permission.
            Log.i( TAG, "Received response for Camera permission request." ) ;
    
            // Check if the only required permission has been granted
            if ( grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED ) {
                // Camera permission has been granted, preview can be displayed
                Log.i( TAG, "CAMERA permission has now been granted. Showing preview." ) ;
                Snackbar.make( mLayout, R.string.permision_available_camera, Snackbar.LENGTH_SHORT ).show() ;
            } else {
                Log.i( TAG, "CAMERA permission was NOT granted." ) ;
                Snackbar.make( mLayout, R.string.permissions_not_granted, Snackbar.LENGTH_SHORT ).show() ;
            }
        }
        // other callback
        else {
            super.onRequestPermissionsResult( requestCode, permissions, grantResults ) ;
        }
    }
    

reference:


android 6.0 remove apache lib solved method

當使用android 6.0進行專案撰寫,6.0版本移除了apache的功能

官網說明如下:
https://developer.android.com/intl/zh-tw/about/versions/marshmallow/android-6.0-changes.html#behavior-apache-http-client

eclipse project solved method

從SDK/platforms/android-23/optional裡頭的org.apache.http.legacy.jar複製到專案的lib資料夾

reference:
http://stackoverflow.com/a/32066606

解決的Eclipse更新ADT插件時遇到的Eclipse reports rendering library more recent than ADT plug-in問題


參照此文章更新ADT
http://wangcuijing.blog.51cto.com/7233352/1320155