DELPHI XE Android 开发笔记

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,

remote path 填写 assets\internal\

 

应用显示中文名(工程不能为中文否则会编译出错)

 

菜单 project ->Option->Version Info->label

 

 

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, 5, 2, TFormatSettings.Create('en-US'));
  ENUSLong := NewLocation.Longitude.ToString(ffGeneral, 5, 2, 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;

Delphi XE8 iOS与Android移动应用开发(APP开发)[完整中文版],这是一本不可多得的介绍使用delphi xe8开发iOS与Android移动应用的电子书,实用的技术开发教程与技术开发手册。 Delphi XE8跨平台开发让你使用一套代码完成iOS和Android移动应用开发。强大的控件支持,让你可以不用编写一句代码并在短短几分钟内完成数据库的读写 应用开发开发效率得到充分提升,让编程不再是枯燥无味的工作。全书400多页,从开发环境的安装配置到使用基本界面控件、使用移动设备功能(移动定位、 照像机等)、使用后端服务、访问数据库等都作了全面介绍,是第一本国内最全的中文版Delphi XE8技术开发教程。本书需要有一定delphi基础知识的人阅读。 目 录 第一章 移动应用程序开发(iOS和Android) 17 1. 安装与配置 17 2. 使用基本用户界面控件 18 3. 使用设备功能 20 4. 使用后端服务 21 5. 访问数据库 21 第二章 配置Mac上的开发环境(IOS) 23 2.1 Mac 和 iOS 的要求 23 2.2 配置 Mac 上的iOS模拟器 24 2.2.1 安装平台助手 24 2.2.2 运行平台助手 25 2.2.3 在Mac上安装Xcode 26 2.3 配置 Mac上iOS 硬件设备运行环境 28 2.3.1 在Mac上安装Xcode命令行工具 28 2.3.2 注册一个开发者账户 30 2.3.3 申请、下载并安装你的开发证书 30 2.3.4 注册您的设备 32 2.3.5 创建与安装配置文件 33 第三章 配置WINDOWS PC上的开发环境(iOS) 36 3.1 配置 RAD Studio 环境 37 3.1.1创建与Mac连接的配置 37 3.1.2为iOS设备添加一个SDK 40 第四章 配置WINDOWS PC上的开发环境 (Android) 43 4.1设置 RAD Studio 环境 43 4.1.1 安装RAD Studio时 android 开发工具安装选项 44 4.1.2 在开发环境中配置 Android SDK 46 4.2安装Android USB 驱动程序(必须) 50 第五章 创建移动平台应用程序 (iOS and Android) 54 5.1在你开始之前 54 5.2创建一个新的Android或iOS FireMonkey应用 55 5.3选择Style 56 5.4在多设备窗体上放置组件 56 5.5添加视图到项目 60 5.6编写用户单击按钮的事件处理程序 60 5.7测试移动应用程序 62 5.7.1在Android 设备上测试应用程序 63 5.7.2在 iOS测试应用程序 64 第六章 使用不同风格的按钮控件 (iOS and Android) 67 6.1移动平台中的按钮 67 6.2定义按钮控件的友好界面 68 6.2.1使用按钮控件的 TintColor 和 IconTintColor属性 69 6.2.2自定义按钮控件的图片 71 6.3使用按钮控件创建Segmented Control 72 6.4在工具栏创建 Scope Bar 74 第七章 使用日历控件选取日期 (iOS and Android) 76 7.1移动平台中的日历 76 7.2为用户更改的日期编写事件处理程序 78 第八章 组合框控件的使用 (iOS and Android) 81 8.1多设备应用程序中的选择器 81 8.2使用代码建立列表数据项 84 8.3显示一个指定的项目 84 8.4编写用户选择后的事件处理程序 86 第九章 使用地图控件 (iOS and Android) 88 9.1TMapView 控件的基本功能 89 9.2创建示例应用程序 89 9.2.1配置 Android 应用程序以使用 TMapView 控件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值