Git Product home page Git Product logo

cordova-plugin-sms-receive's Introduction

npm npm GitHub package.json version GitHub code size in bytes GitHub top language GitHub GitHub last commit

cordova-plugin-sms-receive

Cordova plugin to get received SMS contents in Android platform.

Installation

Add the plugin from NPM:

cordova plugin add cordova-plugin-sms-receive

Methods

startWatch

Start listening for incoming SMS messages. This will request SMS permission to the user if not yet granted.

⚠️ Method moved from window to cordova.plugins object in version 2.0.0

Remarks

  • Both success and error callbacks will react to SMS arrival events as well.
  • Android 5.1 grants permission by default because the individual permission request dialog was added in Android 6.

Success callback return values

  • SMS_WATCHING_STARTED
  • SMS_WATCHING_ALREADY_STARTED
  • SMS_RECEIVED: Second callback, triggered when a SMS was received.

Error callback return values

  • PERMISSION_DENIED: User declined the permission request.
  • SMS_EQUALS_NULL: Triggered after watching started OK but plugin failed to read the received SMS.
  • Any other error string for failed SMS retrieval whenever an SMS is received.

Example

cordova.plugins.SMSReceive.startWatch(function(strSuccess) {
	console.log(strSuccess);
}, function(strError) {
	console.warn(strError);
});

stopWatch

Stops listening for incoming SMS. Always invoke this method after you have received the required SMS to prevent memory leaks.

⚠️ Method moved from window to cordova.plugins object in version 2.0.0

Success callback return values

  • SMS_WATCHING_STOPPED

Example

cordova.plugins.SMSReceive.stopWatch(function(strSuccess) {
	console.log(strSuccess);
}, function(strError) {
	console.warn(strError);
});

Events

onSMSArrive

Triggered when a new SMS has arrived. You need call startWatch first.

⚠️ JSON SMS payload moved from message.data to message object in version 2.0.0

Remarks

  • Success in reading incoming SMS will trigger the startWatch success callback.
  • Failure in reading incoming SMS will trigger the startWatch error callback.

Return values

JSON object with these properties:

  • address: Mobile number from sender
  • body: SMS message body limited to 154 chars.
  • date: SMS received timestamp.

Example

document.addEventListener('onSMSArrive', function(message) {
	console.log('address:' + message.address);
	console.log('body:' + message.body);
	console.log('date' + message.date)
});

Plugin demo app

You can download the compiled SMS Receive plugin demo app and inspect the source code in my plugin demos repository.

ScreenShot

FAQ

Can the SMS be intercepted and deleted?

This plugin does not send SMS nor intercept incoming SMS: the intercepting feature has been removed in Android 5 or earlier for security concerns, so no plugin can do this anymore.

Does the plugin still work with the app minimized?

When the app is sent to the background, as long as Android has not unloaded it to recover memory, SMS watching will remain active and working correctly.

Android Permissions Request

The startWatch method will cause the Android 6.0 and higher permission dialog to show up with this message:

Allow [AppName] to send and view SMS messages?

This message is not exactly accurate, because the plugin only requests permission for receiving SMS as follows:

<uses-permission android:name="android.permission.RECEIVE_SMS" />

How this plugin has been tested?

This plugin has been successfully tested in devices and emulators ranging from Android 5.1 to Android 10.

Contributing

If you find any bugs or want to improve the plugin, kindle subtmit a PR and it will be merged as soon as possible.

Even if you don't quite understand Java, you can investigate and locate issues with the plugin code by opening the SMSReceive.java file and browsing StackOverflow or the Android APIs documentation with the proper keywords.

Changelog

2.0.0

  • ⚠️ Methods moved from the global window to the cordova.plugins object.
  • ⚠️ onSMSArrive no longer returns result in the message.data object, use message directly
  • Fixed SMS message body, now returns the entire message without 154 chars limit.
  • Fixed error when trying to start SMS watching when already active.
  • Changed the onSMSArrive invoking method internally to use native PluginResult callback.
  • Removed the SMS service center number from the JSON payload.
  • Improved all methods return values to make them easier to parse.
  • Improved error handling.
  • Updated demo app, now available as pre-compiled APK.

cordova-plugin-sms-receive's People

Contributors

andreszs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

cordova-plugin-sms-receive's Issues

Demo is not working

The following files are not found:
scripts/platformOverrides.js
scripts/index.js

The plugin cordova-plugin-sms-receive is not present

I install this plugin with "cordova plugin app cordova-plugin-sms-receive"

then, download demo folder with script folder and replace my index.html to demo index.html and script folder copied same folder in index.html

STATUS message is "the plugin cordova_plugin_sms_receive is not preset"

what did i miss?

Remove listener

Hi,

Thanks for the plugin!
I'm facing a problem with the "onSMSArrive" listener.
Even if I call "stopWatch" method or/and "document.removeEventListener('onSMSArrive')" the listener stills alive and call many times.

Any tips to solve this?
Thank you.

error: reference to put is ambiguous

Seems like Java 8 is not liking passing null to JSON.put() directly. If you replace SMSReceive.java:105 with:

json.put(keys[j], JSONObject.NULL);

that should be fixed. 😄

If a Sms body contains more than 140 characters the text message gets reduced

The incoming sms receiver only returns 140 characters in onSMSArrive
document.addEventListener('onSMSArrive', function(e) { console.log('onSMSArrive()'); var IncomingSMS = e.data; console.log('sms.body:' + IncomingSMS.body); /* the incomingSMS.body shows only 140 character the rest of the sms body is missing*/ console.log(JSON.stringify(IncomingSMS)); });

SMS message gettng cut off after 153 characters

I am using the plugin to read incoming messages but the message gets cut off after 153 characters. is there a way to capture the full SMS?

start() { //this.global.createAddressTable(); SMSReceive.startWatch( () => { this.captureStatus = true; alert('watch started'); document.addEventListener('onSMSArrive', (e: any) => { alert(JSON.stringify(e.data)); //alert('onSMSArrive()'); var IncomingSMS = e.data; //alert('sms.address:' + IncomingSMS.address); //alert('sms.body:' + IncomingSMS.body); /* Debug received SMS content (JSON) */ alert(JSON.stringify(IncomingSMS)); //this.processSMS(IncomingSMS); }); }, () => { alert('watch start failed') } ) }

Problem modifying plugin to get sms inbox list in android

I am attempting to build an ionic application that can both read sms messages from inbox and capture incoming messages. I successfully used the https://github.com/andreszs/cordova-plugin-sms-receive/ to capture incoming SMS messages. I attempted to modify the plugin Java file so that it can also pull the SMS list from inbox but it keeps failing and I cant find the point of failure. I created the function inboxMessage() and class MessageProgerty in SMSRecieve,java and used the function getSMSList() in my global.services.ts file to pull the list generated by the plugin.

SMSRecieve.java
`
package com.andreszs.cordova.sms;

import android.Manifest;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.telephony.SmsMessage;
import android.provider.Telephony;
import android.util.Log;


import android.content.Context;
import android.content.ContentResolver;


import java.security.MessageDigest;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Calendar;

public class SMSReceive extends CordovaPlugin {
  
private static final String LOG_TAG = "cordova-plugin-sms-receive";
private static final String ACTION_START_WATCH = "startWatch";
private static final String ACTION_STOP_WATCH = "stopWatch";
private static final String ACTION_GET_LIST = "getlist";
private static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";

public static final int START_WATCH_REQ_CODE = 0;
public static final int PERMISSION_DENIED_ERROR = 20;

private BroadcastReceiver mReceiver = null;

private JSONArray requestArgs;
private CallbackContext callbackContext;

//private Context context;

MessageProperity msg_properity = new MessageProperity();
ArrayList<MessageProperity> messageDetail = new ArrayList<MessageProperity>();


public boolean execute(String action, JSONArray inputs, CallbackContext callbackContext) throws JSONException {
    PluginResult result = null;
    this.callbackContext = callbackContext;
    this.requestArgs = inputs;
    if (action.equals(ACTION_START_WATCH)) {
        if(!hasPermission()) {
            requestPermissions(START_WATCH_REQ_CODE);
        } else {
            result = this.startWatch(callbackContext);
        }
    } else if(action.equals(ACTION_GET_LIST)){
        if(!hasPermission()) {
            requestPermissions(START_WATCH_REQ_CODE);
        } else {
            result = this.getSMSList(callbackContext);
        }           
    } else if (action.equals(ACTION_STOP_WATCH)) {
        result = this.stopWatch(callbackContext);
    } else {
        Log.d(LOG_TAG, String.format("Invalid action passed: %s", action));
        result = new PluginResult(PluginResult.Status.INVALID_ACTION);
    }
    if (result != null) {
        callbackContext.sendPluginResult(result);
    }
    return true;
}

public void onDestroy() {
    this.stopWatch(null);
}

private PluginResult startWatch(CallbackContext callbackContext) {
    Log.d(LOG_TAG, ACTION_START_WATCH);
    if (this.mReceiver == null) {
        this.createIncomingSMSReceiver();
    }
    if (callbackContext != null) {
        callbackContext.success();
    }
    return null;
}

private PluginResult getSMSList(CallbackContext callbackContext) {
    Log.d(LOG_TAG, ACTION_GET_LIST);
    if (messageDetail.isEmpty()) {
        this.inboxMessage();
    }
    if (callbackContext != null) {
        callbackContext.success();
    }
    return null;
}   

private PluginResult stopWatch(CallbackContext callbackContext) {
    Log.d(LOG_TAG, ACTION_STOP_WATCH);
    if (this.mReceiver != null) {
        try {
            webView.getContext().unregisterReceiver(this.mReceiver);
        } catch (Exception e) {
            Log.d(LOG_TAG, "error unregistering network receiver: " + e.getMessage());
        } finally {
            this.mReceiver = null;
        }
    }
    if (callbackContext != null) {
        callbackContext.success();
    }
    return null;
}

private JSONObject getJsonFromCursor(Cursor cur) {
    JSONObject json = new JSONObject();
    int nCol = cur.getColumnCount();
    String keys[] = cur.getColumnNames();
    try {
        for (int j=0; j<nCol; j++) {
            switch(cur.getType(j)) {
                case Cursor.FIELD_TYPE_NULL:
                    json.put(keys[j], JSONObject.NULL);
                break;
                case Cursor.FIELD_TYPE_INTEGER:
                    json.put(keys[j], cur.getLong(j));
                break;
                case Cursor.FIELD_TYPE_FLOAT:
                    json.put(keys[j], cur.getFloat(j));
                break;
                case Cursor.FIELD_TYPE_STRING:
                    json.put(keys[j], cur.getString(j));
                break;
                case Cursor.FIELD_TYPE_BLOB:
                    json.put(keys[j], cur.getBlob(j));
                break;
            }
        }
    }
    catch (Exception e) {
        return null;
    }
    return json;
}

private void onSMSArrive(JSONObject json) {
    webView.loadUrl("javascript:try{cordova.fireDocumentEvent('onSMSArrive', {'data': "+json+"});}catch(e){console.log('exception firing onSMSArrive event from native');};");
}

private void onGetSMSList(JSONArray json) {
    webView.loadUrl("javascript:try{cordova.fireDocumentEvent('onGetSMSList', {'data': "+json+"});}catch(e){console.log('exception firing onGetSMSList event from native');};");
}   

protected void createIncomingSMSReceiver() {
    this.mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(SMS_RECEIVED_ACTION)) {
                // Create SMS container
                SmsMessage smsmsg = null;
                String smsBody = "";
                // Determine which API to use
                if (Build.VERSION.SDK_INT >= 19) {
                    try {
                        /* CHANGE START ------------ */
                        //SmsMessage[] sms = Telephony.Sms.Intents.getMessagesFromIntent(intent);
                        //smsmsg = sms[0];
                        for (SmsMessage smsMessage : Telephony.Sms.Intents.getMessagesFromIntent(intent)) {
                        smsBody += smsMessage.getMessageBody();
                        smsmsg = smsMessage; 
                    }
                    /* CHANGE STOP ------------ */
                    } catch (Exception e) {
                        Log.d(LOG_TAG, e.getMessage());
                    }
                } else {
                    Bundle bundle = intent.getExtras();
                    Object pdus[] = (Object[]) bundle.get("pdus");
                    try {
                        smsmsg = SmsMessage.createFromPdu((byte[]) pdus[0]);
                    } catch (Exception e) {
                        Log.d(LOG_TAG, e.getMessage());
                    }
                }
                // Get SMS contents as JSON
                if(smsmsg != null) {
                    JSONObject jsms = SMSReceive.this.getJsonFromSmsMessage(smsmsg, smsBody);
                    SMSReceive.this.onSMSArrive(jsms);
                    Log.d(LOG_TAG, jsms.toString());
                }else{
                    Log.d(LOG_TAG, "smsmsg is null");
                }
            }
        }
    };
    IntentFilter filter = new IntentFilter(SMS_RECEIVED_ACTION);
    try {
        webView.getContext().registerReceiver(this.mReceiver, filter);
    } catch (Exception e) {
        Log.d(LOG_TAG, "error registering broadcast receiver: " + e.getMessage());
    }
}

private JSONObject getJsonFromSmsMessage(SmsMessage sms, String smsBody) {
    JSONObject json = new JSONObject();
    try {
        json.put( "address", sms.getOriginatingAddress() );
        json.put( "body", smsBody ); // May need sms.getMessageBody.toString()
        json.put( "date_sent", sms.getTimestampMillis() );
        json.put( "date", System.currentTimeMillis() );
        json.put( "service_center", sms.getServiceCenterAddress());
    }
    catch (Exception e) {
        Log.d(LOG_TAG, e.getMessage());
    }
    return json;
}

/**
 * Check if we have been granted SMS receiving permission on Android 6+
 */
private boolean hasPermission() {

    if(Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        return true;
    }
    
    if (cordova.getActivity().checkSelfPermission(Manifest.permission.READ_SMS) == PackageManager.PERMISSION_DENIED) {
        return false;
    }       

    if (cordova.getActivity().checkSelfPermission(Manifest.permission.RECEIVE_SMS) == PackageManager.PERMISSION_DENIED) {
        return false;
    }

    return true;

}

/**
 * We override this so that we can access the permissions variable, which no longer exists in
 * the parent class, since we can't initialize it reliably in the constructor!
 *
 * @param requestCode The code to get request action
 */
public void requestPermissions(int requestCode) {

    cordova.requestPermission(this, requestCode, Manifest.permission.RECEIVE_SMS);
    cordova.requestPermission(this, requestCode, Manifest.permission.READ_SMS);

}

/**
 * processes the result of permission request
 *
 * @param requestCode The code to get request action
 * @param permissions The collection of permissions
 * @param grantResults The result of grant
 */
public void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults) throws JSONException {
    PluginResult result;
    for (int r : grantResults) {
        if (r == PackageManager.PERMISSION_DENIED) {
            Log.d(LOG_TAG, "Permission Denied!");
            result = new PluginResult(PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION);
            callbackContext.sendPluginResult(result);
            return;
        }
    }
    switch(requestCode) {
        case START_WATCH_REQ_CODE:
            this.startWatch(this.callbackContext);
        break;
    }
}

private void inboxMessage() {
try {
    //if (ContextCompat.checkSelfPermission(getBaseContext(), "android.permission.READ_SMS") == PackageManager.PERMISSION_GRANTED) {
        Uri uriSms = Uri.parse("content://sms/inbox");
        //context = (Context)this;
        //ContentResolver result = (ContentResolver)context.getContentResolver();
        Cursor cursor = cordova.getActivity().getContentResolver().query(uriSms, new String[]{"_id", "address", "date", "body"}, null, null, null);
        cursor.moveToFirst();
        //arrayAdapter.clear();
        while (cursor.moveToNext()) {
            msg_properity = new MessageProperity();
            String address = cursor.getString(1);
            Long  msgdate = cursor.getLong(2);
            String body = cursor.getString(3);
            msg_properity.setMessageAddress(address);
            Calendar c = Calendar.getInstance();
            c.setTimeInMillis(msgdate);

            String fullDate= c.get(Calendar.YEAR)+"-"+c.get(Calendar.MONTH)+"-"+c.get(Calendar.DAY_OF_MONTH);
            msg_properity.setMessageDate(fullDate);
            msg_properity.setMessageBody(body);
            messageDetail.add(msg_properity);
            //handleMessage(body);
        }
        //MessageAdapter adapter = new MessageAdapter(this, messageDetail);
        //smsListView.setAdapter(adapter);
        JSONArray jsArray = new JSONArray(messageDetail);
        SMSReceive.this.onGetSMSList(jsArray);
    //} 
} catch (Exception e) {

}


}

public static void handleMessage(String msg) {
try {

    // arrayAdapter.add(msg);
} catch (Exception e) {

}

}   

}

class MessageProperity {
     private String messageAddress;
     private String messageBody;
     private String messageDate;

     public String getMessageAddress() {
       return messageAddress;
    }

    public void setMessageAddress(String messageAddress) {
         this.messageAddress = messageAddress;
    }

    public String getMessageBody() {
         return messageBody;
    }

    public void setMessageBody(String messageBody) {
        this.messageBody = messageBody;
    }

    public String getMessageDate() {
         return messageDate;
    }

    public void setMessageDate(String messageDate) {
         this.messageDate = messageDate;
    }
    }

`

IONIC(global.service.ts)

`
import { Injectable } from '@angular/core';
import { Platform, LoadingController } from '@ionic/angular';
import { SQLite, SQLiteObject } from '@ionic-native/sqlite/ngx';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { NativeStorage } from '@ionic-native/native-storage/ngx';
import { EnvService } from 'src/app/services/env.service';
import { tap } from 'rxjs/operators';
import { Network } from '@awesome-cordova-plugins/network/ngx';
import { ModalController, NavController } from '@ionic/angular';
import { User } from 'src/app/models/user';

   declare var SMSReceive: any;


  @Injectable({
        providedIn: 'root'
  })
  
  export class GlobalService {

   private dbInstance: SQLiteObject;

   MESSAGES: Array <any> ;
   ADDRESS: Array <any> ;
   public response : Array<any> = [];
   public addresses : Array<any> = [];



  public captureStatus = false;
  public incomingSMSMessage: string = '';


  public networkStatus = true;


  public userinfo:any
  public token:any;
  public isLoggedIn = false;







   constructor
   (
           private platform: Platform,
           private sqlite: SQLite,
           private navCtrl: NavController,
           private network: Network,
           private http: HttpClient,
           private loadingController: LoadingController,
           private env: EnvService,
          public storage: NativeStorage,
     ) 
     {

     }




    start() {
        //this.global.createAddressTable();       
         SMSReceive.startWatch(
          () => {
                this.captureStatus = true;  
                 //alert('watch started');
                 document.addEventListener('onSMSArrive', (e: any) => {
                 alert(JSON.stringify(e.data));
                //alert('onSMSArrive()');
                var IncomingSMS = e.data;
                //alert('sms.address:' + IncomingSMS.address);
                //alert('sms.body:' + IncomingSMS.body);
                //alert(JSON.stringify(IncomingSMS));
                this.processSMS(IncomingSMS);
               });
             },
            () => { alert('watch start failed') }
          )
       }


      getSMSList() {

            alert('Getting SMS List');        
            SMSReceive.getlist(
            (e: any) => {
                 alert('Got List');
                 alert(JSON.stringify(e.data));
             },
             () => { alert('get sms list failed') }
           )
        }  


      stop() {
           this.captureStatus = false;    
           SMSReceive.stopWatch(
            () => { alert('SMS watch stopped') },
            () => { alert('SMS watch stop failed') }
          )
      }



      processSMS(data) {
          // Check SMS for a specific string sequence to identify it is you SMS
         // Design your SMS in a way so you can identify the OTP quickly i.e. first 6 letters
         // In this case, I am keeping the first 6 letters as OTP
          alert('processing sms');
          const message = data.body;
          const sc = data.service_center;
          const address = data.address;
          const date_sent = data.date_sent;

          if(this.addresses.indexOf(data.address) >= 0)  
          {
               alert('captured sms from: ' + data.address);
                this.incomingSMSMessage = data;
                alert(this.incomingSMSMessage);
  
           }
       }  



       setData(body, sc, address, date_sent){
       let date = new Date().toString();

        this.addItem(address, body, sc, date, date_sent);
     }



    }

`

App rejected from google play store

Hi,
I used this plugin in Ionic 4 app to read OTP. Everything was working as expected , but unfortunately google play store has changed its policies that why they rejected my application. So what should i do now. I only want this plugin in my app not any other. Is there any way to solve this problem. In google pay they were asking for some reason to use this plugin. I don't know exactly what I have had selected. Can you please help me?

Installation problem

Hello,

trying to install the plugin to a cordova ioniv v1 project I get a strange error

I use this command:
cordova plugin add cordova-plugin-sms-receive

but the installation process claim for a MyApplication, thai is not found

Installing "cordova-plugin-sms-receive" for MyApplication

The platform "MyApplication" does not appear to be a valid cordova p
latform. It is missing API.js. MyApplication not supported.

All other plugins have installed properly so far

Thank you,
Michele

IMPORTANT this plugin has been superseded by the SMS Retriever plugin

Important Notice to Plugin Users

This legacy SMS receive plugin has been deprecated and it must not be used anymore for production environments. This is due to a change in the Android SMS permission policy which prevents the non-default SMS app from reading any SMS contents, for privacy reasons.

To retrieve SMS contents you must switch to my cordova-plugin-sms-retriever plugin, based on the SMS Retriever API. A sample Cordova app is included in the repository.

About the SMS Retriever API

This API lets you read an individual SMS that was specifically targeted to your app alone, by including a unique app ID string in the SMS contents.

The SMS Retriever API does not require SMS permission to work, and it has been developed specifically to fix the SMS privacy issues created by malicious apps and games that used to request SMS permission and could therefore steal all SMS contents from its users.

Kindly switch plugins right away if you are still using the current plugin, otherwise Google Play Store will reject your app at any moment.

Plugin ruins the iOS platform after installation

If I only have Android platform installed, everything is okay. But if I also have iOS platform installed the whole iOS platform is getting ruined and cannot build any more, get the next error:

Unable to load PlatformApi from platform. Error: Cannot find module 'unorm'
Unhandled error. (The platform "ios" does not appear to be a valid cordova platform. It is missing API.js. ios not supported.)

I understand that probably this feature is only allowed on Android but it shouldn't cause and ruin the iOS platform when installing it (cordova plugin add ....). What I probably need to do now is to completely remove the iOS platform, remove the plugin re-install the iOS platform and give up from this plugin since it stucks the iOS.

It could be better if this plugin was consider about the iOS platform or even very much better, to also function and work there.

BTW, on Android it works very good.

SMS event is not getting called if the message app on android is receiving the SMS

I am able to get the event called only when I disable the SMS permission on the default message app on my phone.

hardware: Xiaomi Redmi 5A
Android version: 8.1.0

It was earlier working but now after updating my phone it's behaving strangely, I am pending a release & this is one of the most important.
Quick help here would be a great help.

Thanks in advance!

Unable to receive sms

I am unable to receive sms.
After calling startWatch method, none of the callbacks are getting called

     if (cordova?.plugins?.SMSReceive?.startWatch) {
        console.log(cordova.plugins.SMSReceive);
        cordova.plugins.SMSReceive.startWatch(
          (strSuccess) => {
            console.log(strSuccess);
          }, (strError) => {
            console.warn(strError);
          });
      }

Package.json -

{
  "name": "fraud-detector",
  "version": "0.0.1",
  "author": "Ionic Framework",
  "homepage": "https://ionicframework.com/",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "build:dev": "ionic cordova build android",
    "build:dev2": "ionic cordova build android -- --minSdkVersion=19 --targetSdkVersion=30"
  },
  "private": true,
  "dependencies": {
    "@angular/common": "^14.0.0",
    "@angular/core": "^14.0.0",
    "@angular/forms": "^14.0.0",
    "@angular/platform-browser": "^14.0.0",
    "@angular/platform-browser-dynamic": "^14.0.0",
    "@angular/router": "^14.0.0",
    "@awesome-cordova-plugins/android-permissions": "^5.44.0",
    "@awesome-cordova-plugins/core": "^5.44.0",
    "@ionic/angular": "^6.1.9",
    "@ionic/cordova-builders": "^7.0.0",
    "rxjs": "~6.6.0",
    "tslib": "^2.2.0",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^14.0.0",
    "@angular-eslint/builder": "~13.0.1",
    "@angular-eslint/eslint-plugin": "~13.0.1",
    "@angular-eslint/eslint-plugin-template": "~13.0.1",
    "@angular-eslint/template-parser": "~13.0.1",
    "@angular/cli": "^14.0.0",
    "@angular/compiler": "^14.0.0",
    "@angular/compiler-cli": "^14.0.0",
    "@angular/language-service": "^14.0.0",
    "@ionic/angular-toolkit": "^6.0.0",
    "@types/jasmine": "~3.6.0",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "^12.11.1",
    "@typescript-eslint/eslint-plugin": "5.3.0",
    "@typescript-eslint/parser": "5.3.0",
    "cordova-android": "^9.1.0",
    "cordova-plugin-android-permissions": "^1.1.3",
    "cordova-plugin-device": "2.0.2",
    "cordova-plugin-ionic-keyboard": "^2.0.5",
    "cordova-plugin-ionic-webview": "^5.0.0",
    "cordova-plugin-sms-receive": "^2.0.0",
    "cordova-plugin-splashscreen": "5.0.2",
    "cordova-plugin-statusbar": "^2.4.2",
    "eslint": "^7.6.0",
    "eslint-plugin-import": "2.22.1",
    "eslint-plugin-jsdoc": "30.7.6",
    "eslint-plugin-prefer-arrow": "1.2.2",
    "jasmine-core": "~3.8.0",
    "jasmine-spec-reporter": "~5.0.0",
    "karma": "~6.3.2",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.0.3",
    "karma-coverage-istanbul-reporter": "~3.0.2",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "^1.5.0",
    "protractor": "~7.0.0",
    "ts-node": "~8.3.0",
    "typescript": "~4.7.3"
  },
  "description": "An Ionic project",
  "cordova": {
    "plugins": {
      "cordova-plugin-statusbar": {},
      "cordova-plugin-device": {},
      "cordova-plugin-splashscreen": {},
      "cordova-plugin-ionic-webview": {},
      "cordova-plugin-ionic-keyboard": {},
      "cordova-plugin-sms-receive": {},
      "cordova-plugin-android-permissions": {}
    },
    "platforms": [
      "android"
    ]
  }
}

config.xml

<?xml version='1.0' encoding='utf-8'?>
<widget id="io.fraud.detector" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>Fraud Detector</name>
    <description>An awesome Ionic/Cordova app.</description>
    <author email="[email protected]" href="http://ionicframework.com/">Ionic Framework Team</author>
    <content src="index.html" />
    <access origin="*" />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <preference name="ScrollEnabled" value="false" />
    <preference name="BackupWebStorage" value="none" />
    <preference name="SplashMaintainAspectRatio" value="true" />
    <preference name="FadeSplashScreenDuration" value="300" />
    <preference name="SplashShowOnlyFirstTime" value="false" />
    <preference name="SplashScreen" value="screen" />
    <preference name="SplashScreenDelay" value="3000" />
    <preference name="android-minSdkVersion" value="19" />
    <preference name="android-targetSdkVersion" value="30" />
    <platform name="android">
        <preference name="Scheme" value="http" />
        <edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application" xmlns:android="http://schemas.android.com/apk/res/android">
            <application android:networkSecurityConfig="@xml/network_security_config" />
        </edit-config>
        <resource-file src="resources/android/xml/network_security_config.xml" target="app/src/main/res/xml/network_security_config.xml" />
        <allow-intent href="market:*" />
        <icon density="ldpi" src="resources/android/icon/drawable-ldpi-icon.png" />
        <icon density="mdpi" src="resources/android/icon/drawable-mdpi-icon.png" />
        <icon density="hdpi" src="resources/android/icon/drawable-hdpi-icon.png" />
        <icon density="xhdpi" src="resources/android/icon/drawable-xhdpi-icon.png" />
        <icon density="xxhdpi" src="resources/android/icon/drawable-xxhdpi-icon.png" />
        <icon density="xxxhdpi" src="resources/android/icon/drawable-xxxhdpi-icon.png" />
        <splash density="land-ldpi" src="resources/android/splash/drawable-land-ldpi-screen.png" />
        <splash density="land-mdpi" src="resources/android/splash/drawable-land-mdpi-screen.png" />
        <splash density="land-hdpi" src="resources/android/splash/drawable-land-hdpi-screen.png" />
        <splash density="land-xhdpi" src="resources/android/splash/drawable-land-xhdpi-screen.png" />
        <splash density="land-xxhdpi" src="resources/android/splash/drawable-land-xxhdpi-screen.png" />
        <splash density="land-xxxhdpi" src="resources/android/splash/drawable-land-xxxhdpi-screen.png" />
        <splash density="port-ldpi" src="resources/android/splash/drawable-port-ldpi-screen.png" />
        <splash density="port-mdpi" src="resources/android/splash/drawable-port-mdpi-screen.png" />
        <splash density="port-hdpi" src="resources/android/splash/drawable-port-hdpi-screen.png" />
        <splash density="port-xhdpi" src="resources/android/splash/drawable-port-xhdpi-screen.png" />
        <splash density="port-xxhdpi" src="resources/android/splash/drawable-port-xxhdpi-screen.png" />
        <splash density="port-xxxhdpi" src="resources/android/splash/drawable-port-xxxhdpi-screen.png" />
        <config-file after="uses-permission" parent="/manifest" target="AndroidManifest.xml" xmlns:android="http://schemas.android.com/apk/res/android">
            <uses-permission android:name="android.permission.RECEIVE_SMS" />
        </config-file>
    </platform>
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
        <icon height="57" src="resources/ios/icon/icon.png" width="57" />
        <icon height="114" src="resources/ios/icon/[email protected]" width="114" />
        <icon height="29" src="resources/ios/icon/icon-small.png" width="29" />
        <icon height="58" src="resources/ios/icon/[email protected]" width="58" />
        <icon height="87" src="resources/ios/icon/[email protected]" width="87" />
        <icon height="20" src="resources/ios/icon/icon-20.png" width="20" />
        <icon height="40" src="resources/ios/icon/[email protected]" width="40" />
        <icon height="60" src="resources/ios/icon/[email protected]" width="60" />
        <icon height="48" src="resources/ios/icon/[email protected]" width="48" />
        <icon height="55" src="resources/ios/icon/[email protected]" width="55" />
        <icon height="29" src="resources/ios/icon/icon-29.png" width="29" />
        <icon height="58" src="resources/ios/icon/[email protected]" width="58" />
        <icon height="87" src="resources/ios/icon/[email protected]" width="87" />
        <icon height="40" src="resources/ios/icon/icon-40.png" width="40" />
        <icon height="80" src="resources/ios/icon/[email protected]" width="80" />
        <icon height="120" src="resources/ios/icon/[email protected]" width="120" />
        <icon height="88" src="resources/ios/icon/[email protected]" width="88" />
        <icon height="50" src="resources/ios/icon/icon-50.png" width="50" />
        <icon height="100" src="resources/ios/icon/[email protected]" width="100" />
        <icon height="60" src="resources/ios/icon/icon-60.png" width="60" />
        <icon height="120" src="resources/ios/icon/[email protected]" width="120" />
        <icon height="180" src="resources/ios/icon/[email protected]" width="180" />
        <icon height="72" src="resources/ios/icon/icon-72.png" width="72" />
        <icon height="144" src="resources/ios/icon/[email protected]" width="144" />
        <icon height="76" src="resources/ios/icon/icon-76.png" width="76" />
        <icon height="152" src="resources/ios/icon/[email protected]" width="152" />
        <icon height="167" src="resources/ios/icon/[email protected]" width="167" />
        <icon height="172" src="resources/ios/icon/[email protected]" width="172" />
        <icon height="196" src="resources/ios/icon/[email protected]" width="196" />
        <icon height="1024" src="resources/ios/icon/icon-1024.png" width="1024" />
        <splash height="480" src="resources/ios/splash/Default~iphone.png" width="320" />
        <splash height="960" src="resources/ios/splash/Default@2x~iphone.png" width="640" />
        <splash height="1024" src="resources/ios/splash/Default-Portrait~ipad.png" width="768" />
        <splash height="768" src="resources/ios/splash/Default-Landscape~ipad.png" width="1024" />
        <splash height="1125" src="resources/ios/splash/Default-Landscape-2436h.png" width="2436" />
        <splash height="1242" src="resources/ios/splash/Default-Landscape-736h.png" width="2208" />
        <splash height="2048" src="resources/ios/splash/Default-Portrait@2x~ipad.png" width="1536" />
        <splash height="1536" src="resources/ios/splash/Default-Landscape@2x~ipad.png" width="2048" />
        <splash height="2732" src="resources/ios/splash/Default-Portrait@~ipadpro.png" width="2048" />
        <splash height="2048" src="resources/ios/splash/Default-Landscape@~ipadpro.png" width="2732" />
        <splash height="1136" src="resources/ios/splash/Default-568h@2x~iphone.png" width="640" />
        <splash height="1334" src="resources/ios/splash/Default-667h.png" width="750" />
        <splash height="2208" src="resources/ios/splash/Default-736h.png" width="1242" />
        <splash height="2436" src="resources/ios/splash/Default-2436h.png" width="1125" />
        <splash height="2732" src="resources/ios/splash/Default@2x~universal~anyany.png" width="2732" />
    </platform>
    <plugin name="cordova-plugin-statusbar" spec="2.4.2" />
    <plugin name="cordova-plugin-device" spec="2.0.2" />
    <plugin name="cordova-plugin-splashscreen" spec="5.0.2" />
    <plugin name="cordova-plugin-ionic-webview" spec="^5.0.0" />
    <plugin name="cordova-plugin-ionic-keyboard" spec="^2.0.5" />
    <plugin name="cordova-plugin-android-permissions" spec="^1.1.3" />
</widget>

App híbrida

Tengo una app configurada para impresión de tickets en Zebra mz-200 me gustaría modificar la app para que funciones con todas que sea más genérica al momento de ase la inpresion

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.