DELPHI XE Android 開發筆記

第一次編譯時,設定android SDK:
F:\RAD Studio XE6\PlatformSDKs\adt-bundle-windows-x86-20131030\sdk
F:\RAD Studio XE6\PlatformSDKs\android-ndk-r9c
C:\Program Files\Java\jdk1.7.0_40
SDK更新代理
 
 
XE6 不支持JStringToString、StringTojString、StrToJURI:use Androidapi.Helpers
 
//Splash Image
Delphi XE5,XE6,XE7編譯的程序在Android下啓動會有一段時間黑屏,之前須要用Java擴展Activity增長Splash顯示,
如今Delphi XE7增長了Splash Image顯示功能了。
步驟:
1.鼠標右鍵點擊工程,選擇Options,
2.進入Application分頁
3.勾選Include Splash Image
4.選擇您的Splash Image文件
5.設置Splash Tile mode和Splash Gravity
Splash Tile Mode
disabled -按圖片尺寸大小顯示,顯示位置有Splash Gravity設置
clamp - 圖形邊框適應屏幕大小
repeat - 屏幕水平,豎立方向重複填充滿Splash Image
mirror - 跟repeat差很少,圖片是鏡像的。
Gravity 設置比屏幕小的圖片在屏幕中的位置,只有當Splash Title Mode爲Disable時有效,
參數你們一看便知道什麼意思了,我就不提了。
 
帶文件發佈

菜單 project ->deployment->而後點擊增長按鈕,選擇中sqlite數據 test.s3db,java

remote path 填寫 assets\internal\android

 

應用顯示中文名(工程不能爲中文不然會編譯出錯)git

 

菜單 project ->Option->Version Info->labelsql

 



 

 

FMX.Consts漢化(須要更改單元)
  { Dialog Strings }
//  SMsgDlgWarning = 'Warning';
//  SMsgDlgError = 'Error';
//  SMsgDlgInformation = 'Information';
//  SMsgDlgConfirm = 'Confirm';
//  SMsgDlgYes = 'Yes';
//  SMsgDlgNo = 'No';
//  SMsgDlgOK = 'OK';
//  SMsgDlgCancel = 'Cancel';
//  SMsgDlgHelp = 'Help';
//  SMsgDlgHelpNone = 'No help available';
//  SMsgDlgHelpHelp = 'Help';
//  SMsgDlgAbort = 'Abort';
//  SMsgDlgRetry = 'Retry';
//  SMsgDlgIgnore = 'Ignore';
//  SMsgDlgAll = 'All';
//  SMsgDlgNoToAll = 'No to All';
//  SMsgDlgYesToAll = 'Yes to &All';
//  SMsgDlgClose = 'Close';
//
//  SWindowsVistaRequired = '%s requires Windows Vista or later';
//
//  SUsername = '&Username';
//  SPassword = '&Password';
//  SDomain = '&Domain';
//  SLogin = 'Login';
  SMsgDlgWarning = '警告';
  SMsgDlgError '錯誤';
  SMsgDlgInformation '信息';
  SMsgDlgConfirm '確認';
  SMsgDlgYes '是的';
  SMsgDlgNo '不是';
  SMsgDlgOK '肯定';
  SMsgDlgCancel '取消';
  SMsgDlgHelp '幫助';
  SMsgDlgHelpNone '沒有提供幫助';
  SMsgDlgHelpHelp '幫助';
  SMsgDlgAbort '放棄';
  SMsgDlgRetry '重試';
  SMsgDlgIgnore '忽略';
  SMsgDlgAll '所有';
  SMsgDlgNoToAll '全選「不是」';
  SMsgDlgYesToAll '全選「是」';
  SMsgDlgClose '關閉';

  SWindowsVistaRequired '%s 須要 Windows Vista 或以上操做系統';

  SUsername '&用戶名';
  SPassword '&密碼';
  SDomain '&域名';
  SLogin '登陸';

臨時文件路徑(支持安卓、IOS)
function GeFileName(const AFileName: string): string;
begin
{$IFDEF ANDROID}
  Result := TPath.GetTempPath + '/' + AFileName;
{$ELSE}
  {$IFDEF IOS}
    Result := TPath.GetHomePath + '/Documents/' + AFileName;
  {$ELSE}
    Result := AFileName;
  {$ENDIF}
{$ENDIF}
end;

IOUtils文件說明
路徑類
TPath.GetTempPath; {獲取臨時文件夾路徑} 
TPath.GetTempFileName; {獲取一個臨時文件名}
TPath.GetPathRoot(); {提取盤符, 如: c:\}
TPath.GetDirectoryName(); {提取路徑}
TPath.GetFileName(); {提取文件名}
TPath.GetExtension(); {提取擴展名}
TPath.GetFileNameWithoutExtension(); {提取無擴展名的文件名}
TPath.ChangeExtension(); {更換擴展名}
TPath.DriveExists(); {檢查路徑中的驅動器是否存在}
TPath.GetFullPath(); {根據相對路徑給出全路徑}
TPath.HasExtension(); {判斷是否有擴展名}
TPath.IsPathRooted(); {判斷是不是絕對路徑}
TPath.Combine(); {結合路徑}
TPath.GetRandomFileName; {產生一個隨機文件名}
TPath.GetGUIDFileName(); {用於產生一個惟一的文件名, 布爾參數 決定名稱中是否包含 -} 
TPath.IsValidPathChar(); {判斷給定的字符是否能用於路徑名}
TPath.IsValidFileNameChar(); {判斷給定的字符是否能用於文件名}

TPath.AltDirectorySeparatorChar; {Windows 下是 "\"}
TPath.AltDirectorySeparatorChar; {Windows 下是 "/"}
TPath.ExtensionSeparatorChar; {Windows 下是 "."}
TPath.PathSeparator; {Windows 下是 ";"}
TPath.VolumeSeparatorChar; {Windows 下是 ":"}

//目錄類
TDirectory.CreateDirectory(); {創建新目錄}
TDirectory.Exists(); {判斷文件夾是否存在}
TDirectory.IsEmpty(); {判斷文件夾是否爲空}
TDirectory.Copy(); {複製文件夾}
TDirectory.Move(); {移動文件夾}
TDirectory.Delete(); {刪除文件夾, 第二個參數爲 True 可刪除 非空文件夾} 
TDirectory.GetDirectoryRoot(); {獲取目錄的根盤符, 如: C:\}
TDirectory.GetCurrentDirectory; {獲取當前目錄}
TDirectory.SetCurrentDirectory(); {設置當前目錄}
TDirectory.GetLogicalDrives; {獲取驅動器列表; 下有舉例}
TDirectory.GetAttributes(); {獲取文件夾屬性, 譬如只讀、存檔等; 下有舉例}
TDirectory.SetAttributes(); {設置文件夾屬性; 下有舉例}

//文件類
TFile.Exists();//判斷指定的文件是否存在
TFile.Copy();//複製文件
TFile.Move();//移動文件
TFile.Delete();//刪除文件
TFile.Replace();//替換文件

MotionSensor1: TMotionSensor; 加速傳感器
MotionSensor1.Sensor(AngleAccelX、AngleAccelY、AngleAccelZ)加速度
procedure TAccelerometerForm.Timer1Timer(Sender: TObject);
var
  LProp: TCustomMotionSensor.TProperty;
begin 
  for LProp in MotionSensor1.Sensor.AvailableProperties do
  begin
    { get the data from the sensor }
    case LProp of
      TCustomMotionSensor.TProperty.AccelerationX:
      begin
        lbAccelerationX.Visible := True;
        lbAccelerationX.Text := Format('Acceleration X: %6.2f', [MotionSensor1.Sensor.AccelerationX]);
      end;
   end;
end;
OrientationSensor1: TOrientationSensor;方位傳感器
OrientationSensor1.Sensor(TiltX,TiltY,TiltZ)
procedure TOrientationSensorForm.Timer1Timer(Sender: TObject);
begin
  { get the data from the sensor }
  lbTiltX.Text := Format('Tilt X: %f', [OrientationSensor1.Sensor.TiltX]);
  lbTiltY.Text := Format('Tilt Y: %f', [OrientationSensor1.Sensor.TiltY]);
  lbTiltZ.Text := Format('Tilt Z: %f', [OrientationSensor1.Sensor.TiltZ]);
  lbHeadingX.Text := Format('Heading X: %f', [OrientationSensor1.Sensor.HeadingX]);
  lbHeadingY.Text := Format('Heading Y: %f', [OrientationSensor1.Sensor.HeadingY]);
  lbHeadingZ.Text := Format('Heading Z: %f', [OrientationSensor1.Sensor.HeadingZ]);
end;

TSensorManager傳感器管理器(包含上述兩種傳感器,Samples\Object Pascal\Mobile Samples\Device Sensors and Services\SensorInfo)
TSensorCategory = (Location, Environmental, Motion, Orientation, Mechanical, Electrical, Biometric, Light, Scanner);
位置傳感器,環境傳感器,運動傳感器,方向傳感器,機械傳感器,電傳感器,生物傳感器,光繁傳感器,掃描儀傳感器

TActionList組件能夠添加標準事件(New Standard Action)
TakePhotoFromCameraAction1: TTakePhotoFromCameraAction; // 經過手機攝像頭獲取圖片
TakePhotoFromLibraryAction1: TTakePhotoFromLibraryAction; //獲取手機已存在圖片
ShowShareSheetAction1: TShowShareSheetAction;//用其它程序分享圖片(Bitmap.Assign();)


獲取麥克風設置   FMX.Media
FMicrophone: TAudioCaptureDevice;
FMicrophone := TCaptureDeviceManager.Current.DefaultAudioCaptureDevice;
FMicrophone.FileName 設置路徑
FMicrophone.State = TCaptureDeviceState.Capturing 設備狀態
FMicrophone.StartCapture; //開始錄音
FMicrophone.StopCapture; // 結束錄音

MediaPlayer: TMediaPlayer; 媒體播放器
MediaPlayer.FileName 設置路徑
MediaPlayer.Play; // 開始播放
MediaPlayer.Stop; // 結束播放

獲取手機攝像頭
Camera: TCameraComponent;
Camera.Active := True; //打開
Camera.Active := False; //中止
Camera.SampleBufferToBitmap(imgCameraView.Bitmap, True); //保存圖片 
TThread.Synchronize(TThread.CurrentThread, GetImage); //線程保存圖片
Camera.Quality 圖像質量
Camera.HasFlash 是否有閃光燈
Camera.TorchMode := TTorchMode.ModeOn; //打開閃光燈 Camera.FlashMode := FMX.Media.TFlashMode.fmFlashOff;
Camera.TorchMode := TTorchMode.ModeOff;//關閉閃光燈 Camera.FlashMode := FMX.Media.TFlashMode.fmFlashOn;
Camera.Kind := FMX.Media.TCameraKind.ckFrontCamera;//前置攝像頭
Camera.Kind := FMX.Media.TCameraKind.ckBackCamera;//後置攝像頭

獲取設備信息
lbDeviceType.Text := Format('Device Type: %s', [JStringToString(TJBuild.JavaClass.MODEL)]);
lbOSName.Text := Format('OS Name: %s', [GetCodename(JStringToString(TJBuild_VERSION.JavaClass.RELEASE))]); 
lbOSVersion.Text := Format('OS Version: %s', [JStringToString(TJBuild_VERSION.JavaClass.RELEASE)]);

GestureManager1: TGestureManager; 手勢識別組件(igiRotate|旋轉、igiZoom|縮放、igiLongTap|長按)
組件關聯GestureManager1(Touch.GestureManager,Getures.Standard能夠直接添加事件)
procedure TPinchZoom.FormGesture(Sender: TObject;   const EventInfo: TGestureEventInfo; var Handled: Boolean); 
var
  LObj: IControl;
  LImage: TImage;
  LImageCenter: TPointF;
begin
  if EventInfo.GestureID = igiZoom then
  begin
    LObj := Self.ObjectAtPoint(ClientToScreen(EventInfo.Location));
    if LObj is TImage then
    begin
      if (not(TInteractiveGestureFlag.gfBegin in EventInfo.Flags)) and
        (not(TInteractiveGestureFlag.gfEnd in EventInfo.Flags)) then
      begin
        { zoom the image }
        LImage := TImage(LObj.GetObject);
        LImageCenter := LImage.Position.Point + PointF(LImage.Width / 2,
          LImage.Height / 2);
        LImage.Width := LImage.Width + (EventInfo.Distance - FLastDistance);
        LImage.Height := LImage.Height + (EventInfo.Distance - FLastDistance);
        LImage.Position.X := LImageCenter.X - LImage.Width / 2;
        LImage.Position.Y := LImageCenter.Y - LImage.Height / 2;
      end;
      FLastDistance := EventInfo.Distance;
    end;
  end;
end;

獲取地理信息
LocationSensor1: TLocationSensor;//定位
LocationSensor1.Active := swLocationSensorActive.IsChecked; //開始
NewLocation.Latitude //經度
NewLocation.Longitude //緯度
FGeocoder: TGeocoder;//地理編碼
procedure TLocationForm.LocationSensor1LocationChanged(Sender: TObject;
  const OldLocation, NewLocation: TLocationCoord2D);
const
  LGoogleMapsURL: String 'https://maps.google.com/maps?q=%s,%s';
var
  ENUSLat, ENUSLong: String; // holders for URL strings
begin
  ENUSLat := NewLocation.Latitude.ToString(ffGeneral, 52, TFormatSettings.Create('en-US'));
  ENUSLong := NewLocation.Longitude.ToString(ffGeneral, 52, TFormatSettings.Create('en-US')); 
  { convert the location to latitude and longitude }
  lbLatitude.Text :'Latitude: ' + ENUSLat;
  lbLongitude.Text :'Longitude: ' + ENUSLong;
  { and track the location via Google Maps }
  WebBrowser1.Navigate(Format(LGoogleMapsURL, [ENUSLat, ENUSLong]));

  // Setup an instance of TGeocoder
  try
    if not Assigned(FGeocoder) then
    begin
      if Assigned(TGeocoder.Current) then
        FGeocoder := TGeocoder.Current.Create;
      if Assigned(FGeocoder) then
        FGeocoder.OnGeocodeReverse := OnGeocodeReverseEvent;
    end;
  except
    ListBoxGroupHeader1.Text := 'Geocoder service error.';
  end;

  // Translate location to address
  if Assigned(FGeocoder) and not FGeocoder.Geocoding then
    FGeocoder.GeocodeReverse(NewLocation);
end;
//地理信息
procedure TLocationForm.OnGeocodeReverseEvent(const Address: TCivicAddress);
begin
  ListBoxItemAdminArea.ItemData.Detail       := Address.AdminArea; //省份
  ListBoxItemCountryCode.ItemData.Detail     := Address.CountryCode; //國家編碼 CN
  ListBoxItemCountryName.ItemData.Detail     := Address.CountryName; //國家
  ListBoxItemFeatureName.ItemData.Detail     := Address.FeatureName; //
  ListBoxItemLocality.ItemData.Detail        := Address.Locality; //
  ListBoxItemPostalCode.ItemData.Detail      := Address.PostalCode; //郵政編碼
  ListBoxItemSubAdminArea.ItemData.Detail    := Address.SubAdminArea;//子級省
  ListBoxItemSubLocality.ItemData.Detail     := Address.SubLocality;//子級市
  ListBoxItemSubThoroughfare.ItemData.Detail := Address.SubThoroughfare;//街道
  ListBoxItemThoroughfare.ItemData.Detail    := Address.Thoroughfare;//子街道
end;


獲取本機信息
  FMX.Android.DeviceInfo.GetInformation;
  Memo1.Lines.Add('ID:'+FMX.Android.DeviceInfo.ID);
  Memo1.Lines.Add('IMEI:'+FMX.Android.DeviceInfo.IMEI);
  Memo1.Lines.Add('User:'+FMX.Android.DeviceInfo.User);
  Memo1.Lines.Add('Host:'+FMX.Android.DeviceInfo.Host);
  Memo1.Lines.Add('Tags:'+FMX.Android.DeviceInfo.Tags);
  Memo1.Lines.Add('Time:'+FMX.Android.DeviceInfo.Time);
  Memo1.Lines.Add('AType:'+FMX.Android.DeviceInfo.AType);
  Memo1.Lines.Add('Board:'+FMX.Android.DeviceInfo.Board);
  Memo1.Lines.Add('Radio:'+FMX.Android.DeviceInfo.Radio);
  Memo1.Lines.Add('Brand:'+FMX.Android.DeviceInfo.Brand);
  Memo1.Lines.Add('Model:'+FMX.Android.DeviceInfo.Model);
  Memo1.Lines.Add('Serial:'+FMX.Android.DeviceInfo.Serial);
  Memo1.Lines.Add('Device:'+FMX.Android.DeviceInfo.Device);
  Memo1.Lines.Add('CpuABI:'+FMX.Android.DeviceInfo.CpuABI);
  Memo1.Lines.Add('CpuABI2:'+FMX.Android.DeviceInfo.CpuABI2);
  Memo1.Lines.Add('Display:'+FMX.Android.DeviceInfo.Display);
  Memo1.Lines.Add('Product:'+FMX.Android.DeviceInfo.Product);
  Memo1.Lines.Add('Hardware:'+FMX.Android.DeviceInfo.Hardware);
  Memo1.Lines.Add('Bootloader:'+FMX.Android.DeviceInfo.Bootloader);
  Memo1.Lines.Add('FingerPrint:'+FMX.Android.DeviceInfo.FingerPrint);
  Memo1.Lines.Add('Manufacturer:'+FMX.Android.DeviceInfo.Manufacturer);

MapView1: TMapView;//地圖足跡

WebBrowser1: TWebBrowser; //瀏覽器
WebBrowser1.Navigate('www.baidu.com'); //打開網頁
WebBrowser1.URL := '';//打開網頁
WebBrowser1.GoForward; //前進
WebBrowser1.GoBack;//後退

ShowMessage、MessageDlg、InputQuery //對話框很方便

消息提醒(從手機屏幕頂部向下滑動,出現的提示消息)
NotificationC: TNotificationCenter; 
procedure TNotificationsForm.btnSendNotificationImmediatelyClick(
  Sender: TObject);
var
  Notification: TNotification;
begin
  { verify if the service is actually supported }
  if NotificationC.Supported then
  begin
    Notification := NotificationC.CreateNotification;
    try
      Notification.Name := 'MyNotification';
      Notification.AlertBody := 'Delphi for Mobile is here!';
      Notification.FireDate := Now; //可修改發送消息時間

      { Send notification in Notification Center }
      NotificationC.ScheduleNotification(Notification);
      { also this method is equivalent }
      // NotificationService.PresentNotification(Notification);
    finally
      Notification.DisposeOf;
    end;
  end
end;
  if NotificationC.Supported then
    NotificationC.CancelNotification('MyNotification'); //取消消息
    NotificationC.CancelAll; //取消全部消息



程序事件服務
var
  FMXApplicationEventService: IFMXApplicationEventService;
begin
  if TPlatformServices.Current.SupportsPlatformService (IFMXApplicationEventService,
 IInterface(FMXApplicationEventService)) then 
    FMXApplicationEventService.SetApplicationEventHandler(HandleAppEvent)
  else
     flag := false;
end;
function TForm1.HandleAppEvent(AAppEvent: TApplicationEvent; AContext: TObject)   : boolean; 
begin 
  if flag = false then
    exit;

  case AAppEvent of
    TApplicationEvent.aeEnteredBackground:
      begin
          //當程序後臺運行了
      end;
  end;
  Result := true;
end;


電話信息(Call撥號)
PhoneDialerService: IFMXPhoneDialerService; 
獲取電話服務信息
procedure TPhoneDialerForm.btnGetCarrierInfoClick(Sender: TObject);
var
  PhoneDialerService: IFMXPhoneDialerService;
begin 
  { test whether the PhoneDialer services are supported }
  if TPlatformServices.Current.SupportsPlatformService(IFMXPhoneDialerService, IInterface(PhoneDialerService)) then
  begin
    { if yes, then update the labels with the retrieved information }
    CarrierNameItem.ItemData.Detail := PhoneDialerService.GetCarrier.GetCarrierName;
    CountryCodeItem.ItemData.Detail := PhoneDialerService.GetCarrier.GetIsoCountryCode;
    NetworkCodeItem.ItemData.Detail := PhoneDialerService.GetCarrier.GetMobileCountryCode;
    MobileNetworkItem.ItemData.Detail := PhoneDialerService.GetCarrier.GetMobileNetwork;
  end
  else
    ShowMessage('PhoneDialer service not supported');
end;
撥號
procedure TPhoneDialerForm.btnMakeCallClick(Sender: TObject);
var
  PhoneDialerService: IFMXPhoneDialerService;
begin 
  { test whether the PhoneDialer services are supported }
  if TPlatformServices.Current.SupportsPlatformService(IFMXPhoneDialerService, IInterface(PhoneDialerService)) then
  begin
    { if the Telephone Number is entered in the edit box then make the call, else
      display an error message }
    if edtTelephoneNumber.Text <> '' then
      PhoneDialerService.Call(edtTelephoneNumber.Text)
    else
    begin
      ShowMessage('Please type in a telephone number.');
      edtTelephoneNumber.SetFocus;
    end;
  end
  else
    ShowMessage('PhoneDialer service not supported');
end;

Intent :TJIntent
uses
  Androidapi.JNI.GraphicsContentViewText,
 FMX.Helpers.Android, Androidapi.JNI.Net, Androidapi.Helpers;
procedureCall_URI(constAAction
 : JString;constAURI: string);
var
  uri: Jnet_Uri;
  Intent: JIntent;
begin
  uri := StrToJURI(AURI);
  Intent := TJIntent.JavaClass.init(AAction,
 uri);
  {Intent.putExtra()

//短信
Call_URI(TJIntent.JavaClass.ACTION_SENDTO, 'smsto:137114553XX');
Intent.putExtra(StringToJString('sms_body'), StringToJString('測試短信'));

  若是是要發短信等複雜的應用,須要傳遞各類其餘的參數.要用到Intent.putExtra()傳遞多個參數.
  這裏只封裝最簡單的,具體Intent.putExtra()的用法,能夠查詢Java的資料.大把的
  }
  SharedActivityContext.startActivity(Intent);
end;
 
//使用例子:
//打電話
Call_URI(TJIntent.JavaClass.ACTION_CALL, 'tel:137114553XX');
//打開地圖顯示某個座標點
Call_URI(TJIntent.JavaClass.ACTION_VIEW, 'geo:38.899533,-77.036476');

//打開網頁
Call_URI(TJIntent.JavaClass.ACTION_VIEW, 'www.baidu.com');

//發送電子郵件
 Call_URI(TJIntent.JavaClass.ACTION_SENDTO, 'mailto:wr960204@126.com');
//播放音樂
Call_URI(TJIntent.JavaClass.ACTION_VIEW, 'file:///sdcard/download/最炫民族風.mp3');
回到主畫面procedure TForm1.Button3Click(Sender: TObject);var  Intent: JIntent;begin  Intent:= TJIntent.Create;  Intent.setAction(TJIntent.JavaClass.ACTION_MAIN);  Intent.addCategory(TJIntent.JavaClass.CATEGORY_HOME);  Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);  MainActivity.startActivity(Intent);end;

條碼掃描(須要安裝zxing)
procedure TINVMCForm.btnSCANClick(Sender: TObject);var  uri: Jnet_Uri;       //引用Androidapi.JNI.Net  Intent: JIntent;    //引用Androidapi.JNI.GraphicsContentViewText  jstr:JString;begin  inherited;  uri := StrToJURI('com.google.zxing.client.android.SCAN');  //引用FMX.Helpers.Android  //Intent := TJIntent.JavaClass.init(jstring(('com.google.zxing.client.android.SCAN');  Intent := TJIntent.JavaClass.init(StringToJString('com.google.zxing.client.android.SCAN'));  SharedActivityContext.startActivity(Intent);end;



function GetZXingIntent: JIntent;
const
  GOOGLE_ZXING 'com.google.zxing.client.android.SCAN';
  GOOGLE_ZXING_PACKAGE 'com.google.zxing.client.android';
begin
  Result := TJIntent.JavaClass.init(StringToJString(GOOGLE_ZXING));
  Result.setPackage(StringToJString(GOOGLE_ZXING_PACKAGE));
end;

//是否存在對應

function IsIntentCallable(const AIntent: JIntent): Boolean;
var
  LJPackageManager: JPackageManager;
begin
  Result := False;
  if Assigned(AIntent) then
  begin
    LJPackageManager := SharedActivityContext.getPackageManager;
    Result := LJPackageManager.queryIntentActivities(AIntent,
      TJPackageManager.JavaClass.MATCH_DEFAULT_ONLY).size <> 0;
  end;
end;




獲取手機信息 

function GetPhoneInfo(): string; Var   TelephonyManager: JTelephonyManager;  TelephonyServiceNative: JObject; begin   result := '';   TelephonyServiceNative := SharedActivityContext.getSystemService     (TJContext.JavaClass.TELEPHONY_SERVICE);   if Assigned(TelephonyServiceNative) then     TelephonyManager := TJTelephonyManager.Wrap       ((TelephonyServiceNative as ILocalObject).GetObjectID);   result := JStringToString(TelephonyManager.getLine1Number);//取得手機號   //TelephonyManager.getDeviceId 取IMEI   //TelephonyManager.getLine1Number 取MSISDN  手機號,大部分SIM卡中不會寫入這個信息   //TelephonyManager.getSimSerialNumber 取ICCID   //TelephonyManager.getSubscriberId 取IMSI  運營商其實是用這個查詢的 end; 手機振動 uses  FMX.Helpers.Android,  Androidapi.JNI.App,  Androidapi.JNI.Os,  Androidapi.JNIBridge, FMX.StdCtrls; procedure TForm1.Button2Click(Sender: TObject); function GetVibratorArray(const AintArr:array of int64):TJavaArray<int64>;//震動規律函數var  Lindex:integer;begin  Result:=TJavaArray<int64>.Create(Length(AintArr));  for Lindex:=Low(AintArr) to High(AintArr) do      Result.Items [Lindex]:= AintArr[Lindex];end;var   LVibrator:JVibrator;    LJavaArray:TJavaArray<int64>;begin   LVibrator:=TJVibrator.Wrap((SharedActivity.getSystemService(TJActivity.javaClass.VIBRATOR_SERVICE ) as iLocalObject).GetObjectID );//引用震動   if not LVibrator.hasVibrator then   begin     showmessage('手機不支持震動');     exit;   end;   LVibrator.vibrate(200);//震動200ms    LVibrator.cancel ;//馬上中止震動    LJavaArray:=GetVibratorArray([200,1000,3000,5000]);//調用震動規律   LVibrator.vibrate(LJavaArray,-1);//不重複,  震動一 次    LJavaArray:=GetVibratorArray([200,1000,3000,5000]);//調用震動規律   LVibrator.vibrate(LJavaArray,0);//v不停重複,大於0的參數,能夠指定震動次數end; 網絡傳送文件(相似Server/Client) TTetheringManager|設備管理、TTetheringAppProfile|文件發送 藍牙 System.Bluetooth單元中主要包含一下幾個類 TBluetoothManager、TBluetoothDeviceList、TBluetoothAdapter、TBluetoothDevice、TBluetoothService、 TBluetoothServiceList、TBluetoothSocket TBluetoothManager是藍牙管理器,用於藍牙設備管理,包括髮現藍牙設備,獲取配對設備,處理遠程配對請求等功能 TBluetoothDeviceList是藍牙設備列表,TBluetoothDeviceList = class(TObjectList<TBluetoothDevice>),能夠經過TBluetoothManager.GetPairedDevices得到配對設備列表 TBluetoothAdapter本機藍牙設備,實現配對、取消配對等功能,可經過TBluetoothManager.CurrentAdapter獲得當前藍牙設備 TBluetoothDevice遠端藍牙設備,每一個遠端設備能夠提供若干個服務(TBluetoothService), TBluetoothService遠端藍牙設備服務,包括服務名和UUID TBluetoothServiceList服務列表 = class(TList<TBluetoothService>);可經過TBluetoothDevice.GetServices得到遠端設備服務列表 TBluetoothSocket藍牙通信套接字,經過 TBluetoothDevice.CreateClientSocket(StringToGUID(ServiceGUI), True/False)建立 TimeEdit1: TTimeEdit;//時間選擇 HorzScrollBox1: THorzScrollBox;橫拉組件 MultiView1: TMultiView;//多餘視圖(Mode主明細表,可更改彈出方式) EMSProvider: TEMSProvider;//企業移動服務 BBAS Client(組件組TKinveyProvider、TParseProvider);移動客戶端數據鏈接組件 TabItem1: TTabItem;//多頁 退出鍵不退出程序 procedure TPForm.FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char;   Shift: TShiftState); begin   if Key = vkHardwareBack then   begin     {$IFDEF ANDROID}     MessageDlg('確認退出嗎?', System.UITypes.TMsgDlgType.mtInformation,     [       System.UITypes.TMsgDlgBtn.mbYes,       //System.UITypes.TMsgDlgBtn.mbNo,       System.UITypes.TMsgDlgBtn.mbCancel     ], 0, System.UITypes.TMsgDlgBtn.mbCancel,     procedure(const AResult: TModalResult)     begin       if AResult = mrYES then          MainActivity.finish; { 退出程序 }   // use FMX.Platform.Android       end);     {$ENDIF ANDROID}     //close;     Key := 0;     exit;   end; end; Application.FormFactor.Orientations := [TFormOrientation.Landscape]; //堅屏 Application.FormFactor.Orientations := [TFormOrientation.Portrait];//橫屏 當前網絡狀態(Androidapi.JNI.Network.pas) IsConnected|鏈接,IsWiFiConnected|Wifi是否鏈接,IsMobileConnected|移動網絡是否鏈接 剪貼版FClipboardService: IFMXClipboardService; TPlatformServices.Current.SupportsPlatformService(IFMXClipboardService,    IInterface(FClipboardService)); FClipboardService.SetClipboard(Tvalue(Edit1.Text));  //複製 FClipboardService.GetClipboard.ToString;  //粘貼 鍵盤FService: IFMXVirtualKeyboardToolbarService; if TPlatformServices.Current.SupportsPlatformService (IFMXVirtualKeyboardToolbarService, IInterface(FService)) then  begin   FService.SetToolbarEnabled(true);   FService.SetHideKeyboardButtonVisibility(true); end; 添加桌面快捷方式 procedure Tform1.Button1Click(Sender: TObject); {$IFDEF ANDROID} var   ShortcutIntent: JIntent;   addIntent: JIntent;   wIconIdentifier : integer;   wIconResource : JIntent_ShortcutIconResource; {$ENDIF} begin {$IFDEF ANDROID}   ShortcutIntent := TJIntent.JavaClass.init(SharedActivityContext, SharedActivityContext.getClass);   ShortcutIntent.setAction(TJIntent.JavaClass.ACTION_MAIN);   addIntent := TJIntent.Create;   addIntent.putExtra(TJIntent.JavaClass.EXTRA_SHORTCUT_INTENT, TJParcelable.Wrap((shortcutIntent as ILocalObject).GetObjectID));   addIntent.putExtra(TJIntent.JavaClass.EXTRA_SHORTCUT_NAME, StringToJString(Application.Title));   addIntent.setAction(StringToJString('com.android.launcher.action.INSTALL_SHORTCUT'));   // get icon resource identifier   wIconIdentifier := SharedActivity.getResources.getIdentifier(StringToJString('ic_launcher'), StringToJString('drawable'), StringToJString('com.embarcadero.Project1'));   wIconResource := TJIntent_ShortcutIconResource.JavaClass.fromContext(SharedActivityContext, wIconIdentifier);   // set icon for shortcut   addIntent.putExtra(TJIntent.JavaClass.EXTRA_SHORTCUT_ICON_RESOURCE, TJParcelable.Wrap((wIconResource as ILocalObject).GetObjectID));   SharedActivityContext.sendBroadcast(addIntent); {$ENDIF} end; 截取屏幕圖片 function MakeScaleScreenshot(Sender: TControl): TBitmap;   function GetScreenScale: Single;   var     ScreenService: IFMXScreenService;   begin     Result := 1;     if TPlatformServices.Current.SupportsPlatformService(IFMXScreenService,  IInterface(ScreenService)) then     begin       Result := ScreenService.GetScreenScale;     end;   end; var   fScreenScale: Single; begin    fScreenScale := GetScreenScale;   Result := TBitmap.Create(Round(Sender.Width * fScreenScale),     Round(Sender.Height * fScreenScale));   Result.Clear(0);   if Result.Canvas.BeginScene then     try       Sender.PaintTo(Result.Canvas, RectF(0, 0, Result.Width, Result.Height));     finally       Result.Canvas.EndScene;     end; end; ---------------------
相關文章
相關標籤/搜索