跨過幾個坑,終於完成了我的第一個Xamarin Android App!


  時間過得真快,距離上次發隨筆又是一年多。作為上次發的我的第一個WP8.1應用總結的后繼,這次同樣的主要功能,改為實現安卓版APP。前幾個月巨硬收購Xamarin,把Xamarin集成到VS里了,大大方便了我廣大.net碼農。由於年初脫了WP的坑,換了個安卓低端機,想着什么時候裝Xamarin開發個App玩玩。

  上個月筆記本100G的C盤莫名其妙快滿了,趁着重裝系統的機會,安裝了VS2015 with sp3,下載開發Android App需要的各種東東。這里要感謝【C#】VS2015開發環境的安裝和配置系列文章,2016-07-03更新的,已經算是最新的vs2015 with update3的安裝說明了。可惜看到這篇文章還是有點相見恨晚,文章里的流程是先下載安裝JDK和Android SDK等,最后安裝VS,我反過來做,浪費了一些時間。PS:對於使用Hyper-V的同學,可以使用VS自帶的安卓模擬器,省卻了下載和安裝GOOGLE模擬器的一堆時間,據說GOOGLE模擬器還挺坑。。。

================================扯得太多,言歸正傳======================================

  App項目用的是VS里的Android Blank App,先上個圖讓大家看看我手機上的顯示效果,自己用就不需要那么華麗麗了(關鍵是不會。。。)。

App界面

  Android App使用的是顯示與邏輯分離的設計模式,雖然我基本是做Winform的,也是基本能看懂的。Resources\layout文件夾里放視圖文件,而代碼邏輯文件放在最外層,整個項目的結構如下圖:

  這個App主界面使用的是GridLayout進行垂直布局,用法類似於HTML中的Table和WPF中的Grid,代碼如下:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="horizontal"
 6     android:paddingLeft="10dp"
 7     android:paddingRight="10dp"
 8     android:rowCount="6"
 9     android:columnCount="2">
10     <TextView
11         android:id="@+id/tvMachineCode"
12         android:layout_width="wrap_content"
13         android:layout_marginRight="5dp"
14         android:textSize="20sp"
15         android:layout_marginTop="50dp"
16         android:text="機器碼" />
17     <EditText
18         android:id="@+id/txtMachineCode"
19         android:textSize="20sp"
20         android:maxLength ="20"
21         android:layout_marginTop="50dp"
22         android:layout_width="fill_parent" />
23     <TextView
24         android:id="@+id/tvActiviationCode"
25         android:layout_width="wrap_content"
26         android:layout_marginRight="5dp"
27         android:textSize="20sp"
28         android:layout_marginTop="30dp"
29         android:text="激活碼" />
30     <EditText
31         android:id="@+id/txtActiviationCode"
32         android:textSize="20sp"
33         android:layout_marginTop="30dp"
34         android:layout_width="fill_parent" />
35     <Button
36         android:id="@+id/btnGetActiviationCode"
37         android:layout_marginTop="30dp"
38         android:layout_columnSpan="2"
39         android:layout_width="match_parent"
40         android:text="獲取激活碼" />
41     <Button
42         android:id="@+id/btnScanQRCode"
43         android:layout_columnSpan="2"
44         android:layout_width="match_parent"
45         android:text="掃描二維碼" />
46     <Button
47         android:id="@+id/btnReadQRCode"
48         android:layout_columnSpan="2"
49         android:layout_width="match_parent"
50         android:text="讀取二維碼" />
51   <Button
52       android:id="@+id/btnCopy"
53       android:layout_columnSpan="2"
54       android:layout_width="match_parent"
55       android:text="復制激活碼" />
56   <Button
57       android:id="@+id/btnShare"
58       android:layout_columnSpan="2"
59       android:layout_width="match_parent"
60       android:text="發送激活碼" />
61     <Button
62         android:id="@+id/btnClear"
63         android:layout_columnSpan="2"
64         android:layout_width="match_parent"
65         android:text="清除" />
66 </GridLayout>
Main.axml

  界面設計好之后,開始寫邏輯代碼。App默認是從MainActivity開始啟動(JAVA開發可以在Properties\AndroidManifest.xml中修改,有誰知道Xamarin里是怎么改的?)。開始實現第一個按鈕的功能,自我感覺還是比較容易的,基本可以直接復制粘貼我Winform里的代碼,然而,我發現掉到第一個坑里去了。先看看從Winform里復制來的字符串取MD5的代碼,這個在VS自帶的模擬器中執行是正常的,得到的結果與Winform一致,但安裝到手機里得到的就不對了。

1         private string MD5(string str, bool clearsplitter = true, bool islower = true)
2         {
3             var md5 = MD5CryptoServiceProvider.Create();
4             var output = md5.ComputeHash(Encoding.Default.GetBytes(str));
5             StringBuilder strbvalue = new StringBuilder(BitConverter.ToString(output).Replace("-", string.Empty).Substring(8, 16));
6             if (!clearsplitter)
7                 strbvalue.Insert(12, '-').Insert(8, '-').Insert(4, '-');
8             return islower ? strbvalue.ToString().ToLower() : strbvalue.ToString().ToUpper();
9         }

 

 上網查了下,也問了下別人,電腦里Encoding.Default用的編碼是GB2312,而手機里可能是ASCII。由於不能修改之前的代碼,只能改這個了,把Encoding.Default改成了Encoding.GetEncoding("gb2312"),結果出乎預料,竟然閃退了。。。又上網搜了下,需要引用Xamarin安裝自帶的I18N.CJK,總算是搞定了第一個按鈕。以下是【獲取激活碼】和【清除】的代碼:

        private void Btngetactiviationcode_Click(object sender, EventArgs e)
        {
            string strerr = ValidateFormat(txtMachineCode.Text);
            if (strerr != string.Empty)
            {
                var dlg = new AlertDialog.Builder(this).SetTitle("警告")
                    .SetMessage("輸入的機器碼格式不正確!\n" + strerr);
                dlg.Show();
                Btnclear_Click(this, null);
                return;
            }
            txtActiviationCode.Text = GetActiveCode(txtMachineCode.Text);
        }

        private void Btnclear_Click(object sender, EventArgs e)
        {
            txtMachineCode.Text = txtActiviationCode.Text = string.Empty;
        }

        private string GetActiveCode(string machinecode)
        {
            string guid = "cd89e66c-b897-4ed8-a19f-ef5a30846f0a";
            return MD5(machinecode + MD5(guid, false, false), false, false);
        }

        private string MD5(string str, bool clearsplitter = true, bool islower = true)
        {
            var md5 = MD5CryptoServiceProvider.Create();
            var output = md5.ComputeHash(Encoding.GetEncoding("gb2312").GetBytes(str));
            StringBuilder strbvalue = new StringBuilder(BitConverter.ToString(output).Replace("-", string.Empty).Substring(8, 16));
            if (!clearsplitter)
                strbvalue.Insert(12, '-').Insert(8, '-').Insert(4, '-');
            return islower ? strbvalue.ToString().ToLower() : strbvalue.ToString().ToUpper();
        }
【獲取激活碼】和【清除】

  這個App的主要便利用途就是能夠掃描和識別二維碼,上網搜了下,使用ZXing庫會比較簡單,它有個.net移動開發版本叫ZXing.Net.Mobile,可以使用Nuget直接下載添加引用,由於它依賴於Xamarin.Android.Support.v4,所以也要一起下載安裝。直接按照ZXing.Net.Mobile官網上的掃描二維碼示例代碼,就做好了最簡單的二維碼掃描功能。注意:要在OnCreate方法里先初始化一下:

1     MobileBarcodeScanner.Initialize(Application);
1         private async void Btnscanqrcode_Click(object sender, EventArgs e)
2         {
3             var scanner = new ZXing.Mobile.MobileBarcodeScanner();
4             var result = await scanner.Scan();
5             if (result == null)
6                 return;
7             txtMachineCode.Text = result.Text.Trim();
8             Btngetactiviationcode_Click(this, null);
9         }

  完成掃描二維碼的功能,頓時信心大增,以為識別圖片中的二維碼也很簡單,結果發現又掉第二個坑里去了。原來,ZXing.Net.Mobile里沒有現成簡單的識別二維碼的方法,只查到可以用IBarcodeReader.Decode()方法來識別,然而它第一個參數byte[] rawRGB是個什么鬼?為毛不能提供一個Bitmap讓我爽一下?!去網上搜JAVA版的都是傳遞Bitmap對象,再去看了下ZXing.Net.Mobile的源碼,竟然是有些項目類型是Bitmap對象,有些是byte[]。沒時間深究,我還是自己來弄個byte[]吧。

  印象中看到過一篇教程里介紹過這個方法,說rawRGB參數指的是每個像素點的RGB值數組,而不是圖像文件的二進制數組,這就要讀取圖像中的所有點的顏色值到數組里里再傳遞了。

 1         private void Btnreadqrcode_Click(object sender, EventArgs e)
 2         {
 3             Intent = new Intent();
 4             //從文件瀏覽器和相冊等選擇圖像文件
 5             Intent.SetType("image/*");
 6             Intent.SetAction(Intent.ActionGetContent);
 7             StartActivityForResult(Intent, 1);
 8         }
 9 
10         protected override void OnActivityResult(int requestCode, [GeneratedEnum] Android.App.Result resultCode, Intent data)
11         {
12             base.OnActivityResult(requestCode, resultCode, data);
13             if(requestCode == 1 && resultCode == Android.App.Result.Ok && data != null)
14             {
15                 // create a barcode reader instance
16                 IBarcodeReader reader = new BarcodeReader();
17                 // load a bitmap
18                 int width = 0, height = 0;
19                 //像素顏色值列表(注意:一個像素的每個顏色值都是一個列表中單獨的元素,
20                 //后面將會把像素顏色值轉換成ARGB32格式的顏色,每個像素顏色值就有4個元素加入到列表中)
21                 List<byte> pixelbytelist = new List<byte>();
22                 try
23                 {
24                     //根據選擇的文件路徑生成Bitmap對象
25                     using (Bitmap bmp = Android.Provider.MediaStore.Images.Media.GetBitmap(ContentResolver, data.Data))
26                     {
27                         width = bmp.Width; //圖像寬度
28                         height = bmp.Height;  //圖像高度
29                         // detect and decode the barcode inside the bitmap
30                         bmp.LockPixels();
31                         int[] pixels = new int[width * height];
32                         //一次性讀取所有像素的顏色值(一個整數)到pixels
33                         bmp.GetPixels(pixels, 0, width, 0, 0, width, height);
34                         bmp.UnlockPixels();
35                         for (int i = 0; i < pixels.Length; i++)
36                         {
37                             int p = pixels[i];  //取出一個像素顏色值
38                             //將像素顏色值中的alpha顏色(透明度)添加到列表
39                             pixelbytelist.Add((byte)Color.GetAlphaComponent(p));
40                             //將像素顏色值中的紅色添加到列表
41                             pixelbytelist.Add((byte)Color.GetRedComponent(p));
42                             //將像素顏色值中的綠色添加到列表
43                             pixelbytelist.Add((byte)Color.GetGreenComponent(p));
44                             //將像素顏色值中的藍色添加到列表
45                             pixelbytelist.Add((byte)Color.GetBlueComponent(p));
46                         }
47                     }
48                     //識別
49                     var result = reader.Decode(pixelbytelist.ToArray(), width, height, RGBLuminanceSource.BitmapFormat.ARGB32);
50                     if (result != null)
51                     {
52                         txtMachineCode.Text = result.Text.Trim(); 53                         Btngetactiviationcode_Click(this, null);
54                     }
55                     else
56                         Toast.MakeText(this, "未能識別到二維碼!", ToastLength.Short).Show();
57                 }
58                 catch (Exception ex)
59                 {
60                     var dlg = new AlertDialog.Builder(this).SetTitle("警告")
61                         .SetMessage("獲取圖像時發生錯誤!\n" + ex.ToString());
62                     dlg.Show();
63                 }
64             }
65         }

  上面就完成了識別二維碼的功能,不過上面紅色文字那里又出現個只在手機上出現的詭異問題,識別出來的二維碼后面會多出一個不可見的字符,它會影響EditText中Text的長度,但不影響Text的值,可以被刪除,刪除前后計算出的激活碼是相同的。沒有去看源碼,不知道怎么產生的,有人知道嗎?

  后面的復制激活碼和發送激活碼比較簡單,都是直接找的網上的代碼,調用系統功能來做。

 1         private void Btncopy_Click(object sender, EventArgs e)
 2         {
 3             ClipboardManager clip = (ClipboardManager)GetSystemService(ClipboardService);
 4             StringBuilder strbcontent = new StringBuilder();
 5             strbcontent.AppendLine("機器碼:" + txtMachineCode.Text)
 6                 .AppendLine("激活碼:" + txtActiviationCode.Text);
 7             ClipData clipdata = ClipData.NewPlainText("激活碼", strbcontent.ToString());
 8             clip.PrimaryClip = clipdata;
 9             Toast.MakeText(this, "激活碼已復制到剪貼板", ToastLength.Short).Show();
10         }
11 
12         private void Btnshare_Click(object sender, EventArgs e)
13         {
14             if (string.IsNullOrWhiteSpace(txtActiviationCode.Text))
15             {
16                 var dlg = new AlertDialog.Builder(this).SetTitle("警告")
17                     .SetMessage("請先獲取激活碼!");
18                 dlg.Show();
19                 return;
20             }
21             string strerr = ValidateFormat(txtMachineCode.Text);
22             if (strerr != string.Empty)
23             {
24                 var dlg = new AlertDialog.Builder(this).SetTitle("警告")
25                     .SetMessage("輸入的機器碼格式不正確!\n" + strerr);
26                 dlg.Show();
27                 return;
28             }
29             Intent intent = new Intent(Intent.ActionSend);
30             intent.SetType("text/plain");//所有可以分享文本的app
31             StringBuilder strbcontent = new StringBuilder();
32             strbcontent.AppendLine("機器碼:" + txtMachineCode.Text)
33                 .AppendLine("激活碼:" + txtActiviationCode.Text);
34             intent.PutExtra(Intent.ExtraText, strbcontent.ToString());
35             StartActivity(Intent.CreateChooser(intent, "發送激活碼"));
36         }
37 
38         private string ValidateFormat(string str)
39         {
40             if(str.Length<19)
41                 return "輸入的格式不正確";
42             if (str.Length != 19)
43                 str = str.Substring(0, 19);
44             string[] strs = str.Split('-');
45             if (strs.Length != 4)
46                 return "不能分隔為4組";
47             foreach (string s in strs)
48             {
49                 if (s.Length != 4)
50                     return s + "的長度不是4";
51                 if (!System.Text.RegularExpressions.Regex.IsMatch(s, "^[A-F0-9]{4}$"))
52                     return s + "的格式不正確";
53             }
54             return string.Empty;
55         }
【復制激活碼】和【發送激活碼】

  斷斷續續寫了幾個晚上,終於寫完這篇隨筆了。在眼睛徹底睜不開之前趕緊貼上完整代碼。

  1 using System;
  2 using Android.App;
  3 using Android.Content;
  4 using Android.Runtime;
  5 using Android.Views;
  6 using Android.Widget;
  7 using Android.OS;
  8 using System.Text;
  9 using System.Security.Cryptography;
 10 using ZXing.Mobile;
 11 using Android.Graphics;
 12 using ZXing;
 13 using Android.Database;
 14 using System.Collections.Generic;
 15 
 16 namespace FMSKeygen_Android
 17 {
 18     [Activity(Label = "流程管理系統注冊機", MainLauncher = true, Icon = "@drawable/icon")]
 19     public class MainActivity : Activity
 20     {
 21         private EditText txtMachineCode = null;
 22         private EditText txtActiviationCode = null;
 23 
 24         protected override void OnCreate(Bundle bundle)
 25         {
 26             base.OnCreate(bundle);
 27 
 28             // Set our view from the "main" layout resource
 29             SetContentView(Resource.Layout.Main);
 30 
 31             // 初始化二維碼掃描儀,后面要用到
 32             MobileBarcodeScanner.Initialize(Application);
 33 
 34             txtMachineCode = FindViewById<EditText>(Resource.Id.txtMachineCode);
 35             //設置自動轉換小寫字母為大寫
 36             txtMachineCode.SetFilters(new Android.Text.IInputFilter[] { new Android.Text.InputFilterAllCaps() });
 37             txtActiviationCode = FindViewById<EditText>(Resource.Id.txtActiviationCode);
 38             //取消對驗證碼文本框的所有按鍵監聽
 39             txtActiviationCode.KeyListener = null;
 40             Button btnclear = FindViewById<Button>(Resource.Id.btnClear);
 41             btnclear.Click += Btnclear_Click;
 42             Button btngetactiviationcode = FindViewById<Button>(Resource.Id.btnGetActiviationCode);
 43             btngetactiviationcode.Click += Btngetactiviationcode_Click;
 44             Button btnscanqrcode = FindViewById<Button>(Resource.Id.btnScanQRCode);
 45             btnscanqrcode.Click += Btnscanqrcode_Click;
 46             Button btncopy = FindViewById<Button>(Resource.Id.btnCopy);
 47             btncopy.Click += Btncopy_Click;
 48             Button btnreadqrcode = FindViewById<Button>(Resource.Id.btnReadQRCode);
 49             btnreadqrcode.Click += Btnreadqrcode_Click;
 50             Button btnshare = FindViewById<Button>(Resource.Id.btnShare);
 51             btnshare.Click += Btnshare_Click;
 52         }
 53         
 54 
 55         private void Btnshare_Click(object sender, EventArgs e)
 56         {
 57             if (string.IsNullOrWhiteSpace(txtActiviationCode.Text))
 58             {
 59                 var dlg = new AlertDialog.Builder(this).SetTitle("警告")
 60                     .SetMessage("請先獲取激活碼!");
 61                 dlg.Show();
 62                 return;
 63             }
 64             string strerr = ValidateFormat(txtMachineCode.Text);
 65             if (strerr != string.Empty)
 66             {
 67                 var dlg = new AlertDialog.Builder(this).SetTitle("警告")
 68                     .SetMessage("輸入的機器碼格式不正確!\n" + strerr);
 69                 dlg.Show();
 70                 return;
 71             }
 72             Intent intent = new Intent(Intent.ActionSend);
 73             intent.SetType("text/plain");//所有可以分享文本的app
 74             StringBuilder strbcontent = new StringBuilder();
 75             strbcontent.AppendLine("機器碼:" + txtMachineCode.Text)
 76                 .AppendLine("激活碼:" + txtActiviationCode.Text);
 77             intent.PutExtra(Intent.ExtraText, strbcontent.ToString());
 78             StartActivity(Intent.CreateChooser(intent, "發送激活碼"));
 79         }
 80 
 81         private string ValidateFormat(string str)
 82         {
 83             if(str.Length<19)
 84                 return "輸入的格式不正確";
 85             if (str.Length != 19)
 86                 str = str.Substring(0, 19);
 87             string[] strs = str.Split('-');
 88             if (strs.Length != 4)
 89                 return "不能分隔為4組";
 90             foreach (string s in strs)
 91             {
 92                 if (s.Length != 4)
 93                     return s + "的長度不是4";
 94                 if (!System.Text.RegularExpressions.Regex.IsMatch(s, "^[A-F0-9]{4}$"))
 95                     return s + "的格式不正確";
 96             }
 97             return string.Empty;
 98         }
 99 
100         private void Btnreadqrcode_Click(object sender, EventArgs e)
101         {
102             Intent = new Intent();
103             //從文件瀏覽器和相冊等選擇圖像文件
104             Intent.SetType("image/*");
105             Intent.SetAction(Intent.ActionGetContent);
106             StartActivityForResult(Intent, 1);
107         }
108 
109         protected override void OnActivityResult(int requestCode, [GeneratedEnum] Android.App.Result resultCode, Intent data)
110         {
111             base.OnActivityResult(requestCode, resultCode, data);
112             if(requestCode == 1 && resultCode == Android.App.Result.Ok && data != null)
113             {
114                 // create a barcode reader instance
115                 IBarcodeReader reader = new BarcodeReader();
116                 // load a bitmap
117                 int width = 0, height = 0;
118                 //像素顏色值列表(注意:一個像素的每個顏色值都是一個列表中單獨的元素,
119                 //后面將會把像素顏色值轉換成ARGB32格式的顏色,每個像素顏色值就有4個元素加入到列表中)
120                 List<byte> pixelbytelist = new List<byte>();
121                 try
122                 {
123                     //根據選擇的文件路徑生成Bitmap對象
124                     using (Bitmap bmp = Android.Provider.MediaStore.Images.Media.GetBitmap(ContentResolver, data.Data))
125                     {
126                         width = bmp.Width; //圖像寬度
127                         height = bmp.Height;  //圖像高度
128                         // detect and decode the barcode inside the bitmap
129                         bmp.LockPixels();
130                         int[] pixels = new int[width * height];
131                         //一次性讀取所有像素的顏色值(一個整數)到pixels
132                         bmp.GetPixels(pixels, 0, width, 0, 0, width, height);
133                         bmp.UnlockPixels();
134                         for (int i = 0; i < pixels.Length; i++)
135                         {
136                             int p = pixels[i];  //取出一個像素顏色值
137                             //將像素顏色值中的alpha顏色(透明度)添加到列表
138                             pixelbytelist.Add((byte)Color.GetAlphaComponent(p));
139                             //將像素顏色值中的紅色添加到列表
140                             pixelbytelist.Add((byte)Color.GetRedComponent(p));
141                             //將像素顏色值中的綠色添加到列表
142                             pixelbytelist.Add((byte)Color.GetGreenComponent(p));
143                             //將像素顏色值中的藍色添加到列表
144                             pixelbytelist.Add((byte)Color.GetBlueComponent(p));
145                         }
146                     }
147                     //識別
148                     var result = reader.Decode(pixelbytelist.ToArray(), width, height, RGBLuminanceSource.BitmapFormat.ARGB32);
149                     if (result != null)
150                     {
151                         txtMachineCode.Text = result.Text.Trim();
152                         Btngetactiviationcode_Click(this, null);
153                     }
154                     else
155                         Toast.MakeText(this, "未能識別到二維碼!", ToastLength.Short).Show();
156                 }
157                 catch (Exception ex)
158                 {
159                     var dlg = new AlertDialog.Builder(this).SetTitle("警告")
160                         .SetMessage("獲取圖像時發生錯誤!\n" + ex.ToString());
161                     dlg.Show();
162                 }
163             }
164         }
165 
166         private void Btncopy_Click(object sender, EventArgs e)
167         {
168             ClipboardManager clip = (ClipboardManager)GetSystemService(ClipboardService);
169             StringBuilder strbcontent = new StringBuilder();
170             strbcontent.AppendLine("機器碼:" + txtMachineCode.Text)
171                 .AppendLine("激活碼:" + txtActiviationCode.Text);
172             ClipData clipdata = ClipData.NewPlainText("激活碼", strbcontent.ToString());
173             clip.PrimaryClip = clipdata;
174             Toast.MakeText(this, "激活碼已復制到剪貼板", ToastLength.Short).Show();
175         }
176 
177         private async void Btnscanqrcode_Click(object sender, EventArgs e)
178         {
179             var scanner = new ZXing.Mobile.MobileBarcodeScanner();
180             var result = await scanner.Scan();
181             if (result == null)
182                 return;
183             txtMachineCode.Text = result.Text.Trim();
184             Btngetactiviationcode_Click(this, null);
185         }
186 
187         private void Btngetactiviationcode_Click(object sender, EventArgs e)
188         {
189             string strerr = ValidateFormat(txtMachineCode.Text);
190             if (strerr != string.Empty)
191             {
192                 var dlg = new AlertDialog.Builder(this).SetTitle("警告")
193                     .SetMessage("輸入的機器碼格式不正確!\n" + strerr);
194                 dlg.Show();
195                 Btnclear_Click(this, null);
196                 return;
197             }
198             txtActiviationCode.Text = GetActiveCode(txtMachineCode.Text);
199         }
200 
201         private void Btnclear_Click(object sender, EventArgs e)
202         {
203             txtMachineCode.Text = txtActiviationCode.Text = string.Empty;
204         }
205 
206         private string GetActiveCode(string machinecode)
207         {
208             string guid = "cd89e66c-b897-4ed8-a19f-ef5a30846f0a";
209             return MD5(machinecode + MD5(guid, false, false), false, false);
210         }
211 
212         private string MD5(string str, bool clearsplitter = true, bool islower = true)
213         {
214             var md5 = MD5CryptoServiceProvider.Create();
215             var output = md5.ComputeHash(Encoding.GetEncoding("gb2312").GetBytes(str));
216             StringBuilder strbvalue = new StringBuilder(BitConverter.ToString(output).Replace("-", string.Empty).Substring(8, 16));
217             if (!clearsplitter)
218                 strbvalue.Insert(12, '-').Insert(8, '-').Insert(4, '-');
219             return islower ? strbvalue.ToString().ToLower() : strbvalue.ToString().ToUpper();
220         }
221     }
222 }
完整代碼

  碎覺。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM