System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite); System.IO.StreamReader sr = new System.IO.StreamReader(fs, System.Text.Encoding.Default);使用System.Text.Encoding.Default指定系統預設編碼為StremReader的編碼格式。
上色
Code Block
2016年6月3日 星期五
[.Net] 讀取CSV出現亂碼
當CSV檔中含有中文時,使用StremReader讀取通常都會出現亂碼,這是因為.Net預設使用Unicode編碼,但通常Excel還是使用Big5編碼,此時只要以下列方式指定系統編碼即可解決;
[.Net] 字串轉為DateTime
通常需要將字串轉為DateTime的時候,一大問題就是來源格式常常不是固定的格式,而是有各種五花八門的格式,這時候就可以利用以下方式進行轉換:
首先定義可能出現的各種日期格式,可參照https://msdn.microsoft.com/en-us/library/8kb3ddd4(VS.71).aspx
接著就可以開始處理字串,使用CultureInfo.InvariantCulture解析不同國家語言格式的字串(或是套用目前的國家地區設定解析,CultureInfo.CurrentCulture),使用DateTimeStyles.AllowWhiteSpaces避免字串中可能出現的無意義空白;此外為了避免依然轉換錯誤,可以將整段敘述加入到Try...Catch區塊中,再於Catch區塊中對轉換錯誤加以處理。
Ref: https://dotblogs.com.tw/chhuang/2008/03/18/1921
首先定義可能出現的各種日期格式,可參照https://msdn.microsoft.com/en-us/library/8kb3ddd4(VS.71).aspx
string[] dateTimeList = { "yyyy/M/d tt hh:mm:ss", "yyyy/MM/dd tt hh:mm:ss", "yyyy/MM/dd HH:mm:ss", "yyyy/M/d HH:mm:ss", "yyyy/M/d", "yyyy/MM/dd", "M/d HH:mm:ss" };
接著就可以開始處理字串,使用CultureInfo.InvariantCulture解析不同國家語言格式的字串(或是套用目前的國家地區設定解析,CultureInfo.CurrentCulture),使用DateTimeStyles.AllowWhiteSpaces避免字串中可能出現的無意義空白;此外為了避免依然轉換錯誤,可以將整段敘述加入到Try...Catch區塊中,再於Catch區塊中對轉換錯誤加以處理。
string DateTime date; try { date = DateTime.ParseExact(dateString, dateTimeList, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces); transferFlag = true; } catch (Exception e) { throw new Exception("日期格式錯誤: " + e.Message); }
Ref: https://dotblogs.com.tw/chhuang/2008/03/18/1921
2016年2月1日 星期一
[Android] Android 6.0 (marshmallow) run-time permission 執行期間權限取得
自Android 6.0開始,除了必須在AndroidManifest.xml中宣告權限,在安裝時告知使用者外,執行期間需要用到特殊權限的話也必須告知使用者並取得。
權限可區分為以下兩大類
若要確認是否具有權限,可使用
而當使用者拒絕授予此權限時,開發者可能會需要說明該權限的用途並再次詢問,這時可使用
Reference: Android developer documents
權限可區分為以下兩大類
- 一般權限(PROTECTION_NORMAL),亦即在AndroidManifest.xml中宣告即可,在程式安裝時即授予程式該權限,用戶也無法手動取消。在Android 6.0(API 23)中,一般權限列表如下︰
- ACCESS_LOCATION_EXTRA_COMMANDS
- ACCESS_NETWORK_STATE
- ACCESS_NOTIFICATION_POLICY
- ACCESS_WIFI_STATE
- BLUETOOTH
- BLUETOOTH_ADMIN
- BROADCAST_STICKY
- CHANGE_NETWORK_STATE
- CHANGE_WIFI_MULTICAST_STATE
- CHANGE_WIFI_STATE
- DISABLE_KEYGUARD
- EXPAND_STATUS_BAR
- GET_PACKAGE_SIZE
- INTERNET
- KILL_BACKGROUND_PROCESSES
- MODIFY_AUDIO_SETTINGS
- NFC
- READ_SYNC_SETTINGS
- READ_SYNC_STATS
- RECEIVE_BOOT_COMPLETED
- REORDER_TASKS
- REQUEST_INSTALL_PACKAGES
- SET_TIME_ZONE
- SET_WALLPAPER
- SET_WALLPAPER_HINTS
- TRANSMIT_IR
- USE_FINGERPRINT
- VIBRATE
- WAKE_LOCK
- WRITE_SYNC_SETTINGS
- SET_ALARM
- INSTALL_SHORTCUT
- UNINSTALL_SHORTCUT
- 需要執行期間授權的權限,用戶也可以在設定中隨時關閉他們,Android將之分為數個類別,當取得類別中的其中一個權限時,也就等於取得該類別所有權限,分類如下︰
ActivityCompat.requestPermissions(Activity activity, String[] permissions, int requestCode)
若要確認是否具有權限,可使用
ContextCompat.checkSelfPermission (Context context, String permission)
而當使用者拒絕授予此權限時,開發者可能會需要說明該權限的用途並再次詢問,這時可使用
ActivityCompat.shouldShowRequestPermissionRationale(Activity activity, String permission)
當使用者拒絕授予權限時,下次調用此函式就會返回true,開發者可在此時加入權限說明。
當使用者選擇授予或拒絕此權限時,會呼叫onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)方法,此時override此方法即可處理需要權限的操作。
當使用者選擇授予或拒絕此權限時,會呼叫onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)方法,此時override此方法即可處理需要權限的操作。
具體程式碼如下(以讀寫SD卡為例)︰
private final int REQUEST_CODE_ASK_PERMISSIONS = 10; @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case REQUEST_CODE_ASK_PERMISSIONS: if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Permission Granted //執行需要讀寫SD卡的操作 } else { // Permission Denied Toast.makeText(MainActivity.this, getString(R.string.noPermission), Toast.LENGTH_LONG).show(); } break; default: super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } private void checkPermission(){ //讀取關於讀寫外部儲存裝置的權限 int hasReadExternalStoragePermission = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE); //若沒有權限則詢問取得 if (hasReadExternalStoragePermission!= PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,Manifest.permission.WRITE_EXTERNAL_STORAGE)){ //當被使用者拒絕後再次詢問時,說明該權限用途,用戶可選擇重試(重新詢問是否授予)或取消(維持不授予權限) new AlertDialog.Builder(MainActivity.this) .setMessage("該權限用以讀寫SD卡") .setPositiveButton("重試", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_ASK_PERMISSIONS); } }) .setNegativeButton("取消", null) .create() .show(); return; } ActivityCompat.requestPermissions(MainActivity.this,new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},REQUEST_CODE_ASK_PERMISSIONS); } else //已有權限,直接執行需要讀寫SD卡的操作 }
Reference: Android developer documents
訂閱:
文章 (Atom)