如何分析传入消息(Android上的JavaFX) [英] How to analyze incoming message (JavaFX on Android)
问题描述
我将我的JavaFX应用程序移植到我的Android设备上。我希望我的应用程序读取传入的SMS消息并将其存储在数据库中。我在StackOverflow中发现了几个问题,但我不知道如何在JavaFX方法中实现。请帮助!
这些是创建JavaFX应用程序并将其移植到Android设备所需的步骤,因此您可以跟踪SMS消息,允许:
- 向您输入的号码发送短信。警告:这可能需要支付移动帐户的费用。
- 阅读收件箱中的所有短信列表。
- 收听来电短信,当新的内容出现时显示内容。
第1步
为NetBeans使用Gluon ,我们将添加 PlatformService
类和 PlatformProvider
接口,带有所需服务:
public interface PlatformProvider {
void sendSMS(String number,String message);
列表< SMSMessage> readSMSs();
void listenToIncomingSMS();
ObjectProperty< SMSMessage> messageProperty();
}
此界面将在三个平台上实现(桌面,iOS和Android)。显然,我们只关注Android实现。
这是NetBeans上包含所有包和文件的项目视图:
第3步
让我们现在实现Android上的服务。为此,我在SO上听了几个很棒的答案:发送短信,阅读 inbox 并收听传入SMS 。
从最后一个,我们可以创建一个设置 ObjectProperty
每次收到一个 SMSMessage
对象:
公共类SmsListener扩展BroadcastReceiver {
private final ObjectProperty< SMSMessage> messages = new SimpleObjectProperty<>();
@Override
public void onReceive(Context cntxt,Intent intent){
if(intent.getAction()。equals(Intents.SMS_RECEIVED_ACTION)){
for (SmsMessage smsMessage:Intents.getMessagesFromIntent(intent)){
SMSMessage sms = new SMSMessage(0,smsMessage.getOriginatingAddress(),
smsMessage.getMessageBody(),smsMessage.getStatus()== 1 ?read:not read,
Long.toString(smsMessage.getTimestampMillis()),inbox);
messages.set(sms);
}
}
}
public ObjectProperty< SMSMessage> messagesProperty(){
返回消息;
}
}
为了启动这个监听器,我们使用 FXActivity
,扩展Android Context类并提供对Android服务的访问的类,以注册 SmsListener $ c的实例$ c>:
公共类AndroidPlatformProvider实现PlatformProvider {
私有最终SmsListener receiver = new SmsListener( );
@Override
public void listenToIncomingSMS(){
FXActivity.getInstance()。registerReceiver(receiver,new IntentFilter(Intents.SMS_RECEIVED_ACTION));
}
@Override
public ObjectProperty< SMSMessage> messagesProperty(){
return receiver.messagesProperty();
}
}
第4步
最后,我们需要做的是将属性与UI上的标签绑定并开始广播:
@Override
public void start(阶段阶段){
...
PlatformService.getInstance()。messageProperty()。addListener(
(obs,s,s1) - > {
Platform.runLater(() - > incoming.setText(s1.toString()));
});
//开始播放
PlatformService.getInstance()。listenToIncomingSMS();
}
注意使用 Platform.runLater()
更新标签:广播线程与JavaFX线程不同。
第5步
构建apk之前的最后一步是修改 AndroidManifest.xml
文件以询问所需的权限。
由于jfxmobile-plugin默认创建一个,因此在此阶段运行 gradlew android
将生成它。它位于 SMSTracker\build\javafxports\tmp\android
文件夹下。
将其复制到另一个位置( SMSTracker \ ltl
)并在 build.gradle
文件中包含其引用:
jfxmobile {
android {
manifest ='lib / AndroidManifest.xml'
}
}
现在编辑文件并添加所需的权限和接收者:
<?xml version =1.0encoding =UTF-8?>
< manifest xmlns:android =http://schemas.android.com/apk/res/androidpackage =org.jpereda.smsandroid:versionCode =1android:versionName =1.0 >
< supports-screens android:xlargeScreens =true/>
< uses-permission android:name =android.permission.READ_SMS/>
< uses-permission android:name =android.permission.SEND_SMS/>
< uses-permission android:name =android.permission.RECEIVE_SMS/>
< uses-sdk android:minSdkVersion =4android:targetSdkVersion =21/>
< application android:label =SMSTrackerandroid:name =android.support.multidex.MultiDexApplication>
< activity android:name =javafxports.android.FXActivityandroid:label =SMSTrackerandroid:configChanges =orientation | screenSize>
< meta-data android:name =main.classandroid:value =org.jpereda.sms.SMSTrackerFX/>
< meta-data android:name =debug.portandroid:value =0/>
< intent-filter>
< action android:name =android.intent.action.MAIN/>
< category android:name =android.intent.category.LAUNCHER/>
< / intent-filter>
< / activity>
< receiver android:name =。SmsListener>
< intent-filter android:priority =2147483647>
< action android:name =android.provider.Telephony.SMS_RECEIVED/>
< / intent-filter>
< / receiver>
< / application>
< / manifest>
保存,构建并运行 gradlew androidInstall
to将apk上传到您的设备。
完整项目
所有代码这个应用程序可以在这里找到,包括 apk 已准备好安装在Android设备上。
I ported my JavaFX application to my Android device. I want my application to read incoming SMS messages and store it in a database. I found several questions here in StackOverflow but I don't know how to implement in a JavaFX approach. Please help!
These are the required steps to create and port a JavaFX application to an Android device, so you can track SMS messages, allowing:
- sending SMS to the number you type. Warning: This may by subjected to costs to your mobile account.
- reading all your list of SMS on your inbox.
- listening to incoming SMS, and displaying the content when a new one appears.
Step 1
Using Gluon plugin for NetBeans create a new JavaFX project. Let's call it SMSTracker, with main class org.jpereda.sms.SMSTrackerFX
. On build.gradle
, update the jfxmobile plugin version to b9:
dependencies {
classpath 'org.javafxports:jfxmobile-plugin:1.0.0-b9'
}
First of all let's create SMSMessage
, a JavaFX pojo with our model:
public class SMSMessage {
private final StringProperty id;
private final StringProperty address;
private final StringProperty msg;
private final StringProperty readState; //"0" not read, "1" read sms
private final StringProperty time;
private final StringProperty folderName;
public SMSMessage(String id, String address, String msg, String readState, String time, String folderName){
this.id = new SimpleStringProperty(id);
this.address = new SimpleStringProperty(address);
this.msg = new SimpleStringProperty(msg);
this.readState = new SimpleStringProperty(readState);
this.time = new SimpleStringProperty(time);
this.folderName = new SimpleStringProperty(folderName);
}
public String getId() {
return id.get();
}
public StringProperty idProperty() {
return id;
}
public String getAddress() {
return address.get();
}
public StringProperty addressProperty() {
return address;
}
public String getMsg() {
return msg.get();
}
public StringProperty msgProperty() {
return msg;
}
public String getReadState() {
return readState.get();
}
public StringProperty readStateProperty() {
return readState;
}
public String getTime() {
return time.get();
}
public StringProperty timeProperty() {
return time;
}
public String getFolderName() {
return folderName.get();
}
public StringProperty folderNameProperty() {
return folderName;
}
@Override
public String toString(){
return id.get()+ ": " + address.get() + ": " + msg.get();
}
}
With ScenicBuilder and FXML or by code, create your UI. For this sample, it will be a simple UI with three main areas, for the three above mentioned options.
public class SMSTrackerFX extends Application {
@Override
public void start(Stage stage) {
BorderPane root = new BorderPane();
/*
TOP :: Sending SMS
Warning: This may by subjected to costs to your mobile account
*/
Button buttonSend = new Button("Send SMS");
TextField number = new TextField();
number.setPromptText("Insert number");
HBox.setHgrow(number, Priority.ALWAYS);
HBox hbox = new HBox(10,buttonSend, number);
TextField message = new TextField();
message.setPromptText("Insert text");
HBox.setHgrow(message, Priority.ALWAYS);
VBox vboxTop = new VBox(10,hbox,message);
buttonSend.disableProperty().bind(Bindings.createBooleanBinding(()->{
return number.textProperty().isEmpty()
.or(message.textProperty().isEmpty()).get();
}, number.textProperty(),message.textProperty()));
vboxTop.setPadding(new Insets(10));
root.setTop(vboxTop);
/*
CENTER :: Reading SMS Inbox
*/
Button button = new Button("Read SMS Inbox");
ListView<SMSMessage> view = new ListView<>();
view.setCellFactory(data -> new SMSListCell());
VBox.setVgrow(view, Priority.ALWAYS);
VBox vboxCenter = new VBox(10,button,view);
vboxCenter.setPadding(new Insets(10));
root.setCenter(vboxCenter);
/*
BOTTOM :: Listening to incoming SMS
*/
Label incoming = new Label("No messages");
VBox vboxBottom = new VBox(10,new Label("Incoming SMS"),incoming);
vboxBottom.setPadding(new Insets(10));
root.setBottom(vboxBottom);
Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds();
Scene scene = new Scene(root, visualBounds.getWidth(), visualBounds.getHeight());
stage.setScene(scene);
stage.show();
}
private static class SMSListCell extends ListCell<SMSMessage> {
@Override
protected void updateItem(SMSMessage item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty) {
setGraphic(new Label(item.getId()+ ": " + item.getMsg()));
} else {
setGraphic(null);
}
}
}
}
And this is what we have for now:
Step 2
Following HelloPlatform sample, we will add a PlatformService
class and a PlatformProvider
interface, with the required services:
public interface PlatformProvider {
void sendSMS(String number, String message);
List<SMSMessage> readSMSs();
void listenToIncomingSMS();
ObjectProperty<SMSMessage> messageProperty();
}
This interface will be implemented on each of the three platforms (desktop, iOS and Android). Obviously, we'll focus only on the Android implementation.
This is the project view on NetBeans with all the packages and files involved:
Step 3
Let's implement now the services on Android. For that I've followed several great answers at SO: sending SMS, read inbox and listening to incoming SMS.
From the last one, we can crete a class that sets an ObjectProperty
with an SMSMessage
object every time one is received:
public class SmsListener extends BroadcastReceiver {
private final ObjectProperty<SMSMessage> messages = new SimpleObjectProperty<>();
@Override
public void onReceive(Context cntxt, Intent intent) {
if(intent.getAction().equals(Intents.SMS_RECEIVED_ACTION)){
for (SmsMessage smsMessage : Intents.getMessagesFromIntent(intent)) {
SMSMessage sms = new SMSMessage("0", smsMessage.getOriginatingAddress(),
smsMessage.getMessageBody(), smsMessage.getStatus()==1?"read":"not read",
Long.toString(smsMessage.getTimestampMillis()), "inbox");
messages.set(sms);
}
}
}
public ObjectProperty<SMSMessage> messagesProperty() {
return messages;
}
}
In order to launch this listener, we use FXActivity
, the class that extends the Android Context class and provides the access to the Android services, to register an instance of SmsListener
:
public class AndroidPlatformProvider implements PlatformProvider {
private final SmsListener receiver = new SmsListener();
@Override
public void listenToIncomingSMS() {
FXActivity.getInstance().registerReceiver(receiver, new IntentFilter(Intents.SMS_RECEIVED_ACTION));
}
@Override
public ObjectProperty<SMSMessage> messagesProperty() {
return receiver.messagesProperty();
}
}
Step 4
Finally, all we need to do is bind the property with our label on the UI and start the broadcast:
@Override
public void start(Stage stage) {
...
PlatformService.getInstance().messageProperty().addListener(
(obs,s,s1)->{
Platform.runLater(()->incoming.setText(s1.toString()));
});
// start broadcast
PlatformService.getInstance().listenToIncomingSMS();
}
Note the use of Platform.runLater()
to update the label: the broadcast thread is different than the JavaFX thread.
Step 5
The last step before building the apk consists on modifying the AndroidManifest.xml
file to ask for the required permissions.
Since the jfxmobile-plugin creates one by default, running gradlew android
at this stage will generate it. It is located under SMSTracker\build\javafxports\tmp\android
folder.
Copy it to another location (SMSTracker\lib
) and include its reference in the build.gradle
file:
jfxmobile {
android {
manifest = 'lib/AndroidManifest.xml'
}
}
Now edit the file and add the required permissions and the receiver:
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.jpereda.sms" android:versionCode="1" android:versionName="1.0">
<supports-screens android:xlargeScreens="true"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="21"/>
<application android:label="SMSTracker" android:name="android.support.multidex.MultiDexApplication">
<activity android:name="javafxports.android.FXActivity" android:label="SMSTracker" android:configChanges="orientation|screenSize">
<meta-data android:name="main.class" android:value="org.jpereda.sms.SMSTrackerFX"/>
<meta-data android:name="debug.port" android:value="0"/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<receiver android:name=".SmsListener">
<intent-filter android:priority="2147483647">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
</manifest>
Save, build and run gradlew androidInstall
to upload the apk to your device.
Full project
All the code for this application can be found here, including apk ready to be installed on Android devices.
这篇关于如何分析传入消息(Android上的JavaFX)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!