Мобильное приложение 1С и приложение Java. Совместная работа через Intent. Часть 1. Запуск приложения Java из 1С

Программирование - Практика программирования

Пишем два приложения - конфигурацию на мобильной платформе 1С и приложение Java Android Studio. На примере рассматриваем совместное использование двух приложений через Intent. Публикация состоит из 3 частей: Часть 1. Запуск приложения Java из 1С Часть 2. Получаем данные в 1С из приложения Java Часть 3. Отправляем данные в приложение Java из 1С.

Добрый день, уважаемые коллеги!

В данной части рассмотрим создание двух приложений на мобильной платформе и  Java Android Studio. И реализуем вызов приложение Java из 1С.

1. Начнем с реализации мобильного приложения на Java. Запускаем Android Studio

Выбираем версию SDK. Я выбрал минимальную для работы на большинстве мобильных устройств 2.3.3

Открываем activity_main.xml и рисуем две кнопки:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:id="@+id/btnTime"
        android:text="Показать время">
    </Button>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:id="@+id/btnDate"
        android:text="Показать дату">
    </Button>
</LinearLayout>

Пишем реализацию MainActivity.java:

package ru.w0rm.develop.intentfilter;

import android.app.Activity;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btnTime = (Button) findViewById(R.id.btnTime);
        Button btnDate = (Button) findViewById(R.id.btnDate);

        btnTime.setOnClickListener(this);
        btnDate.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Intent intent;

        switch(v.getId()) {
            case R.id.btnTime:
                intent = new Intent("ru.w0rm.intent.action.showtime");
                startActivity(intent);
                break;
            case R.id.btnDate:
                intent = new Intent("ru.w0rm.action.showdate");
                startActivity(intent);
                break;
        }

    }
}

В коде мы определили кнопки и присвоили им Activity как обработчик нажатий. В методе onCilck мы определяем какая кнопка была нажата и создаем Intent.

Для создания Intent используем конструктор: Intent (String action). Т.е. мы при создании заполняем атрибут объекта Intent, который называется action. Это обычная строковая константа. Action обычно указывает действие, которое мы хотим произвести. Аction – это некий идентификатор окна, по которому мы его будем вызывать из 1С. В моем случае это ru.w0rm.intent.action.showtime и ru.w0rm.action.showdate

Теперь создадим два дополнительных Layout (окна) time.xml и date.xml. Одно окно будет отображать текущее время, а второе дату. Эти Layout мы будем вызывать из 1С.

time.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tvTime"
        android:text="TextView"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="20dp"
        android:textSize="30sp">
    </TextView>
</LinearLayout>

date.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tvDate"
        android:text="TextView"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="20dp"
        android:textSize="30sp">
    </TextView>
</LinearLayout>

Cоздаем класс ActivityTime с суперклассом android.app.Activity.

Пишем код в ActivityTime.java:

package ru.w0rm.develop.intentfilter;

        import java.sql.Date;
        import java.text.SimpleDateFormat;

        import android.app.Activity;
        import android.os.Bundle;
        import android.widget.TextView;

public class ActivityTime extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.time);

        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        String time = sdf.format(new Date(System.currentTimeMillis()));

        TextView tvTime = (TextView) findViewById(R.id.tvTime);
        tvTime.setText(time);
    }
}

Аналогично создаем класс ActivityDate.

Пишем код в ActivityDate.java:

package ru.w0rm.develop.intentfilter;

import java.sql.Date;
import java.text.SimpleDateFormat;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class ActivityDate extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.date);

        SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
        String date = sdf.format(new Date(System.currentTimeMillis()));

        TextView tvDate = (TextView) findViewById(R.id.tvDate);
        tvDate.setText(date);
    }
}

Теперь только осталось дописать в манифесте:

<activity android:name="ActivityTime">
            <intent-filter>
                <action android:name="ru.w0rm.intent.action.showtime"></action>
                <category android:name="android.intent.category.DEFAULT"></category>
            </intent-filter>
        </activity>
        <activity android:name="ActivityDate" android:label="Date basic">
            <intent-filter>
                <action android:name="ru.w0rm.action.showdate"></action>
                <category android:name="android.intent.category.DEFAULT"></category>
            </intent-filter>
        </activity>

Здесь мы как раз и инициализируем наши Action. В итоге в манифесте должно получиться следующее:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="ru.w0rm.develop.intentfilter">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="ActivityTime">
            <intent-filter>
                <action android:name="ru.w0rm.intent.action.showtime"></action>
                <category android:name="android.intent.category.DEFAULT"></category>
            </intent-filter>
        </activity>
        <activity android:name="ActivityDate" android:label="Date basic">
            <intent-filter>
                <action android:name="ru.w0rm.action.showdate"></action>
                <category android:name="android.intent.category.DEFAULT"></category>
            </intent-filter>
        </activity>

    </application>

</manifest>

Запускаем мобильное приложение и проверяем. При нажатии на кнопки вызываются два окна. Одно показывает дату, второе время.

2. Теперь создадим приложение на мобильной платформе 1С и будем вызывать наши Activity из приложения на Java

Создаем новую конфигурацию. Имя Intent. Назначение использования - Мобильное устройство.

Создаем общую форму - Начальная форма. На форму добавляем две команды - ПоказатьВремя и ПоказатьДату.

Добавляем обработчики команд:

&НаКлиенте
Процедура ПоказатьВремя(Команда)
	
	#Если МобильноеПриложениеКлиент Тогда 
		НовВз = Новый ЗапускПриложенияМобильногоУстройства();
    	НовВз.Действие="ru.w0rm.intent.action.showtime";
    	НовВз.Запустить(Истина);
	#КонецЕсли

КонецПроцедуры

&НаКлиенте
Процедура ПоказатьДату(Команда)
	
	#Если МобильноеПриложениеКлиент Тогда 
		НовВз = Новый ЗапускПриложенияМобильногоУстройства();
    	НовВз.Действие="ru.w0rm.action.showdate";
    	НовВз.Запустить(Истина);
	#КонецЕсли

КонецПроцедуры

В обработчике и указываем Action из форм Java. По ним и будут вызываться необходимые нам Activity.

Открываем Рабочую область начальной страницы и выбираем нашу Начальную форму.

Публикуем мобильное приложение и запускаем. Видим, что при нажатии на кнопки у нас вызываются окна из мобильного приложения написаного на Java.

В следующей части  //catalog.mista.ru/public/613225/ рассмотрим как передавать значения в1С из приложения Java.

Спасибо за внимание!

 

Скачать файлы

Наименование Файл Версия Размер
1С Мобильное приложение и приложение Java. Совместная работа через Intent. Часть 1. Запуск приложения Java из 1С:
.zip 25,50Mb
20.04.17
5
.zip 1.0.1 25,50Mb 5 Скачать

См. также

Комментарии
1. Дмитрий Васильев (user621724_Dimav1979) 211 20.04.17 09:41 Сейчас в теме
Задавайте вопросы. С удовольствием отвечу.
AlexGroovy; dj_serega; smirnov.es; +3 Ответить
4. Сергей Сячин (SyachinS) 20.04.17 10:31 Сейчас в теме
5. Дмитрий Васильев (user621724_Dimav1979) 211 20.04.17 10:38 Сейчас в теме
2. asd asd (user738101) 20.04.17 10:06 Сейчас в теме
3. Дмитрий Васильев (user621724_Dimav1979) 211 20.04.17 10:11 Сейчас в теме
6. Кирилл Власов (neikist) 20.04.17 11:08 Сейчас в теме
Спасибо за статью, вечерком почитаю. Сейчас мельком пробежался по началу статьи и один вопрос возник: почему обработчики кнопкам не в разметке назначаете, а программно? С java и андроидом не особо разбирался, но по моему так разве что какие то анонимные обработчики передавать смысл есть (если это возможно, а судя по тому что нагуглил - невозможно), а явно задаваемые наверно все же лучше в xml описать. Например у меня как у полного чайника сразу вопрос появился: как повесить разные обработчики на кнопки? Судя по тому что нагуглил - нужно реализовать под каждый обработчик объект с соответствующим интерфейсом и его как обработчик устанавливать, другого способа не нашел: https://developer.android.com/reference/android/view/View.OnClickListener.html

Но это так, из разряда придирок мелких.
9. Дмитрий Васильев (user621724_Dimav1979) 211 20.04.17 15:15 Сейчас в теме
(6) спасибо Кирилл за вопрос. По обработчикам Java почитайте StartAndroid
10. Кирилл Власов (neikist) 20.04.17 16:44 Сейчас в теме
(9) странно как то что по ссылке не описано задание обработчиков в разметке, например здесь показаны оба способа как в коде, так и в разметке, в свое время почитал немного данный ресурс чтобы хоть какое то представление иметь.
11. Денис Козлов (Akbis) 47 21.04.17 08:41 Сейчас в теме
(10) Программно боле гибче, если понадобится переназначать. Ну здесь можно было и в разметке задать.
12. Кирилл Власов (neikist) 21.04.17 20:05 Сейчас в теме
(11) Соглашусь пожалуй, главное не начать набивать эту точку входа десятками вариантов обработок нажатий на разные кнопки, или на одну в разных условиях.
7. Ruslan Ruslan (flyer) 252 20.04.17 11:19 Сейчас в теме
однозначно плюс. жду 2 часть.
8. Дмитрий Васильев (user621724_Dimav1979) 211 20.04.17 13:45 Сейчас в теме
13. Илья Низамов (Region102) 32 26.04.17 07:50 Сейчас в теме
Это все интересно конечно, но было бы интересно тоже самое сделать с service, для 1с-ников - это типа фоновых заданий. Т.е. оправил данные, они там обсчитались, распечатались и еще что-нибудь и вернулся результат в 1С. Приложение 1с вроде слушает broadcast, оно же как-то получает push, но как возвращать данные из сервиса я так и не понял.
14. Дмитрий Кинаш (Dementor) 133 26.04.17 15:01 Сейчас в теме
(13)
Т.е. оправил данные, они там обсчитались, распечатались и еще что-нибудь и вернулся результат в 1С.

Половина ответа в том, как вы собираетесь отправлять данные в сервис. Дело в том, что в мобильной платформе для работы с приложениями Android есть только ЗапускПриложенияМобильногоУстройства (пусть меня поправят, если я ошибаюсь). А этот объект в зависимости от булевского параметра в методе запустить использует или startActivity или startActivityForResult - т.е. никаких startService не предусмотрено вообще, а потому и получение из них данных колбеками или подпиской на "слушанье" тоже не реализовано.

А вот если вы дергаете какую-то активити (возможно даже невидимую), которая стартует сервис, то вы можете продолжить развитие этой темы и сделать обработчик ожидания, который периодически будет дергать вашу активити, которая будет получать данные из сервиса и сообщать назад в 1С.
15. Илья Низамов (Region102) 32 26.04.17 19:41 Сейчас в теме
Просто когда я дергаю активити, идет инициализация bluetooth ККМ и распечатка чека и все это время у меня заместо активити 1С черный экран ). Я пытался запускать сервис и закрывать активити, в принципе получилось, но мне надо получить результат выполнения операции (ok или результат exception).
16. Павел Апарин (taishy) 49 28.06.17 09:17 Сейчас в теме
(15) Я использовал ASyncTask, и теперь вместо черного экрана четкое отображение текущих действий
17. Денис Лупейкин (Lupeykin) 1 04.12.17 07:07 Сейчас в теме
Этот парень реально умеет писать понятно и кратко, талант
Оставьте свое сообщение