JavaTutorialNetwork-中文系列教程-二-

JavaTutorialNetwork 中文系列教程(二)

原文:JavaTutorialNetwork

协议:CC BY-NC-SA 4.0

如何在 Java 中使用 MySQL 连接器

https://javatutorial.net/how-to-use-the-mysql-connector-in-java

java-featured-image

在通过 Java 程序测试 MySQL 连接之前,我们需要将 MySQL JDBC 库添加到类路径中。 我们将需要从下载页面下载mysql-connector-java-*.jar文件:

Jar file downloads page mySQl for Java

现在,根据您的工作环境(例如 Eclipse 或命令行),您将必须执行以下任一操作:

  1. 如果使用 Eclipse IDE,请将 JAR 文件作为库添加到项目属性中的“构建路径”。
  2. 如果使用命令控制台,请在执行应用程序时在-cp-classpath参数中指定 JAR 文件的路径。

命令行执行的示例如下所示:

java -cp .;/xxx/xxx/xxx/mysql-connector-java-*.jar com.nameapp.ClassName

现在我们已经澄清了这一点,让我们从 Java 类连接到 MySQL 数据库。

在 Eclipse 中创建项目,然后右键单击项目名称并选择“属性”。 之后,转到“Java 构建路径”并通过单击“添加外部 JAR ..”添加.jar文件。 您可以查看以下图像以显示步骤:

(1)

Properties Eclipse Java Project

(2)

Add External JAR file in Eclipse IDE Java Spring

做完了 现在我们添加了 JAR 文件,是时候创建我们的 MySQL 数据库了。 我假设您已经下载了 MySQL 工作台。 如果不是,请从此处下载。

要创建数据库,只需键入

create database demoapp;

create database mysql java

然后,要验证确实已创建数据库,请键入

show databases;

您应该看到类似以下的内容:

show databases mysql java spring

如您所见,demoapp显示为数据库。

现在,最后一步是测试 Java 类与该数据库的连接。

这是一个带有主要方法的示例 Java 类,该方法尝试建立与数据库的连接:

package mysqlconnection.mysqlconnection;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class App 
{
    public static void main( String[] args )
    {
        String url = "jdbc:mysql://localhost:3306/demoapp";

        String username = "root";
        String password = "admin123";

        // try to establish the connection to the database
        try {
        	Connection connection = DriverManager.getConnection(url, username, password);
        	System.out.println("Connection established successfully!");
        }
        // if the connection couldn't be established raise an exception
        catch (SQLException e) {
        	throw new IllegalStateException("Unable to connect to the database. " + e.getMessage());
        }
    }
}

输出

Connection established successfully mysql java

现在忽略警告。

细分

我们将本地主机的 url 存储在一个名为url的变量中。 jdbc部分是 API, demoapp是数据库的名称。 然后,我们存储用户名和密码。 这里的主要注意事项是,密码必须与安装 MySQL 时选择的密码相同。 之后,我们有一个Try {} Catch {}块。 如果无法建立数据库连接,则将执行catch块。 在try块中,我们获得 url 和用户名/密码的连接。 之后,我们只需打印“连接成功建立!”。

只是一件事 - 如果您忘记在项目的构建路径中添加.jar 文件,则将无法建立连接,并且catch将被执行。 因此,请不要忘记添加 JAR 文件,这一点非常重要。

安卓

安装和配置 Android Studio

原文: https://javatutorial.net/install-configure-android-studio

本教程说明并指导您如何在 Windows 中安装和配置 Android Studio。

Android Studio

众所周知,Android 世界正日趋增长。 数十亿个 Android 应用已在 Google Play 商店中发布。 因此,需要时间来学习 Android 开发的一些基础知识。 Android Studio 是用于 Android 应用程序开发的 IDE(集成开发环境)。

Android Studio 的功能

以下是 Android Studio 的一些有趣功能:

  • 它提供了一个基于 Gradle 的灵活构建系统。
  • 它还支持 C++ 和 NDK
  • 在不构建新 APK 的情况下运行您的应用。
  • 提供虚拟设备来运行和测试您的应用

安装

请按照以下步骤完整安装和配置 Android Studio。

步骤 1)下载 Android Studio

您可以从链接下载 Android Studio,或转到 developer.android.com 主页并搜索下载内容。 选择适用于 Windows,Mac 或 Linux 的适当平台。 以下是 Windows 操作系统的先决条件。

前提条件

  • Microsoft Windows 7/8/10(32 或 64 位)
  • 最低 3GB RAM(建议 8GB)
  • 2GB 磁盘空间
  • 最小 1280 x 800 屏幕分辨率
  • 英特尔加速仿真器处理器
  • Android SDK

注意:如果您没有 Android SDK,则可以通过 Android Studio 下载。 转到下载页面的末尾,找到android-studio-bundle-162.4069837-windows.exe,其中还包含 SDK。

步骤 2)运行.exe文件

现在,下一步是启动您刚刚下载的.exe文件。 出现以下屏幕

Step 1: Run .exe file

步骤 1:运行.exe文件

单击“下一步”,然后选择已选中的 Android SDK(如果尚未安装)。 更好的是保留默认设置。

确保还检查了 Android 虚拟设备。

Step 2: Choose components

步骤 2:选择组件

下一步是接受许可和协议。 点击“我同意”

Step 3: Accept license

步骤 3:接受许可

下一步是设置安装位置。 在单击“下一步”之前,请确保磁盘具有最小的所需空间。 对于 Android Studio,安装位置必须至少有 500MB 可用空间。 要安装 Android SDK,所选位置必须至少具有 3.25GB 的可用空间。

Step 4: Install location

步骤 4:安装位置

下一步是选择要在其中创建快捷方式的开始菜单文件夹。 如果您不想创建快捷方式,只需标记,不要创建快捷方式

Step 5: Choose start menu folder

步骤 5:选择开始菜单文件夹

然后点击“安装”按钮。

它将开始安装。 完成后,将出现以下窗口。

Step 6: Finish

步骤 6:完成

这将通知您安装已完成。 单击“完成”。 确保已选中“启动 Android Studio”。 将出现以下 Android Studio 的初始屏幕。

Step 7: Android Studio Splash Screen

步骤 7:Android Studio 启动画面

步骤 3)配置 Android Studio

首次运行时,系统会要求您提供 Android Studio 设置。

Step 8: Import settings

步骤 8:导入设置

如果您之前没有任何设置,请点击第二个选项(我没有 Studio 的早期版本,或者我不想导入设置)。

选择一个主题,然后单击下一步。

Step 9: Select theme

步骤 9:选择主题

在第一次运行时,它需要下载一些必要的组件,直到完成。

Step 10: Download components

步骤 10:下载组件

一切都完成了。

Step 11: Done

步骤 11:完成

点击“完成”并开始构建您的 Android 应用。

Android Studio 用户界面简介

Android Studio 是一个集成开发环境(IDE)。 您已经在本教程中看到了下载和安装。 让我们学习一些 Android Studio 的基础知识。 这是一个正在运行的 Android Studio 的屏幕截图。

Android Studio screen

Android Studio 屏幕

红色标记显示

1:工具栏 - 它是许多工具的集合,如剪切,复制,粘贴,运行调试等。

2:导航栏 - 它可以帮助您浏览项目的最近打开的文件。

3:项目层次结构 - 这是项目文件夹的层次结构。

4:组件树 - 它以树结构的形式显示活动中使用的组件。

5:属性窗口 - 它在屏幕上显示所选项目的属性。

6:布局编辑器 - 它显示图形布局,以及您的应用程序外观。

7:“调色板”窗口 - “调色板”窗口显示了 Android Studio 中可用的组件,布局和小部件。

将 Android 设备连接到 Android Studio

原文: https://javatutorial.net/connect-android-device-android-studio

本教程将按照分步说明说明如何将您的 Android 设备连接到 Android Studio。

解释

在 Android Studio 中创建应用非常容易。 那么运行和测试呢? Android Studio 为我们提供了一种方法,可以非常轻松,快速地在手机 Android 设备上运行应用程序。 如果您没有 Android 设备,请放心,Android Studio 会为您提供一个模拟器,它会创建虚拟 Android 设备,因此您无需真正拥有 Android 智能手机就可以运行和发送应用程序文本。 这次,我将向您展示如何将 Android 设备连接到 Android Studio。 因为没有替代品可以在硬件设备上运行您的应用程序。

前提条件

以下是一些先决条件:

  • Android Studio(如果没有它,请参阅先前的教程,以安装 Android Studio)。
  • USB 电缆
  • Android 设备

步骤 1)启用 USB 调试

第一步是在 Android 设备上启用 USB 调试。 为此,请按照下列步骤操作

  • 在手机(或平板电脑)上,转到“设置 => 关于手机”
  • 轻按“内部版本号” 7 次,第 7 次之后将显示“您现在是开发人员”。

Step 1: USB debugging

步骤 1:USB 调试

  • 您会注意到“开发人员的选项”现在可用。

Step 2: USB debugging

步骤 2:USB 调试

  • 转到“开发人员选项”并启用“USB 调试”

Step 3: USB debugging

步骤 3:USB 调试

单击“确定”。

Step 4: USB debugging

步骤 4:USB 调试

步骤 2:安装 USB 驱动程序

下一步是为您的 Android 设备安装 USB 驱动程序。 为此,请遵循设备制造商的说明。 例如,我正在使用华为的 Android 智能手机,因此我只是从他们的官方网站下载了华为 USB 驱动程序。 如果您的设备使用 Google USB 驱动程序,则可以从此链接 http://developer.android.com/sdk/win-usb.html 下载。 安装后,您需要对其进行更新。 确保您的设备通过 USB 电缆连接。 转到“控制面板 => 设备管理器”,然后找到并右键单击您的 Android 设备,然后单击“更新驱动程序软件”。

注意:确保通过 USB 电缆连接时,Android 设备未处于睡眠状态。

步骤 3:运行您的应用

您可以运行您的 Android 应用。 右键单击该应用程序,然后单击“运行”。 或者只需从下面显示的工具栏菜单中选择运行选项。

Android Studio screen

Android Studio 屏幕

将出现一个窗口“Select Deployment Target”,并出现可用设备的列表。 选择您的设备,然后单击“OK”。 Android Studio 将在您的 Android 设备上运行您的应用程序。

Deployment target

部署目标

如果您想保存此设置供以后的应用程序,请单击“将相同的选择用于以后的启动”。

参考文献

官方 Android OEM 驱动程序安装指南

适用于 Windows 的 Samsung Android USB 驱动程序

LG Android USB 驱动程序

Android 简介,活动,意图,服务,布局

原文: https://javatutorial.net/introduction-android-activities-intents-services-layouts

本教程将教您一些 Android 基础知识,因此您可以轻松制作自己的第一个 Android 应用。

Android 简介

Android 是适用于多种不同设备的操作系统,例如平板电脑和智能手机。 它基于 Google 维护的 Linux。 统计数据显示,目前全球每月有 20 亿台活跃的 Android 设备。 Android 是功能强大的操作系统,具有许多不同的功能。

消息传递:它允许 SMS 和 MMS。

浏览: Android 的网络浏览器基于 WebKit 布局引擎。 它允许浏览。

用户界面:Android 提供了醒目的且易于使用的用户界面。

触摸屏输入:Android 支持简单和多点触摸系统。

3G 通信协议:它提供​​3G,4G 和 5G 通信协议以通过网络进行通信。

让我们谈谈内部工作,如何创建应用屏幕。

Android 活动

活动类是 Android 的重要组成部分。 活动就像带有用户界面的单个屏幕一样,就像 Java 的框架一样。 我们知道任何用 Java 或 C++ 编写的可执行程序都具有main()方法,并且程序是通过main()方法启动的。 代替主要方法,Android 具有不同的活动概念

大多数应用程序包含多个屏幕,这意味着它们具有多个活动。 活动已在应用的清单文件中注册。 每个活动都有其自己的生命周期,您必须正确管理。

这是一个活动示例。 有关 Android 活动的更多详细信息和全面说明,请阅读我们的 Android 活动示例

package com.example.admin.app;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {

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

Android 意图

目的使我们能够在组件之间进行通信。 意图就像一条消息,用于从另一个组件请求操作。 它用于不同应用程序中的代码之间的运行时绑定。

Android intents

Android 意图

意图有两个基本组成部分

数据:要传送的数据。

操作:要执行的操作。

有两种主要类型的意图,显式意图和隐式意图。

<intent-filter>
                 <action android:name="android.intent.action.INSERT" />
                 <category android:name="android.intent.category.DEFAULT" />
                 <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
             </intent-filter>

转到我们的 Android Intent示例,以了解有关 Android Intent的更多信息

Android 服务

服务是没有用户界面的组件,可以执行长时间运行的操作。 Android 中有两种服务。

服务:由于它是 Android 后台服务的基类,因此它在主线程中运行。

意图服务:它在单独的线程中运行,并且已自毁。

查看我们的 Android 服务示例,以了解有关 Android 服务的更多信息

Android 布局

布局是视觉组件在框架中的排列。 Android 支持许多不同的布局,例如线性布局,相对布局和 Web 视图是最常用的布局。 您还可以混合布局以将所需的设计应用于 Android 应用程序。

Android Studio layouts

Android 布局

线性布局:将组件组织成单个水平或垂直行。 完整示例可在这里找到

相对布局:它指定组件相对于彼此的位置。 完整示例可在这里找到

Web 视图:用于网页。 完整示例可在这里找到

创建一个简单的 Android 应用

原文: https://javatutorial.net/creating-simple-android-app

本教程介绍了如何在 Android Studio 中创建简单的 Android 应用。

在 Android Studio 中创建应用非常容易。 在开始实际编程之前,请确保已正确设置环境和 Android SDK 路径。 您可以按照本教程中的步骤进行操作。 让我们从头开始。

创建 Android 项目

创建一个新项目。

  • 转到“文件菜单 => 新建”,然后选择“新建项目”。
  • 输入应用程序名称,然后选择项目的位置。单击,然后单击。(应用程序名称将在您的应用程序中显示为顶部横幅)。

Step 1: New Application

步骤 1:新应用

  • 为您的项目选择“目标设备”,然后单击“Next”。

Step 2: Target Android Device

第 2 步:定位 Android 设备

  • 然后为您的项目选择一个活动。 因为这是基本教程,所以我选择一个空的活动。

Step 3: Add activity

步骤 3:添加活动

  • 下一步是命名活动和活动的布局。 (活动是 java 类,您将在其中进行所有编码,而布局是 xml 格式的设计)。

Step 4: Customize activity

步骤 4:自订活动

  • 单击“完成”。
  • 这是一个空的活动的样子

Project screen

项目画面

项目的层次结构

首先,探索您应用的层次结构

Project Hierarchy

项目层次结构

  • xml:它定义应用程序的属性。
  • layout:布局文件夹包含所有布局文件,用于设计应用程序的形状和外观。
  • values:此文件夹包含其他 xml 文件,例如strings.xmlstyles.xmlcolors.xml。 这些资源文件对于项目的代码和样式很有用。
  • Java:此文件夹包含所有 Java 类。
  • gradle:它包含SDKversionapplicationIdBuilToolVersion

现在开始编码。

创建界面

打开布局文件,然后单击“设计”视图。

面板窗口中将文本视图拖到屏幕上。 单击Textview,然后可以在属性窗口中更改其属性,如字体大小,字体颜色。

同样,也拖动文本字段和按钮并将其排列。 设置其属性,使屏幕如下所示。

Design screen

设计画面

在单击按钮后出现另一个textview。 它应该为空(无文本)。

如果您不喜欢这种拖放选项,则可以随时进行编码。 转到您的布局文件夹,然后打开此活动的布局文件。 它在 xml 中。 使用拖放界面时,它将自动更新。 这是现在的样子。

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout android:layout_width="368dp"
    android:layout_height="495dp"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="horizontal"
    tools:layout_editor_absoluteX="8dp"
    tools:layout_editor_absoluteY="8dp"
    android:weightSum="1"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <RelativeLayout
        android:layout_width="390dp"
        android:layout_height="509dp">

        <TextView
            android:id="@+id/textView4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_alignParentTop="true"
            android:layout_marginLeft="13dp"
            android:layout_marginStart="13dp"
            android:layout_marginTop="104dp"
            android:text="Enter Name:"
            android:textColor="@android:color/black"
            android:textSize="24sp" />

        <EditText
            android:id="@+id/editText4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="11dp"
            android:ems="10"
            android:inputType="textPersonName"
            android:text="Name"
            android:layout_alignBaseline="@+id/textView4"
            android:layout_alignBottom="@+id/textView4"
            android:layout_toRightOf="@+id/textView4"
            android:layout_toEndOf="@+id/textView4"
            android:layout_marginStart="11dp" />

        <Button
            android:id="@+id/button3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignEnd="@+id/editText4"
            android:layout_alignRight="@+id/editText4"
            android:layout_below="@+id/editText4"
            android:layout_marginEnd="41dp"
            android:layout_marginRight="41dp"
            android:layout_marginTop="46dp"
            android:onClick="ShowMessage()"
            android:text="OK" />

        <TextView
            android:id="@+id/textView5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/editText4"
            android:layout_alignStart="@+id/editText4"
            android:layout_below="@+id/button3"
            android:layout_marginTop="56dp"
            android:textColor="@android:color/black"
            android:textSize="24sp" />
    </RelativeLayout>
</LinearLayout>

用 Java 类编写代码

现在打开MainActivity.java并将操作监听器添加到您的按钮。

这是添加动作监听器的方法。

package com.example.admin.example;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    Button  button = null;
    TextView textView = null;
    EditText editText = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = (Button)findViewById(R.id.button3);
        textView = (TextView) findViewById(R.id.textView5);
        editText = (EditText) findViewById(R.id.editText4);
        final String name = editText.getText().toString();
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            textView.setText("Hello "+name+"\nWelcome to JavaTutorial");
            }
        });
    }
}

以下是屏幕快照的工作原理。

Application screen

应用画面

当用户单击“确定”按钮时,将执行动作监听器,并说“欢迎”。

Application screen

应用画面

阅读本教程,立即开始制作您的第一个应用程序。 您可以从链接下载完整的项目。

运行和调试 Android 应用程序

原文: https://javatutorial.net/running-debugging-android-applications

在上一教程中,您学习了如何创建一个简单的 Android 应用。 本教程将说明如何在 Android Studio 中运行和调试 Android 应用程序。

解释

Android Studio 具有自己的默认运行/调试配置,足以满足我们的需求。 但是,如果要创建自己的配置或修改默认配置,也可以使用它。 当您在硬件设备上运行应用程序时,Android Studio 会为您的应用程序创建一个 APK 文件,然后在您的设备上安装并运行。 它为您处理大部分细节。 在 Android Studio 中运行和调试应用非常容易。 开始吧。

运行 Android 应用程序

请按照以下步骤运行您的应用程序。

  • 在 Android Studio 中打开您的应用。
  • 在运行/调试配置页面上,输入配置名称并选择模块(如果您不想使用默认的运行/调试配置,则此步骤是可选的)。
  • 设置您的 Android 设备,确保已安装适当的 USB 驱动程序,启用 USB 调试并选择部署目标(有关更多详细信息,请参见前面的教程如何配置 Android 设备)。
  • 单击菜单栏上的“运行”图标,或通过右键单击根文件夹来运行您的应用,然后选择“运行”。
  • 我运行了本教程的上一个示例(一个简单的 Android 应用)。 这是结果
  • 我的设备显示在部署目标窗口中。 选择它并运行。

Select Deployment Target

选择部署目标

它将开始在您的设备中安装您的应用程序。 在这里安装后,它会创建快捷方式。

App shortcut

应用程式捷径

App running on Android device

在 Android 设备上运行的应用

App running on Android device

在 Android 设备上运行的应用

调试 Android 应用程序

调试是发现错误的过程。AndroidStudio 还提供了一种机制,可以调试在虚拟 Android 设备或硬件 Android 设备上运行的应用。 Android 调试器提供以下功能。

  • 选择设备来调试您的应用
  • 在代码中设置断点
  • 在运行时检查表达式流。
  • 允许捕获屏幕截图和视频

在开始调试之前,请确保该构建变量将debuggable属性设置为true

为此,转到“构建 => 选择构建变量”。 要开始调试,请单击菜单栏上的“调试”图标。 在 Android 设备上构建并安装后,它将打开调试窗口。

  • 选择屏幕菜单上的调试图标。
  • 在“部署目标”窗口中选择您的设备。
  • 然后选择要附加到调试器的进程。

Choose process

选择进程

  • 单击“确定”。
  • 您将看到调试窗口,控制台将显示已连接到设备。

Console message

控制台消息

下图显示了调试器窗口,其中显示了当前线程。

Debugger window

调试器窗口

单击“终止”以终止调试会话。

在虚拟设备上运行 Android 应用程序

原文: https://javatutorial.net/run-android-application-virtual-device

本教程介绍了如何配置虚拟设备以及如何在 Android 虚拟设备上运行应用程序。

背景

在上一教程中,您已经了解了如何在硬件 Android 设备上运行和调试 Android 应用。 如果您没有 Android 硬件设备,则无需购买。 Android Studio 为我们提供了对虚拟 Android 设备的支持。 本教程全部关于 Android 虚拟设备。

Android 虚拟设备

Android SDK 包含 Android 虚拟设备(AVD)或称为移动设备模拟器。 它使您无需使用 Android 硬件设备即可在计算机上开发,测试和运行 Android 应用程序。 多核处理器使其快速,强大且功能丰富。

在 Android 虚拟设备上运行的应用

您可以使用 Android Studio 在 Android 虚拟设备上运行应用程序,或者如果您有应用程序的 APK 文件,则可以直接在模拟器上拖动该文件以运行它。 如果要通过 Android Studio 运行,请执行以下步骤。

  • 在 Android Studio 中打开您的项目(如果没有该项目,则可以按照本教程的进行创建
  • 单击菜单栏中的“运行”图标,或右键单击项目的根目录,然后单击“运行”。
  • 将出现一个新窗口,用于选择部署目标(如果您是第一次使用,可能会遇到一个错误,提示某些必需的文件丢失了,您可以通过单击“下载”按钮进行下载)。

Select deployment target

选择部署目标

  • 它显示了可用虚拟设备的列表。 您可以选择任何人。
  • 如果要使用此部署目标,请始终仅单击“对以后的启动使用相同的选择”。
  • 点击“确定”
  • 如果看不到任何必需的虚拟设备,则可以为您创建一个。
  • 在菜单栏中选择“AVD 管理器”。

create virtual device

创建虚拟设备

  • 单击“创建虚拟设备”
  • 从列表中选择硬件,然后单击“下一步”

Select hardware

选择硬件

  • 选择“系统映像”(选择推荐的一个),然后单击“下一步”

System Image

系统映像

  • 验证配置,然后单击“完成”

Verify configuration

验证配置

  • 现在,单击“运行”,然后选择新创建的虚拟设备作为目标设备。
  • 仿真器将以以下方式启动

Loading emulator

加载模拟器

  • APK 文件将被安装。

Emulator

仿真器

  • 它将以

App on emulator

在模拟器上的应用

Android Studio 还允许我们自定义您的模拟器。 您可以在仿真器右侧看到一个垂直菜单栏。 这用于自定义您的应用,例如更改方向,音量设置,拍照等。 因此,您可以使用 Android 虚拟设备轻松,快速地运行,调试应用。

Android 活动示例

原文: https://javatutorial.net/android-activity-example

本教程介绍了什么是 Android 中的活动,活动周期和示例。

Android 活动

Activity是 Android 应用程序开发的基本组成部分之一。 就像带有用户界面的单个屏幕一样。 ContextThemeWrapper是 Android 活动的超类。 活动是 Android 应用程序的主要切入点,就像用 Java 或 C++编写的程序的主要方法一样。 一个活动与用户进行交互,因此它创建了一个放置 UI 元素的窗口。 一个 Android 应用程序可以包含多个活动,这意味着可以相互交互的许多不同屏幕。

活动生命周期

在 Android 应用程序中,Android 活动具有其自身的生命周期。 活动存储和管理在称为活动栈的栈中。 新活动位于栈顶部并开始运行,而以前的活动则位于栈中新活动的下方。 当栈中的顶部活动退出时,从下至上的活动将变为活动状态。

Android 活动状态

一个活动有四个状态

正在运行:栈顶部的活动处于运行或活动状态,表示该活动位于屏幕的前台。

已暂停:处于活动状态但未专注的活动处于暂停状态。 (这是活动中显示的弹出消息)。

恢复:暂停的活动变为活动状态后,它将刷新并重新开始。

已停止:在屏幕上不再可见的活动处于停止状态。

调用 Android 活动的方法

Android 活动实现以下回调方法

OnCreate():这是 Android 活动的第一个回调方法。 创建活动时调用它。 在这里,您可以设置所有东西,例如按钮和视图。

OnStart():这是第二次回调。 当活动在屏幕上可见时调用。

OnResume():如果活动进入前台,则在OnStart()之后调用。 这是用户开始与活动进行交互的时间。

OnPause():然后是OnResume()。 恢复上一个活动时将调用此方法。

OnStop():当另一个活动恢复时该调用不再可见。 它变得隐藏了。

OnDestroy():这是活动完成时的最后一次回调。

下图显示了 Android 活动的完整生命周期。

Android activity life cycle

Android 活动生命周期

图中的矩形代表 6 种回调方法。

Android 活动示例

这是 Android 活动的示例。 打开您的 Android Studio 并创建一个新项目。 新建项目向导将允许您创建一个新的活动。 您可以在“创建简单的 Android 应用程序”教程中找到有关如何创建新 Android 项目的更多信息。

package com.example.admin.androidactivity;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;

public class ActivityExample extends AppCompatActivity {

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

}

这是示例代码,您可以下载

Android 意图示例

原文: https://javatutorial.net/android-intent-example

本教程通过示例说明了 Android 的意图,类型和方法。

Android 意图

意图是用于向另一个组件请求操作的对象。 目的是一种数据结构,其中包含要执行的操作的抽象描述。 它用于从其他 Android 组件请求功能。 简而言之,意图是做某事的意图。 通过使用意图,我们可以做很多事情,例如从一个活动转到另一个活动,通过相机应用程序拍照,网络搜索,在地图上搜索位置等等。 这使开发人员可以轻松地重新混合不同的应用程序。

意图类型

有两种类型的意图,显式和隐式意图。

显式意图

在显式意图中,目标组件名称在创建意图时直接传递到意图中。 当一个活动调用另一个活动时,通常使用显式意图。 例如,我们有两个活动 - 登录活动和主页活动,登录应用程序将用户带到主页后,请参见下图。

Explicit intent

显式意图

这是在登录活动中应如何调用的代码。

Intent intent = new intent(this, homepageActivity);
startActivity(intent);

隐式意图

在显式意图中,目标组件名称在创建时不会在意图中传递。 Android 自行决定应在哪个应用程序的哪个组件中接收此意图。 显式意图用于激活其他应用程序中的组件。

例如,如果您的应用程序需要打开手机中的联系人(此意图需要另一个应用程序即手机中的联系人),那么代码将如下所示

Intent intent = new Intent();
Intent.setAction(android.content.intent.ACTION_VIEW);
Intent.setDeta(ContactsContract.Contacts.intent.CONTENT_URI);
startActivity(intent);

因此,它将如下所示打开 Android 联系人

Android contacts

Android 联系人

目标方法

有用于向活动,服务和广播接收者传达意图的单独机制。 这是几种方法的解释

Context.startActivity():此方法用于启动新活动,目的是作为参数传递的。

Context.startService():此方法用于启动新服务,目的对象作为参数传递。

Context.sendBroadcast():此方法用于将消息发送到任何广播接收器。 意图对象作为参数传递。

意图对象有两个主要组成部分。

动作:显示要执行的动作。 它是意图对象的必修部分。 要执行的动作可以是ACTION_VIEWACTION_EDIT等。

数据:它显示要操作的数据。 它可以是简单的数据类型或 URI。

意图的示例

这是一个显示意图的示例。 转到您的 Android Studio 并创建一个新项目。 本示例将在您的 Android 中打开javatutorial.net

这是activity_main.xml

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout android:layout_width="368dp"
    android:layout_height="495dp"
    xmlns:tools="http://schemas.android.com/tools"
    tools:layout_editor_absoluteX="8dp"
    tools:layout_editor_absoluteY="8dp"
    xmlns:android="http://schemas.android.com/apk/res/android">

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="202dp"
            android:text="Visit JavaTutorial.net" />
    </RelativeLayout>

这是ActivtyMain.java

package com.example.admin.intentexample;

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

public class MainActivity extends AppCompatActivity {

    Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = (Button)findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent i = new Intent(android.content.Intent.ACTION_VIEW,
                Uri.parse("http://www.javatutorial.net"));
                startActivity(i);
            }
        });
    }
}

这是它的样子

intent example

意图示例

Choose browser

选择浏览器

Java Tutorial

Java 教程

您可以从链接下载此代码。

Android 服务示例

原文: https://javatutorial.net/android-service-example

本教程介绍了 Android 中的服务及其生命周期,并提供了有关如何创建服务的示例。

Android 服务与 Android 活动有很大不同。 这是 Android 应用程序开发的概念。 让我们讨论一下。

Android 服务

服务用于实现或执行在我们的应用中运行的后台操作。 它是一个应用程序组件,用于执行长时间运行的重要后台任务,例如播放音乐,下载文件或执行网络事务。 由于服务在后台运行,因此与活动不同,它没有任何用户界面。 它使我们能够在应用程序中启用多任务处理。 尽管应用程序已关闭或服务已完成工作或已明确停止,但服务仍在后台继续运行。 因此,它比不活动的应用程序具有更高的优先级。 您还可以将其设置为与正在运行的前台任务相同的优先级。 让我们讨论一下服务类型。

Android 服务的类型

Android 中提供三种不同类型的服务。

调度:在诸如jobScheduler之类的 API 中计划了一项服务,然后将其称为计划服务。 系统检查jobScheduler并在适当的时间执行服务。

启动:如果服务可以由应用程序组件启动,则将其称为已启动服务。 活动调用startService(0方法,然后在后台运行。 通常,此服务执行单个操作。

绑定:如果应用程序组件将服务绑定到bindService(),则称为绑定。 它具有一个客户端服务器接口,该接口允许组件与服务进行交互。

Android 服务的生命周期

Android 服务生命周期与 Android 活动完全不同。 如果使用startService()创建服务或使用bindService()创建服务,则其生命周期可能会有所不同。 下图显示了两个生命周期。

Life cycle of service

服务生命周期

让我们讨论服务生命周期的回调方法。 当使用startService()创建服务时,将调用OnStartCommand()方法。 执行此方法后,服务星将在后台运行。 如果使用此方法创建了服务,请通过调用stopSelf()stopService()方法将其停止。 如果服务是有界的,则使用OnBound()方法。 其他组件使用此方法将自己与服务绑定。OnCreate()方法用于创建服务。OnDestroy()方法用于销毁服务。

Android 中的服务示例

这是 Android Studio 中的服务示例。 打开您的 IDE 并创建一个新项目。 创建活动并将其命名为actvity_main,这是activty_main.xml的代码

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout android:layout_width="368dp"
    android:layout_height="495dp"
    xmlns:tools="http://schemas.android.com/tools"
    tools:layout_editor_absoluteX="8dp"
    tools:layout_editor_absoluteY="8dp"
    xmlns:android="http://schemas.android.com/apk/res/android">

        <Button
            android:id="@+id/buttonStart"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="122dp"
            android:text="Button"
            tools:text="Start Service" />

        <Button
            android:id="@+id/buttonStop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/buttonStart"
            android:layout_alignStart="@+id/buttonStart"
            android:layout_below="@+id/buttonStart"
            android:layout_marginTop="36dp"
            android:text="Button"
            tools:text="Stop Service" />

        <Button
            android:id="@+id/buttonNext"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="44dp"
            android:text="Button"
            tools:text="Next"
            android:layout_below="@+id/buttonStop"
            android:layout_centerHorizontal="true" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="47dp"
        android:text="TextView"
        android:textColorLink="@android:color/black"
        android:textSize="24sp"
        tools:text="javaTutorial.net" />
</RelativeLayout>

这是MainActivity.java的代码

package com.example.admin.androidservice;

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 {

    Button buttonStart, buttonStop,buttonNext;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        buttonStart = (Button) findViewById(R.id.buttonStart);
        buttonStop = (Button) findViewById(R.id.buttonStop);
        buttonNext = (Button) findViewById(R.id.buttonNext);

        buttonStart.setOnClickListener(this);
        buttonStop.setOnClickListener(this);
        buttonNext.setOnClickListener(this);
    }
    public void onClick(View src) {
        switch (src.getId()) {
            case R.id.buttonStart:
                startService(new Intent(this, SecondActivity.class));
                break;
            case R.id.buttonStop:
                stopService(new Intent(this, SecondActivity.class));
                break;
            case R.id.buttonNext:
                Intent intent=new Intent(this,SecondActivity.class);
                startActivity(intent);
                break;
        }
    }
}

为另一个屏幕创建另一个活动,然后为其命名。 打开activity_second.xml并粘贴以下代码

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout android:layout_width="368dp"
    android:layout_height="495dp"
    xmlns:tools="http://schemas.android.com/tools"
    tools:layout_editor_absoluteX="8dp"
    tools:layout_editor_absoluteY="8dp"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="96dp"
        android:layout_marginTop="112dp"
        android:text="Next Page" />

</RelativeLayout>

这是secondActivity.java的代码

package com.example.admin.androidservice;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class SecondActivity extends AppCompatActivity {

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_second);
        }

}

运行并测试它,这是此代码的输出

android service

android 服务

service

服务

您可以从此链接下载代码。

Android 线性布局示例

原文: https://javatutorial.net/android-linear-layout-example

在先前的教程中,您了解了 Android 意图服务活动。 本教程和接下来的几本教程将介绍有关 Android 中不同布局的信息。

布局是事物以特定方式进行排列的方式。 Android 还提供了不同的布局,以不同的方式排列不同的组件。 其中一些是线性布局,相对布局,Web 视图布局等。布局对于 UI 应用程序的开发非常重要。 本教程的主要重点是线性布局。

线性布局

Android 中的线性布局使我们可以将组件水平排列在单列中或垂直排列在单行中。 垂直或水平方向取决于属性android:orientation。线性布局简单易用,如果窗口的长度超过屏幕的长度,则会创建滚动条。 垂直线性布局每行只有一项。 线性布局具有许多不同的属性,可用于根据需要自定义线性布局。 下图显示了水平和垂直线性布局。

Linear layout

线性布局

线性布局的属性

以下是 Android 线性布局的一些属性。

  • Id:布局的唯一标识符。
  • Orientation:用于将线性布局方向设置为垂直或水平的属性。
  • Layout_Weight:此属性在每个组件处分配“重要性”值。
  • Gravity:此属性显示对象在 x-y 平面中的位置,例如中心,右侧,顶部,底部和左侧。
  • Weight_sum:此属性定义最大加权和。
  • Divider:绘图可用作按钮之间的垂直分隔线。

除了这些属性,线性布局还具有许多不同的构造函数。

线性布局的构造函数

以下是线性布局的构造函数

  • LinearLayout(Context context)
  • LinearLayout(Context context, AttributeSet attribute)
  • LinearLayout(Context context, AttributeSet attrs, int styleAttribute)
  • LinearLayout(Context context, AttributeSet attrs, int styleAttribute, int styleRes)

Android 中的线性布局示例

如果为两个线性布局(例如垂直线性布局或水平线性布局)设置了不同的属性值,则线性布局看起来会有所不同。

以下示例显示垂直线性布局。 这是activity_linear_vertical.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="368dp"
    android:layout_height="495dp"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    tools:layout_editor_absoluteX="8dp"
    tools:layout_editor_absoluteY="8dp"
    xmlns:android="http://schemas.android.com/apk/res/android">

        <Button
            android:id="@+id/button5"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Button1" />

        <Button
            android:id="@+id/button6"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Button2" />

        <Button
            android:id="@+id/button7"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Button3" />

        <Button
            android:id="@+id/button8"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Button4" />
    </LinearLayout>

这是输出的样子

linear layout Vertical

垂直线性布局

这是另一个显示水平线性布局的示例。 以下是activity_linear_horizo​​ntal.xml的代码

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout android:layout_width="368dp"
    android:layout_height="495dp"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="horizontal"
    tools:layout_editor_absoluteX="8dp"
    tools:layout_editor_absoluteY="8dp"
    xmlns:android="http://schemas.android.com/apk/res/android">

        <Button
            android:id="@+id/button4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Button4" />

        <Button
            android:id="@+id/button3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Button3" />

        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Button2" />

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Button1" />
    </LinearLayout>

这是输出的样子

linear Layout Horizontal

水平线性布局

您可以从链接下载示例代码。 有关更多 Android 布局,请遵循以下教程。

Android 相对布局示例

原文: https://javatutorial.net/android-relative-layout-example

本教程通过示例说明了 Android 中的相对布局。

Android 中的布局对于基于 GUI 的应用程序非常重要。 在上一教程中,我们学习了线性布局,本教程介绍了 Android 中的相对布局。

相对布局

顾名思义,相对布局显示组件之间的相对位置。 可以相对于连续元素或父组件来指定位置。 相对布局是 Android 提供的最灵活的布局。 它使您可以在屏幕上放置元素。 默认情况下,它将所有组件设置在布局的左上方。 下图显示了相对布局的外观,

relative layout

相对布局

相对布局属性

以下是相对布局的属性。

  • Id:定义布局 ID
  • Gravity*它指定对象在 x-y 平面中的位置。
  • IgnoreGravity:被添加以忽略特定组件上的重力。

相对布局构造函数

相对布局具有四个不同的构造函数

  • RelativeLayout(Contetxt context)
  • RelativeLayout(Contetxt context, AttributeSet attribute)
  • RelativeLayout(Contetxt context, AttributeSet attribute, int defStyleAttribute)
  • RelativeLayout(Contetxt context, AttributeSet attribute, int defStyleAttribute, in defStyleRes)

相对布局的方法

以下是相对布局的几种重要方法

  • setGravity():它将子视图的重力设置为居中,向左或向右。
  • setHorizo​​ntalGravity():用于水平定位元素。
  • setVerticalGravity():用于垂直放置元素。
  • requestLayout():用于请求布局。
  • setIgnoreGravity():用于忽略任何特定元素的重力。
  • getGravity():用于获取元素的位置。
  • getAccessibilityClassName():返回对象的类名称。

相对布局的 XML 属性

相对布局具有以下 XML 属性。

android:layout_above,它将给定组件的底部边缘定位在给定组件 ID 上方。

android:layout_alignBaseline,它将给定组件的基线置于给定组件 ID 的基线之上。

android:layout_alignBottom,它在给定组件 ID 的底部对齐。

android:layout_alignEnd,它在给定组件 ID 的末尾对齐。

android:layout_alignLeft,它将组件定位在给定组件 ID 的左侧。

android:layout_alignRight,将该组件定位在给定组件 ID 的右侧。

相对布局示例

以下示例显示了 Android 中的相对布局。 创建一个空的活动并将相对布局从调色板拖到屏幕上。 然后拖动所需的 GUI 组件。 这是 xml 文件。

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout android:layout_width="368dp"
    android:layout_height="495dp"
    xmlns:tools="http://schemas.android.com/tools"
    tools:layout_editor_absoluteX="8dp"
    tools:layout_editor_absoluteY="8dp"
    xmlns:android="http://schemas.android.com/apk/res/android">

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_alignParentTop="true"
            android:layout_marginLeft="141dp"
            android:layout_marginStart="141dp"
            android:layout_marginTop="89dp"
            android:text="Sign In"
            android:textColor="@android:color/black"
            android:textColorLink="@android:color/black"
            android:textSize="28sp" />

        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="43dp"
            android:text="ID"
            android:textColor="@android:color/black"
            android:textSize="18sp"
            android:typeface="normal"
            android:layout_below="@+id/textView"
            android:layout_alignLeft="@+id/textView5"
            android:layout_alignStart="@+id/textView5"
            android:layout_marginLeft="10dp"
            android:layout_marginStart="10dp" />

        <EditText
            android:id="@+id/editText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ems="10"
            android:inputType="textPersonName"
            android:text="Enter ID"
            android:layout_alignBaseline="@+id/textView2"
            android:layout_alignBottom="@+id/textView2"
            android:layout_alignLeft="@+id/editText2"
            android:layout_alignStart="@+id/editText2" />

    <TextView
        android:id="@+id/textView5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:textColor="@android:color/black"
        android:text="Password"
        android:layout_alignBottom="@+id/editText2"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_marginLeft="32dp"
        android:layout_marginStart="32dp" />

    <EditText
        android:id="@+id/editText2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/editText"
        android:ems="10"
        android:text="Password"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/S"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/editText2"
        android:layout_marginTop="32dp"
        android:text="SignIn" />
</RelativeLayout>

这是输出的样子

relative layout example

相对布局示例

您可以从链接下载源代码。

Android Web 视图示例

原文: https://javatutorial.net/android-web-view-layout-example

在先前的教程中,我们学习了 Android 中的线性相对布局,本教程以示例说明了 Web 视图。

您要在 Android 应用程序中打开网页吗? Android 提供了一种称为 Web 视图,可帮助我们在应用程序中打开网页。

Web 视图

Web 视图用于显示活动中的在线内容。 Web 视图类是 Android 中视图类的扩展。 它不像网络浏览器,因此不提供导航控件和 URL。 Web 工具包呈现引擎显示网页,并允许我们向前和向后导航。 如果要在应用程序中显示一些网页信息,则使用 Web 视图非常普遍。 或者,如果您想提供需要更新的信息(例如用户指南或协议),则可以用作另一种用途。

如果要在应用程序中访问互联网,则必须向清单文件添加INTERNET权限,例如

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

Web 查看方法

以下是 Android 中 Web 视图的方法。

  • addJavascriptInterface(Object object, String name),用于在 Web 视图中注入 JavaScript 代码。
  • canGoBack(),用于转到上一个历史记录项目。
  • canGoBackOrForward(int steps),用于按给定步骤前进或后退。
  • canGoForward(),用于转到下一个历史记录项目。
  • canZoonIn(),用于放大。
  • canZoomOut(),用于缩小。
  • clearHistory(),用于清除 Web 视图的历史记录。
  • clearView(),用于重置 Web 视图和释放资源。
  • destroy(),用于破坏 Web 视图的内部状态。
  • findFocus(),在以当前具有焦点的此视图为根的层次结构中查找视图。
  • freeMemory(),用于释放内存,现在不建议使用此方法。
  • getSettings(),获取 Web 视图的设置。
  • getTitle(),以字符串形式获取当前页面的标题。
  • getURL(),以字符串形式获取当前页面的 URL。
  • goBack(),返回 Web 视图的历史记录。
  • capturePicture(),用于拍摄 Web 视图的位图快照。

Android 中的 Web 视图示例

这是一个示例,显示了如何通过在活动中使用 Web 视图在应用程序中显示javatutorial.net网站。 首先,您需要创建一个新活动。 打开您的activity_main.xml并粘贴此代码。

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout android:layout_width="368dp"
    android:layout_height="495dp"
    tools:layout_editor_absoluteX="8dp"
    tools:layout_editor_absoluteY="8dp"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="53dp"
        android:text="Welcome to JavaTutorial.net"
        android:textColor="@android:color/black"
        android:textSize="24sp" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="44dp"
        android:text="Click Here"
        android:id="@+id/button" />

    <WebView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/button"
        android:layout_marginTop="86dp"
        android:id="@+id/webView"/>
</RelativeLayout>

现在打开mainActivity.java并粘贴此代码

package com.example.admin.webview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {

    Button b1;

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

        b1=(Button)findViewById(R.id.button);

        wv1=(WebView)findViewById(R.id.webView);
        wv1.setWebViewClient(new MyBrowser());

        b1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String url = "https://www.javatutorial.net/";

                wv1.getSettings().setLoadsImagesAutomatically(true);
                wv1.getSettings().setJavaScriptEnabled(true);
                wv1.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
                wv1.loadUrl(url);
            }
        });
    }

    private class MyBrowser extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
    }
}

您的清单文件应该是这样的

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.admin.webview">
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        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>
    </application>

</manifest>

这是此应用程序的输出

web view

网页视图

web view Example

Web 视图示例

您可以通过单击链接下载此代码。

Android 列表视图示例

原文: https://javatutorial.net/android-list-view-example

您已经学习了 Android 的许多其他布局,本教程通过示例说明了 android 中的列表视图。

ListView

您要在应用中显示列表吗? Android 通过提供列表视图布局来解决其问题。 它是一种布局,在垂直可滚动列表中显示项目。 列表中的每个项目都位于列表中上一个项目的下方。 列表项存储在数组中,并由使用适配器从列表中拉出项目,然后将其插入列表。 列表视图是AdapterView的子类。 自定义列表在移动应用程序中非常常见,列表视图提供了一种创建自定义列表的简便方法。 它是最常用的布局之一,例如,当您要显示一组日期时,没有什么比列表更合适的了。 下图显示了列表视图的外观

list view

列表显示

列表视图的属性

这是列表视图的一些重要 XML 属性。

android: divider,它用作绘制能力或颜色,用于在列表项之间绘制。

android: entries,它用于引用数组资源以填充列表视图。

android: headerDividersEnabled,用于在每个标题视图之后绘制分隔线。

android: footerDividersEanabled,用于在每个页脚视图之前绘制分隔线。

列表视图的方法

列表视图有许多公共方法,下面将对其中的一些方法进行说明。

  • getAdapter():返回列表视图中使用的适配器。
  • addHeaderView():用于在列表顶部添加标题视图。
  • getAccessibilityClassName():返回对象的类名。
  • getDivider():返回列表中每个项目之间的分隔符。
  • getDividerHeight():返回分隔线的高度。
  • isOpaque():显示列表是否不透明。
  • removeFooterView(View view):用于删除列表中先前添加的页脚视图。
  • removeHeaderView(View view):用于删除列表中先前添加的标题视图。

列表视图的构造函数

列表视图具有四个不同的公共构造函数,如下所示:

  • ListView(Context context)
  • ListView(Context context, AttributeSet attrs)
  • ListView(Context context, AttributeSet attrs, int defStyleAttr)
  • ListView(Context context, AttributeSet attrs, AttributeSet attrs, int defStyleRes)

列表视图的示例

这是在 Android 中使用列表视图的示例。 它显示了计算机科学中的语言列表。 首先创建一个活动,打开活动_main.xml并粘贴此代码

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

    <ListView
        android:id="@+id/mobile_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

创建另一个布局作为activity_listview.xml并粘贴此代码

<?xml version="1.0" encoding="utf-8"?>
<!--  Single List Item Design -->

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/label"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dip"
    android:textSize="16dip"
    android:textStyle="bold" >
</TextView>

打开您的 MainActivity.java 并使用此代码

package com.example.admin.listviewexample;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class MainActivity extends AppCompatActivity {

    String[] mobileArray = {"Java","C++","C#","CSS",
            "HTML","XML",".Net","VisualBasic", "SQL", "Python", "PHP"};

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

        ArrayAdapter adapter = new ArrayAdapter<String>(this,
                R.layout.activity_listview, mobileArray);

        ListView listView = (ListView) findViewById(R.id.mobile_list);
        listView.setAdapter(adapter);
    }
}

这是输出的样子

list view example

列表视图示例

您可以通过以下链接下载此示例代码。

Android 网格视图示例

原文: https://javatutorial.net/android-grid-view-example

Android 网格视图是许多应用程序中最常用的布局之一。 本教程通过示例说明了网格视图的布局。

GridView

网格视图是 android 中的布局,可让您将组件排列在二维可滚动网格中。GirdView中的组件不一定是静态的,它可以存储在ListAdapter中(适配器就像数据和 UI 组件之间的桥梁)。 下图显示了 android 中GridView的示例。

GridViewAndroid

Android GridView

网格视图在计算器,日历等许多应用程序中非常常见。

网格视图的属性

以下是 Android 网格视图布局的一些 XML 属性。

  • android:gravity,代表每个单元格(如中心,底部,顶部,左侧等)中的重力。
  • android:columnWidth,用于指定每个单元格的列宽。
  • android:horizo​​ntalSpacing,指定网格列之间的水平空间。
  • android:verticalSpacing,用于指定网格行之间的垂直空间。
  • android:numColumns,指定要显示的列数。

网格视图的方法

网格视图有多种使用方法,其中一些在此处说明

  • getAccessibilityClassName():返回对象的类名称。
  • getAdapter():返回与其关联的适配器。
  • getColumnWidth():返回网格上列的宽度。
  • getGravity():返回网格组件的重力,即它们如何水平对齐。
  • getHorizo​​ntalSpacing():返回网格组件之间的水平间距。
  • getNumColumns():获取网格中的列数。
  • setAdapter(ListAdapter adapter):用于在网格视图后面设置数据。
  • setColumnWidth(int columnWidth):用于设置列宽。
  • setGravity(in gravity):用于设置网格组件的重力。
  • setHorizo​​ntalSpacing(int horizo​​ntalSpacing):用于设置水平间距以将项目放置在网格中。
  • setVerticalSpacing(int verticalSpacing):用于设置垂直间距以将项目放置在网格上。

网格视图的构造函数

GridView具有四个不同的公共构造函数,如下所示

  • GridView(Context context)
  • GridView(Context context, AttributeSet attribute)
  • GridView(Context context, AttributeSet attribute, int defStyleAttr)
  • GridView(Context context, AttributeSet attribute, int defStyleAttr, int defStyleRes)

网格视图示例

本示例说明如何在 Android 中使用GridView布局。 如前所述,GridView可以直接使用,也可以与自定义适配器一起使用。 本示例显示了小写和大写英文字母的网格。

打开 Android Studio 并开始创建一个新项目。 创建一个活动并将以下代码粘贴到main_Activity.xml中。

<?xml version="1.0" encoding="utf-8"?>

<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/gridView1"
    android:numColumns="auto_fit"
    android:gravity="center"
    android:columnWidth="80dp"
    android:stretchMode="columnWidth"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
</GridView>

打开mainActivity.java并粘贴此代码

package com.example.admin.gridviewexample;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    GridView gridView;

    static final String[] numbers = new String[] {
            "A", "B", "C", "D", "E",
            "F", "G", "H", "I", "J",
            "K", "L", "M", "N", "O",
            "P", "Q", "R", "S", "T",
            "U", "V", "W", "X", "Y", "Z", "\n","\n","\n","\n",
            "a", "b","c","d","e",
            "f","g","h","i","j",
            "k","l","m","n","o",
            "p","q","r","s","t",
            "u","v","w","x","y",
            "z"};

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        gridView = (GridView) findViewById(R.id.gridView1);

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, numbers);

        gridView.setAdapter(adapter);

        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v,
                                    int position, long id) {
                Toast.makeText(getApplicationContext(),
                        ((TextView) v).getText(), Toast.LENGTH_SHORT).show();
            }
        });

    }

}

这是输出的样子

grid view example

网格视图示例

您可以通过单击链接下载此代码。

带有ListAdapter的 Android ListView示例

原文: https://javatutorial.net/android-listview-with-listadapter-example

在上一个教程中,我们通过一个简单的示例了解了列表视图布局。 本教程介绍了用于创建自定义列表的列表适配器。

Android ListAdapter

列表视图非常简单,您要自定义列表吗?ListAdapter用于自定义列表视图的布局。 它的行为就像是数据源和列表视图之间的桥梁。 它的父类是BaseAdapter。 当您要为列表中的各个行指定布局时使用。 不要将其与ArrayAdapter混淆,ListAdapter是一个接口,而ArrayAdapter是可处理数据数组的类。 下图显示了使用ListAdapter的自定义列表视图。

List Adapter

列表适配器

ListAdapter构造函数

ListAdapter的构造方法采用一个参数,该参数指定每一行的布局资源。 除此之外,它还有两个参数(这两个参数通常是并行数组),使我们能够指定将哪个数据字段与行布局资源中的哪个对象相关联。

ListAadapter的方法

ListAdapter具有以下公共方法。

  • areAllItemsEnabled():它通过返回布尔值来告知是否启用列表适配器中的所有项目。 如果返回true,则表示所有项目都是可选择和可单击的。 如果返回不同的值(如果值更改),则不能保证它将生效。
  • isEnabled(int position):如果可以单击并选择位于特定位置的项目,则返回true。如果给定的位置无效,则无法指定结果。

ListAdapter的示例

让我们开始使用ListAdapter进行编码。在列表视图的先前教程中,已经讨论了计算机科学语言的简单示例。 这被显示为简单列表。 现在,我们以不同的方式做同样的事情。 不仅显示语言列表,还显示带有语言图标。

首先为每行创建一个布局,该布局具有图像视图和文本视图。 这是list_single.xml的代码

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <TableRow>
        <ImageView
            android:id="@+id/img"
            android:layout_width="100dp"
            android:layout_height="100dp"/>

        <TextView
            android:id="@+id/txt"
            android:layout_width="wrap_content"
            android:layout_height="100dp" />

    </TableRow>
</TableLayout>

创建一个 Java 类并将其命名为CustomList.java,这是它的代码

package com.example.admin.listadapterexample;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class CustomList extends ArrayAdapter<String>{

    private final Activity context;
    private final String[] web;
    private final Integer[] imageId;
    public CustomList(Activity context,
                      String[] web, Integer[] imageId) {
        super(context, R.layout.list_single, web);
        this.context = context;
        this.web = web;
        this.imageId = imageId;

    }
    @Override
    public View getView(int position, View view, ViewGroup parent) {
        LayoutInflater inflater = context.getLayoutInflater();
        View rowView= inflater.inflate(R.layout.list_single, null, true);
        TextView txtTitle = (TextView) rowView.findViewById(R.id.txt);

        ImageView imageView = (ImageView) rowView.findViewById(R.id.img);
        txtTitle.setText(web[position]);

        imageView.setImageResource(imageId[position]);
        return rowView;
    }
}

现在创建一个主要活动,mainActivty.java的代码是

package com.example.admin.listadapterexample;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import android.app.Activity;

public class MainActivity extends Activity {
    ListView list;
    String[] web = {
            "Java",
            "C++",
            "C#",
            "HTML",
            "CSS"

    } ;
    Integer[] imageId = {
            R.drawable.java,
            R.drawable.cplus,
            R.drawable.csharp,
            R.drawable.html,
            R.drawable.download

    };

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

        CustomList listAdapter = new
                CustomList(MainActivity.this, web, imageId);
        list=(ListView)findViewById(R.id.list);
        list.setAdapter(listAdapter);
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {
                Toast.makeText(MainActivity.this, "You Clicked at " +web[+ position], Toast.LENGTH_SHORT).show();

            }
        });

    }

}

这是activty_main.xml布局的样子

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <ListView
        android:id="@+id/list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

    </ListView>

</RelativeLayout>

运行您的应用程序,这里是输出

list adapter example

列表适配器示例

您可以通过单击链接下载此代码。

Android SQLite 数据库介绍

原文: https://javatutorial.net/android-sqlite-database-introduction

本文是 SQLite 数据库类和方法的简介。 它与完整的 Android SQLite 示例相等。

Android 中的 SQLite 数据库

您是否要在设备中存储和保存 Android 应用程序的数据? 该解决方案非常简单,因为 Android 内置了 SQLite 数据库引擎。 SQLite 是 SQL 数据库,它将您的应用程序数据存储在一个文本文件中。 它重量很轻,也是开源的。 SQLite 数据库支持关系数据库的标准功能。 它支持文本,整数和实数数据类型。android.database.sqlite软件包具有保存应用程序数据所需的全部。SqliteDatabase类具有许多不同的方法来创建数据库,执行 SQL 命令和删除数据库。

SQLiteDatabase类的方法

这是SQLiteDatabase类的一些公共方法。

  • createSQLIteDatabase(SQLiteDatabase.Cursorfactory factory):用于创建 SQLite 数据库。
  • complieStatement(String sql):编译 SQL 语句。
  • deleteDatabase(File file):删除整个数据库。
  • delete( String table, String wholeClass, String[] whereArgs):删除数据库中行的方法。
  • getPath():获取数据库路径的方法。
  • getVersion():获取数据库版本的方法。
  • isreadOnly():告知数据库是否为只读。
  • isOpen():告知数据库是否打开。
  • uupdate( String table, Content values, String whereClause, String[] whereArgs):用于更新数据库中的行。
  • releaseMemory():用于释放 SQL 所保存的内存。

光标

游标是提供随机读写访问的接口。 游标对象帮助我们从数据库中检索任何内容。 Cursor 类的许多功能可以帮助我们进行数据检索。

  • rawQuery():以指向表的光标对象的形式返回结果集。
  • moveToFirst():它将光标移动到第一行。
  • moveToLast():此方法将光标移动到最后一行。
  • moveToNext():此函数将光标移动到下一行。
  • move(int offset):该功能用于根据给定的偏移值向前或向后移动光标。
  • isFirst():检查光标是否在第一行。
  • isLast():检查光标是否在最后一行。
  • isNull():检查光标是否指向null
  • getPosition():该方法以行集的形式返回光标的当前位置。
  • getString(int column):此方法以字符串形式返回给定列的值。
  • getCount():此方法返回游标中的行数。

请遵循下一个教程,了解完整的 Android SQLite 数据库示例,演示创建,更新,检索和删除数据。

Android SQLite 数据库示例

原文: https://javatutorial.net/android-sqlite-database-example

[上一教程(https://javatutorial.net/android-sqlite-database-introduction)对 Android 中的 SQLite 数据库进行了简介。 本教程以示例说明了所有 CRUD(创建,检索,更新,删除)功能。

示例背景

让我们开始使用 SQLite 数据库。 本示例全部有关注册和登录过程以及将用户凭据存储到数据库中的逐步说明。 当用户单击“注册”按钮时,将出现一个新活动,并且用户填写该表单,该表单具有四个值,分别是名字,姓氏,电子邮件 ID 和密码。 当用户单击“确定”按钮时,这些值将保存到数据库中。 下图显示了数据库中的注册表的外观

login table

登录表

第 1 步:活动布局

让我们开始创建用于注册和登录的 xml 布局。如上所述,注册有四个字段和一个确定按钮。 用户单击“确定”按钮时,将显示一个对话框,因为已保存值,然后将开始登录活动。

这是activity_main.xml的代码

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout android:layout_width="368dp"
    android:layout_height="495dp"
    xmlns:tools="http://schemas.android.com/tools"
    tools:layout_editor_absoluteX="8dp"
    tools:layout_editor_absoluteY="8dp"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="104dp"
        android:text="Sign In"
        android:textColor="@android:color/holo_red_dark"
        android:textSize="25sp" />

    <EditText
        android:id="@+id/Email"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView2"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="26dp"
        android:ems="10"
        android:inputType="textPersonName"
        android:text="Email ID" />

    <EditText
        android:id="@+id/Password"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignEnd="@+id/Email"
        android:layout_alignRight="@+id/Email"
        android:layout_centerVertical="true"
        android:ems="10"
        android:inputType="textPassword"
        android:text="password" />

    <Button
        android:id="@+id/buttonSignIn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/Password"
        android:layout_alignStart="@+id/Password"
        android:layout_below="@+id/Password"
        android:layout_marginTop="52dp"
        android:backgroundTint="@color/colorAccent"
        android:onClick="SignIN"
        android:text="Sign In" />

    <Button
        android:id="@+id/buttonSignUp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignEnd="@+id/Password"
        android:layout_alignRight="@+id/Password"
        android:layout_alignTop="@+id/buttonSignIn"
        android:backgroundTint="@color/colorAccent"
        android:onClick="SignUP"
        android:text="Sign Up" />

</RelativeLayout>

现在为activity_sign_up.xml创建另一个布局。 登录有两个字段和两个按钮,分别是“登录”和“登录”。 如果您已经有一个帐户,请输入 ID 和密码并登录。如果没有,请单击“注册”按钮并为您创建帐户。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="368dp"
    android:layout_height="495dp"
    xmlns:tools="http://schemas.android.com/tools"
    tools:layout_editor_absoluteX="8dp"
    tools:layout_editor_absoluteY="8dp"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <TextView
        android:id="@+id/tSignUP"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Sign Up"
        android:textColor="@android:color/holo_red_dark"
        android:textSize="25sp"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="22dp" />

    <EditText
        android:id="@+id/tFirstName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tSignUP"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="26dp"
        android:ems="10"
        android:inputType="textPersonName"
        android:text="First Name" />

    <EditText
        android:id="@+id/tPassword"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPassword"
        android:text="password"
        android:layout_below="@+id/tEmail"
        android:layout_alignLeft="@+id/tEmail"
        android:layout_alignStart="@+id/tEmail"
        android:layout_marginTop="23dp"  />

    <EditText
        android:id="@+id/tLastName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/tFirstName"
        android:layout_alignStart="@+id/tFirstName"
        android:layout_below="@+id/tFirstName"
        android:layout_marginTop="14dp"
        android:ems="10"
        android:inputType="textPersonName"
        android:text="Last Name" />

    <EditText
        android:id="@+id/tEmail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignEnd="@+id/tLastName"
        android:layout_alignRight="@+id/tLastName"
        android:layout_below="@+id/tLastName"
        android:layout_marginTop="25dp"
        android:ems="10"
        android:inputType="textPersonName"
        android:text="Email ID" />

    <Button
        android:id="@+id/buttonOK"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignEnd="@+id/tPassword"
        android:layout_alignRight="@+id/tPassword"
        android:layout_below="@+id/tPassword"
        android:layout_marginTop="47dp"
        android:background="@color/colorAccent"
        android:onClick="OK"
        android:text="OK" />
</RelativeLayout>

步骤 2:创建数据库助手类

此类在磁盘上创建数据库。

package com.example.admin.androiddatabaseexample;

        import android.content.Context;
        import android.database.sqlite.SQLiteDatabase;
        import android.database.sqlite.SQLiteDatabase.CursorFactory;
        import android.database.sqlite.SQLiteOpenHelper;
        import android.util.Log;

public class DataBaseHelper extends SQLiteOpenHelper {
    public DataBaseHelper(Context context, String name, CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    // Called when no database exists in disk and the helper class needs
    // to create a new one.
    @Override
    public void onCreate(SQLiteDatabase _db) {
        try {
            _db.execSQL(LoginDatabaseAdapter.DATABASE_CREATE);

        }catch(Exception er){

            Log.e("Error","exceptioin");
        }

    }

    // Called when there is a database version mismatch meaning that the version
    // of the database on disk needs to be upgraded to the current version.
    @Override
    public void onUpgrade(SQLiteDatabase _db, int _oldVersion, int _newVersion)
    {
        // Log the version upgrade.
        Log.w("TaskDBAdapter", "Upgrading from version " +_oldVersion + " to " +_newVersion + ", which will destroy all old data");

        // Upgrade the existing database to conform to the new version. Multiple
        // previous versions can be handled by comparing _oldVersion and _newVersion
        // values.
        // The simplest case is to drop the old table and create a new one.
        _db.execSQL("DROP TABLE IF EXISTS " + "LOGIN");

        // Create a new one.
        onCreate(_db);
    }

}

步骤 3:创建登录数据库类

登录数据库是一类,您在其中实现所有数据库编码。 首先使用四个字段创建用于登录的表,然后实现所有其他方法。

package com.example.admin.androiddatabaseexample;

        import android.app.AlertDialog;
        import android.content.ContentValues;
        import android.content.Context;
        import android.content.DialogInterface;
        import android.database.Cursor;
        import android.database.SQLException;
        import android.database.sqlite.SQLiteDatabase;
        import android.util.Log;
        import android.widget.Toast;

        import java.util.ArrayList;
        import java.util.List;

public class LoginDatabaseAdapter {

    static final String DATABASE_NAME = "database.db";
    String ok="OK";
    static final int DATABASE_VERSION = 1;
    public  static String getPassword="";

    public static final int NAME_COLUMN = 1;
    // TODO: Create public field for each column in your table.
    // SQL Statement to create a new database.
    static final String DATABASE_CREATE = "create table LOGIN( ID integer primary key autoincrement,FIRSTNAME  text,LASTNAME  text,USERNAME text,PASSWORD text); ";

    // Variable to hold the database instance
    public static SQLiteDatabase db;
    // Context of the application using the database.
    private final Context context;
    // Database open/upgrade helper
    private static DataBaseHelper dbHelper;
    public  LoginDatabaseAdapter(Context _context)
    {
        context = _context;
        dbHelper = new DataBaseHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    // Method to openthe Database
    public  LoginDatabaseAdapter open() throws SQLException
    {
        db = dbHelper.getWritableDatabase();        return this;
    }

    // Method to close the Database
    public void close()
    {
        db.close();
    }

    // method returns an Instance of the Database
    public  SQLiteDatabase getDatabaseInstance()
    {
        return db;
    }

    // method to insert a record in Table
    public String insertEntry(String firstName,String lastName,String Id,String password)
    {

        try {

            ContentValues newValues = new ContentValues();
            // Assign values for each column.
            newValues.put("FIRSTNAME", firstName);
            newValues.put("LASTNAME", lastName);
            newValues.put("USERNAME", Id);
            newValues.put("PASSWORD", password);

            // Insert the row into your table
            db = dbHelper.getWritableDatabase();
            long result=db.insert("LOGIN", null, newValues);
            System.out.print(result);
            Toast.makeText(context, "User Info Saved", Toast.LENGTH_LONG).show();

        }catch(Exception ex) {
            System.out.println("Exceptions " +ex);
            Log.e("Note", "One row entered");
        }
        return ok;
    }
    // method to delete a Record of UserName
    public int deleteEntry(String UserName)
    {

        String where="USERNAME=?";
        int numberOFEntriesDeleted= db.delete("LOGIN", where, new String[]{UserName}) ;
        Toast.makeText(context, "Number fo Entry Deleted Successfully : "+numberOFEntriesDeleted, Toast.LENGTH_LONG).show();
        return numberOFEntriesDeleted;

    }

    // method to get the password  of userName
    public String getSinlgeEntry(String userName)
    {

        db=dbHelper.getReadableDatabase();
        Cursor cursor=db.query("LOGIN", null, "USERNAME=?", new String[]{userName}, null, null, null);
        if(cursor.getCount()<1) // UserName Not Exist
            return "NOT EXIST";
        cursor.moveToFirst();
        getPassword= cursor.getString(cursor.getColumnIndex("PASSWORD"));
        return getPassword;

    }
    // Method to Update an Existing
    public void  updateEntry(String userName,String password)
    {
        //  create object of ContentValues
        ContentValues updatedValues = new ContentValues();
        // Assign values for each Column.
        updatedValues.put("USERNAME", userName);
        updatedValues.put("PASSWORD", password);

        String where="USERNAME = ?";
        db.update("LOGIN",updatedValues, where, new String[]{userName});

    }

}

步骤 4:MainActivity.java

在该类中,您可以从登录活动中获取 ID 和密码,并在点击监听器上实现登录和注册按钮。

package com.example.admin.androiddatabaseexample;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {

 private EditText etUserEmail;
 private EditText etPassword;
 public String username;
 private String password;
 String storedPassword;
 Context context=this;

 LoginDatabaseAdapter loginDataBaseAdapter;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
     // create the instance of Databse
     loginDataBaseAdapter=new LoginDatabaseAdapter(getApplicationContext());

     etUserEmail = (EditText) findViewById(R.id.Email);
     etPassword = (EditText) findViewById(R.id.Password);

 }

 public void SignIN(View view) {

   try {

       loginDataBaseAdapter = loginDataBaseAdapter.open();
       username = etUserEmail.getText().toString();
       password = etPassword.getText().toString();

       if (username.equals("") || password.equals("")) {
          AlertDialog alertDialog = new AlertDialog.Builder(this).create();
          alertDialog.setTitle("ALERT!");
          alertDialog.setMessage("Fill All Fields");
          alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int which) {
          }
          });
          alertDialog.show();
       }

      // fetch the Password form database for respective user name
      if (!username.equals("")) {
          storedPassword = loginDataBaseAdapter.getSinlgeEntry(username);

         // check if the Stored password matches with Password entered by user
      if (password.equals(storedPassword)) {
         Intent intent1 = new Intent(MainActivity.this, DisplayInfoActivity.class);
         startActivity(intent1);
         // finish();
       } 
      else
       {
         AlertDialog alertDialog = new AlertDialog.Builder(this).create();
         alertDialog.setTitle("ALERT!");
         alertDialog.setMessage("Incorrect Username OR Password");
         alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
       public void onClick(DialogInterface dialog, int which) {
       }
       });
       alertDialog.show();
       }
       }
       }
    catch (Exception ex)
      {
      Log.e("Error", "error login");
      }

 }

 public void SignUP(View view)
{
      Intent intent = new Intent(MainActivity.this, SignUp.class);
      startActivity(intent);
 }

 @Override
 protected void onDestroy() 
{
     // TODO Auto-generated method stub
     super.onDestroy();

     // Close The Database
      loginDataBaseAdapter.close();
 }
}

步骤 5:SignUp.java

当用户在注册活动中单击“确定”按钮时,将出现一个对话框,指出值已添加到数据库的登录表中。

package com.example.admin.androiddatabaseexample;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.View;
import android.widget.EditText;

public class SignUp extends AppCompatActivity {

 Context context=this;
 private EditText et_first_name;
 private EditText et_last_name;
 private EditText et_ID;
 private EditText et_password;
 private String firstName;
 private String lastName;
 private String userName;
 private String password;
 String receieveOk;
 LoginDatabaseAdapter loginDataBaseAdapter;

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

     // get Instance of Database Adapter
     loginDataBaseAdapter=new LoginDatabaseAdapter(getApplicationContext());
     loginDataBaseAdapter=loginDataBaseAdapter.open();
     et_first_name = (EditText) findViewById(R.id.tFirstName);
     et_last_name = (EditText) findViewById(R.id.tLastName);
     et_ID = (EditText) findViewById(R.id.tEmail);
     et_password = (EditText) findViewById(R.id.tPassword);

 }

 public void OK(View view)
{

     firstName = et_first_name.getText().toString();
     lastName = et_last_name.getText().toString();
     userName = et_ID.getText().toString();
     password = et_ID.getText().toString();
     if((firstName.equals(""))||(lastName.equals(""))||(userName.equals(""))||(password.equals("")))
     {
         //Display Message
         AlertDialog alertDialog = new AlertDialog.Builder(this).create();
         alertDialog.setTitle("ALERT!");
         alertDialog.setMessage("All fields must be filled");
         alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
         public void onClick(DialogInterface dialog, int which) {

     }
     });
     alertDialog.show();
 }
else
{

       // Save the Data in Database
       receieveOk=loginDataBaseAdapter.insertEntry(firstName,lastName,userName, password);

       AlertDialog alertDialog = new AlertDialog.Builder(this).create();
       alertDialog.setTitle("SUCCESSFUL!");
       alertDialog.setMessage("SIGN IN NOW " + receieveOk);
       alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
       public void onClick(DialogInterface dialog, int which) {

       Intent intent = new Intent(SignUp.this, MainActivity.class);
       startActivity(intent);
       }
       });
       alertDialog.show();
       finish();
       }

 }

 @Override
 protected void onDestroy()
 {
      // TODO Auto-generated method stub
      super.onDestroy();

     loginDataBaseAdapter.close();
 }
}

现在运行您的应用程序并进行测试。 这是正在运行的应用程序的屏幕截图

sign in

登入

wrong id or password

错误的 ID 或密码

sign up

注册

您可以从链接下载此代码。

Android 动画教程

原文: https://javatutorial.net/animations-with-android-tutorial

本教程借助一个示例来说明什么是动画以及如何在 Android 应用程序中使用动画。

动画

你知道什么是动画吗? 动画实际上是对运动的幻想。 在这项技术中,相差很小的连续图像会产生运动效果。 动画在移动应用程序中非常有用。 教育中的动画用于解释理论和概念。 应用程序中的动画用来显示一些准则或过程。 向 Android 应用程序添加动画会增加用户的可加性。 它增加了乐趣,并平滑了用户体验。 在本教程中,您将学习如何通过在 Android 应用中添加动画来增加用户体验。

Android 中的动画

Android 提供了一个名为Animations的类。 此类提供了许多不同的方法。 以下是其中一些:

  • loadAnimation(Context, Layout):此方法用于加载动画。 它有两个参数。
  • start():用于启动动画。
  • setDuration(long duration):此方法设置 Android 中动画的持续时间。
  • getDuration():用于获取 Android 动画的持续时间。
  • end():用于结束动画。
  • cancel():用于取消动画。

Android 中的动画示例

让我们开始为 Android 中的动画创建示例。 我将讨论四种类型的动画:眨眼,淡入淡出,顺时针和滑动。 打开您的 Android Studio 并创建一个新活动。 在主要活动中,有一个图像视图和一个按钮。 我用足球的形象。 这是activity_main.xml的代码

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="368dp"
    android:layout_height="495dp"
    tools:layout_editor_absoluteX="8dp"
    tools:layout_editor_absoluteY="8dp"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="JavaTutorial"
            android:id="@+id/textView2"
            android:textColor="#ff3eff0f"
            android:textSize="35dp"
            android:layout_centerHorizontal="true" />

        <ImageView
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:id="@+id/imageView"
            android:src="@drawable/football"
            android:layout_below="@+id/textView2"
            android:layout_alignRight="@+id/textView2"
            android:layout_alignEnd="@+id/textView2"
            android:layout_marginTop="50dp" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/imageView"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="59dp"
        android:backgroundTint="@color/colorAccent"
        android:onClick="Animation"
        android:text="Animation" />

    </RelativeLayout>

现在为眨眼动画,淡入淡出动画,顺时针动画和幻灯片动画创建四个布局文件。 这是blink_animation.xml的代码

<?xml version="1.0" encoding="utf-8"?>

    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <alpha android:fromAlpha="0.0"
            android:toAlpha="1.0"
            android:interpolator="@android:anim/accelerate_interpolator"
            android:duration="600"
            android:repeatMode="reverse"
            android:repeatCount="infinite"/>
    </set>

这是fade_animation.xml的代码

<?xml version="1.0" encoding="utf-8"?>

    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@android:anim/accelerate_interpolator" >

        <alpha
            android:fromAlpha="0"
            android:toAlpha="1"
            android:duration="2000" >
        </alpha>

        <alpha
            android:startOffset="2000"
            android:fromAlpha="1"
            android:toAlpha="0"
            android:duration="2000" >
        </alpha>

    </set>

这是clockwise_animation.xml的代码

<?xml version="1.0" encoding="utf-8"?>

       <set xmlns:android="http://schemas.android.com/apk/res/android">

        <rotate xmlns:android="http://schemas.android.com/apk/res/android"
            android:fromDegrees="0"
            android:toDegrees="360"
            android:pivotX="50%"
            android:pivotY="50%"
            android:duration="5000" >
        </rotate>

        <rotate xmlns:android="http://schemas.android.com/apk/res/android"
            android:startOffset="5000"
            android:fromDegrees="360"
            android:toDegrees="0"
            android:pivotX="50%"
            android:pivotY="50%"
            android:duration="5000" >
        </rotate>

    </set>

这是slide_animation.xml的代码

<?xml version="1.0" encoding="utf-8"?>

    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:fillAfter="true" >

        <scale
            android:duration="500"
            android:fromXScale="1.0"
            android:fromYScale="1.0"
            android:interpolator="@android:anim/linear_interpolator"
            android:toXScale="1.0"
            android:toYScale="0.0" />
    </set>

现在创建一个 Java 类MainActivity.java并粘贴以下代码

package com.example.admin.androidanimations;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity {
    int count=0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void Animation(View view){
        if(count==0){
            ImageView image = (ImageView)findViewById(R.id.imageView);
            Animation animation = AnimationUtils.loadAnimation(getApplicationContext(),
            R.anim.clockwise_animation);
            image.startAnimation(animation);
        }
        if(count==1){
            ImageView image = (ImageView)findViewById(R.id.imageView);
            Animation animation1 = AnimationUtils.loadAnimation(getApplicationContext(),
            R.anim.fade_animation);
            image.startAnimation(animation1);
        }
        if(count==2){
            ImageView image = (ImageView)findViewById(R.id.imageView);
            Animation animation1 =
                    AnimationUtils.loadAnimation(getApplicationContext(),
                      R.anim.blink_animation);
            image.startAnimation(animation1);
        }
        if(count==3){
            ImageView image = (ImageView)findViewById(R.id.imageView);
            Animation animation1 =
                    AnimationUtils.loadAnimation(getApplicationContext(),
                            R.anim.slide_animation);
            image.startAnimation(animation1);
            count=0;
        }
        count++;

    }

}

当用户首次单击count = 0的动画按钮时,图像将顺时针旋转。 当用户第二次单击count = 1时,图像将消失。 当用户第三次单击count = 2时,图像将开始闪烁。 第四次count = 3,则图像将显示幻灯片动画。 现在运行它,这是输出

animation example

动画示例

这是它闪烁时的输出

blink animation

闪烁动画

您可以通过单击链接下载本教程。

资源

官方 Android 动画指南

Android 中的通知

原文: https://javatutorial.net/notifications-in-android

Android 应用程序中的通知非常有用。 本教程将通过示例说明如何在应用程序中设置通知。

通知

通知是通知或通知某事。 Android 应用程序中的通知非常有用。 它提供有关重要信息的信息。 现在,一天的用户希望易于使用,而又不想一次又一次地打开应用以获取新的更新。 取而代之的是,它们启用上推通知。 例如,没有人希望在一天内一次又一次地检查电子邮件,最好是在收到新邮件时调整通知。 为了满足这种通知需求,本教程提供了一个简单的示例来设置通知。

NotificationCompat.Builder

NotificationCompat构建器类可帮助我们开发通知布局。 它有许多用于在应用程序中进行通知的方法。 以下是其中一些:

  • addNotification(NotificationCompat.Action action):顾名思义,此方法用于向通知中添加操作。
  • addPerson(String uri):此方法用于将人添加到通知中。 例如,来自特定人的电子邮件。
  • getNotification():用于获取通知。
  • build():用于构建通知。
  • setCategory(String category):此方法用于设置通知类别。
  • setColor(int argb):此方法用于设置通知颜色。
  • setContentTitle(CharSequence title):此方法用于设置通知栏的标题。
  • setContentText(CharSequence text):此方法用于设置通知栏中显示的文本。

通知管理器

通知管理器是一个类,用于告知用户后台发生了某些事情。 它通知事件。

Android 中的通知示例

让我们开始创建一个简单的示例,该示例演示如何在 Android 应用中使用通知。 打开您的 Android Studio 并创建主要活动。 在主要活动中,只有文本视图,图像视图和按钮。 当用户单击按钮时,它将在状态栏中显示通知。 这是activity_main.xml的 XML 布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="MainActivity">

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="48dp"
        android:text="Java Tutorial "
        android:textColor="@android:color/holo_red_dark"
        android:textSize="30dp" />

    <ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imageButton"
        android:src="@drawable/message"
        android:layout_below="@+id/textView2"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="42dp" />

    <Button
        android:id="@+id/button"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/imageButton"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="62dp"
        android:background="@android:color/holo_red_dark"
        android:text="Notification"
        android:onClick="notification"
        android:textColor="@android:color/background_light" />

</RelativeLayout>

现在为通知创建另一个布局,这是activity_notification_bar.xml的代码

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

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="400dp"
        android:text="You have a new unread message...." />
</LinearLayout>

这是NotificationBar.java

package com.example.admin.androidnotifications;

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

public class NotificationBar extends Activity{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notification_bar);

    }
}

现在打开您的MainActivity.java并粘贴以下代码

package com.example.admin.androidnotifications;

import android.os.Bundle;
import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {

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

    }

    public void notification(View view)
    {
        addNotification();
    }

    private void addNotification()
    {
        NotificationCompat.Builder builder =
        new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.message)
                .setContentTitle("Unread Message")   //this is the title of notification
                .setColor(101)
                .setContentText("You have an unread message.");   //this is the message showed in notification

        Intent intent = new Intent(this, MainActivity.class);
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        builder.setContentIntent(contentIntent);

        // Add as notification
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        manager.notify(0, builder.build());
    }
}

现在运行您的应用,这是输出

notification example

通知示例

单击“通知”按钮后,新的通知将出现在状态栏中。 这是它的样子

new notification

新通知

您可以通过单击链接下载此项目。

Android 中的事件处理

原文: https://javatutorial.net/event-handing-android

在先前的教程中,您了解了活动意向和其他内容。 本教程借助示例介绍了 Android 中的事件处理。

事件处理

事件是一个动作。 当用户与移动应用程序交互时,会发生这种情况。 Android 中的事件采用多种不同形式,例如按键,触摸输入和许多其他形式。 触摸屏交互属于触摸事件的类别。 Android 框架将所有事件维护在先进先出(FIFO)队列中。 顾名思义,事件处理程序用于处理 Android 中的事件。 事件处理程序和事件监听器是相关概念。

事件监听器

它是一个包含回调方法的接口。 当用户触发视图元素时,它将调用这些方法。 以下是一些重要的回调方法:

  • OnClickListener():当用户单击任何 UI 元素(如按钮,文本或图像)时,将调用此事件监听器。OnClick()事件处理程序用于处理此监听器。
  • OnLongClickListener():当用户长时间单击任何 UI 元素或按住 UI 元素几秒钟时,将调用此方法。OnLongClick()事件处理程序用于处理此监听器。
  • OnFocusChangeListener():当 UI 元素或小部件失去焦点时,将调用此方法。 只需用户向前导航。OnFocusChange()事件处理程序用于处理此监听器。
  • OnKeyListener():当用户按下键盘上的键时,将调用此方法。OnKey()事件处理程序用于处理此事件。
  • OnTouchListener():当用户触摸屏幕上的任何 UI 元素(例如按下或释放按钮)时,将调用此方法。OnTouch()事件处理程序用于处理此监听器。
  • OnMenuItemClickListener():当用户单击或选择菜单项时使用此方法。OnMenuItemClick()事件处理程序用于处理此监听器。
  • OnCreateContextMenuListener()OnCreateContextMenu()事件处理程序用于处理此监听器。

事件处理示例

让我们开始创建一个示例,说明如何在 Android 应用中使用事件处理程序和事件监听器。 打开 Android Studio 并创建一个新项目。 打开您的activtity_main.xml并添加测试视图,图像视图和按钮。 这是代码

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="MainActivity">

    <TextView
        android:id="@+id/tv_welcome"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Welcome to "
        android:textColor="@android:color/holo_red_dark"
        android:textSize="40dp"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />

    <ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imageButton"
        android:src="@drawable/message"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp" />

    <Button
        android:id="@+id/button"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:background="@android:color/holo_red_dark"
        android:text="Change Color"
        android:textColor="@android:color/background_light"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="70dp" />

    <TextView
        android:id="@+id/tv_java"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/holo_red_dark"
        android:textSize="40dp"
        android:layout_marginTop="21dp"
        android:text="Java Tutorial.net"
        android:layout_below="@+id/tv_welcome"
        android:layout_centerHorizontal="true" />

</RelativeLayout>

现在在mainActivity.java中编写代码,当用户单击按钮时,文本的颜色将改变,在此实现onClickListener()。 最初,文本颜色为红色,第一次单击时颜色将变为黑色,第二次单击时颜色将变为绿色,依此类推。 这是代码

package com.example.admin.androideventhandling;

import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    TextView welcome;
    TextView java;
    Button button;
    int i=0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        welcome = (TextView)findViewById(R.id.tv_welcome);
        java = (TextView)findViewById(R.id.tv_java);
        button = (Button) findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(i==0) {
                    welcome.setTextColor(Color.BLACK);
                    java.setTextColor(Color.BLACK);
                    button.setBackgroundColor(Color.BLACK);
                }
                if(i==1) {
                    welcome.setTextColor(Color.GREEN);
                    java.setTextColor(Color.GREEN);
                    button.setBackgroundColor(Color.GREEN);
                }
                if(i==2) {
                    welcome.setTextColor(Color.BLUE);
                    java.setTextColor(Color.BLUE);
                    button.setBackgroundColor(Color.BLUE);
                }
                if(i==3) {
                    welcome.setTextColor(Color.MAGENTA);
                    java.setTextColor(Color.MAGENTA);
                    button.setBackgroundColor(Color.MAGENTA);
                    i=0;
                }
                i++;
            }
        });
    }

}

在这里运行您的应用程序,输出结果看起来像

event handling

事件处理

单击按钮后,文本颜色将更改

event handling color change

事件处理颜色变化

event handling example

事件处理示例

event handling magenta color

事件处理:洋红色

event handling blue color

事件处理:蓝色

您可以通过单击链接下载此代码。

如何在 Android 中发送带有附件的电子邮件

原文: https://javatutorial.net/send-email-with-attachments-android

在本教程中,您将学习如何在 Android 中以编程方式发送电子邮件以及如何附加文件,图像或视频。

电子邮件通常用于专业和个人对话。 许多应用程序需要电子邮件选项才能将数据发送给其他人。 您可以使用 Android 应用程序轻松发送电子邮件。 附件呢? 不幸的是,Android 不允许我们附加许多不同的文件格式,但是您可以添加其中的一些格式,例如照片,音频,视频,pdf 和 Word 文档。

电子邮件附件的示例

首先创建一个允许用户通过电子邮件发送数据的应用程序。Intent.ACTION_SEND用于通过手机中的现有客户端发送电子邮件。 类似地,Intent.ACTION_GET_CONTENT用于附件。

Intent.ACTION_SEND

ACTION_SEND用于将数据发送到您应用中的其他活动或其他应用。 两者都很容易理解和使用。 如果要将数据发送到应用程序中的其他活动,则只需指定数据及其类型。 Android 操作系统将完成剩下的工作……它将找到兼容的活动并显示数据。 同样,您可以将数据发送到其他应用程序。 将内容类型设置为简单的纯文本。 这是应该如何编码的

final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("plain/text");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,new String[] { email });
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,subject);

Intent.ACTION_GET_CONTENT

ACTION_GET_CONTENT用于选择多种类型的数据并返回。 您可以通过将 MIME 类型设置为此类数据来直接选择所需的内容类型。 或者,您可以选择所需的任何类型的数据。 为此,请使用选择器包装您的意图,该选择器将启动一个新活动,并让用户选择所需的内容。 这是怎么做的

Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.putExtra("return-data", true);
startActivityForResult(Intent.createChooser(intent, "Complete action using"), PICK_FROM_GALLERY);

向清单文件添加权限

向清单文件添加以下权限。

<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

打开 Android Studio 并创建一个新项目。 创建主要活动并将以下代码粘贴到activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="5dp"
    tools:context=".MainActivity" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="5dp"
        android:padding="5dp" >

        <EditText
            android:id="@+id/et_to"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:layout_margin="5dp"
            android:hint="Receiver's Email Address!"
            android:inputType="textEmailAddress"
            android:singleLine="true" />

        <EditText
            android:id="@+id/et_subject"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/et_to"
            android:layout_margin="5dp"
            android:hint="Enter Subject"
            android:singleLine="true" />

        <EditText
            android:id="@+id/et_message"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:layout_below="@id/et_subject"
            android:layout_margin="5dp"
            android:gravity="top|left"
            android:hint="Compose Email"
            android:inputType="textMultiLine" />

        <Button
            android:id="@+id/bt_send"
            android:layout_width="80dp"
            android:layout_height="50dp"
            android:layout_below="@id/et_message"
            android:layout_margin="5dp"
            android:text="Send" />

        <Button
            android:id="@+id/bt_attachment"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="attachment"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true" />

    </RelativeLayout>

</ScrollView>

现在这里是MainActivity.java

package com.example.admin.emailattachmentexample;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

    EditText et_email;
    EditText et_subject;
    EditText et_message;
    Button Send;
    Button Attachment;
    String email;
    String subject;
    String message;
    String attachmentFile;
    Uri URI = null;
    private static final int PICK_FROM_GALLERY = 101;
    int columnIndex;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et_email = (EditText) findViewById(R.id.et_to);
        et_subject = (EditText) findViewById(R.id.et_subject);
        et_message = (EditText) findViewById(R.id.et_message);
        Attachment = (Button) findViewById(R.id.bt_attachment);
        Send = (Button) findViewById(R.id.bt_send);

        //send button listener
        Send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendEmail();
            }
        });

        //attachment button listener
        Attachment.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                openFolder();
            }
        });
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        if (requestCode == PICK_FROM_GALLERY && resultCode == RESULT_OK) {
            Uri selectedImage = data.getData();
            String[] filePathColumn = { MediaStore.Images.Media.DATA };
            Cursor cursor = getContentResolver().query(selectedImage,filePathColumn, null, null, null);
            cursor.moveToFirst();
            columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            attachmentFile = cursor.getString(columnIndex);
            Log.e("Attachment Path:", attachmentFile);
            URI = Uri.parse("file://" + attachmentFile);
            cursor.close();
        }

    }

    public void sendEmail()
    {
        try
        {
            email = et_email.getText().toString();
            subject = et_subject.getText().toString();
            message = et_message.getText().toString();
            final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
            emailIntent.setType("plain/text");
            emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,new String[] { email });
            emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,subject);
            if (URI != null) {
                emailIntent.putExtra(Intent.EXTRA_STREAM, URI);
            }
            emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, message);
            this.startActivity(Intent.createChooser(emailIntent,"Sending email..."));

        }
        catch (Throwable t)
        {
            Toast.makeText(this, "Request failed try again: " + t.toString(),Toast.LENGTH_LONG).show();
        }
    }

    public void openFolder()
    {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        intent.putExtra("return-data", true);
        startActivityForResult(Intent.createChooser(intent, "Complete action using"), PICK_FROM_GALLERY);

    }
}

运行您的应用,这是输出

Email with attachment example

带附件的电子邮件示例

点击“添加附件”

add attachment

添加附件

现在点击“发送”按钮

send email

发电子邮件

您可以通过单击链接下载此项目。

参考文献

Android ACTION_SEND javadoc

Android ACTION_GET_CONTENT javadoc

杂项

选择您的 JAVA IDE:Eclipse,NetBeans 和 IntelliJ IDEA

原文: https://javatutorial.net/choose-your-java-ide-eclipse-netbeans-and-intellij-idea

在 Java 世界中,有许多集成开发环境或 IDE,它们被视为开发成功的移动应用程序的关键方面。 对于开发人员来说,IDE 是否适合他们的兴趣也很重要。

需要 IDE 或编程编辑器才能使用 Java 类库和框架。 决定哪种 IDE 适合您取决于几件事情,包括正在开发的项目的需求以及团队开发过程。 Eclipse,NetBeans 和 IntelliJ IDEA 是三种最常选择的服务器端 Java 开发。

在这里,我们对所有这些内容进行简短回顾,以帮助简化选择合适的对象的任务。

您对 JAVA IDE 有什么期望?

马上,您希望您的 IDE 支持最新的 JAVA 版本以及经常使用的 JVM 语言,例如 Scala,Groovy 等。此外,您希望它支持主要的应用程序服务器和最受欢迎的服务器 Web 框架,例如 Spring MVC,JSF,Struts,GWT,Play,Wicket,Grails 和 Vaadin。 与团队开发版本控制系统兼容的 IDE,例如 Ant, Maven ,SVN,Mercurial 等。作为一项附加功能,它还应处理客户端和数据库层,嵌入式 JavaScript,HTML, SQL, JSP ,Hibernate 和 JAVA API。

Eclipse

从 2001 年开始,IBM 就发布了 Eclipse 作为开放源代码平台。 它还在开源项目和商业项目中运行。 尽管它以适度的方式启动,但作为主要平台之一,它也已经广泛流行,该平台也以多种不同的语言使用。

使用 Eclipse 的优点是它具有大量可自定义且用途广泛的插件。 它在后台编译代码中工作,并在出现错误时报告错误。 Eclipse 具有 Java 服务器开发的许多编辑,浏览,重构和调试功能。

Eclipse IDE

Eclipse IDE

礼貌– 图片

Eclipse 是整个视觉容器,它们提供一组编辑器视图。 基本上,它可以完成您希望 IDE 成为的所有工作,并且可以与大多数工具集成。 开发人员选择 Eclipse 是因为它易于使用和开放源代码平台。 与新手一起工作可能会有点麻烦,但是稳定地使用它会成为一种很棒的经验。

NetBeans

NetBeans 最初是 Sun 系统的一部分,现在已经落入 Oracle 的掌控之中。 它是一个免费的开源 IDE 平台。 该 IDE 用于为所有版本的 JAVA 开发软件。 它还支持您可以使用的各种插件。

该平台可作为开发 JAVA swing 桌面应用程序的框架。 使用插件和基于平台的应用程序进行开发的 JAVA SE 中的 NetBeans IDE 不需要其他 SDK。

NetBeans IDE

NetBeans IDE

礼貌–图片

NetBeans 提供了多个版本,例如 PHP,JAVA SE,JAVA EE,以及您的项目开发所需的更多版本。 您还可以找到用于许多 Web 技术的工具和编辑器。 NetBeans 支持 JAVA DB,PostgreSQL,MySQL 和 Oracle 的驱动程序,这些驱动程序的排名高于 Eclipse。 数据库资源管理器使您可以在 IDE 中轻松创建,修改和删除记录和表。

IntelliJ IDEA

作为 JetBrains 一部分的 IntelliJ IDEA 既有免费版本,也有商业版本。 我们已经知道 JetBrains 在 C#开发中为 Visual Studio 提供了 Resharper 插件。 IntelliJ 支持多种语言,例如 Clojure,Groovy,Scala,Java 等。 它还具有高级预测,代码分析和智能代码完成等功能。 主要针对企业领域的最终商业版本支持 PHP,Ruby,Python,SQL 和 ActionScript。

IntelliJ IDEA IDE

IntelliJ IDEA IDE

最近,它发布了版本 12,该版本带有用于 Android 应用开发的新 Android UI。 它允许用户使用其内置的 Swing 组件提交更多插件,并具有多个用户编写的企业版插件。

Eclipse,Netbeans 和 IntelliJ IDEA 甚至还有许多其他选择。 例如,Visual Studio 也可以利用最新的工具和服务为使用云的设备创建出色的应用程序。 其他选项基于基于 IntelliJ IDEA android 开发环境的 Android Studio,为构建出色应用程序提供完整工具集的 Xcode 和为专业 PHP 和 Web 开发人员提供的 PhpStorm IDE。

结论

我们看到了上面的 Eclipse,NetBeans 和 IntelliJ IDEA 之间的比较,并且还发现了一些其他适合不同目的的替代方案。 这完全取决于开发人员和项目要求,这是最适合他们的 IDE。

其中,Eclipse 被认为是广泛使用的 IDE,因为它是一个开放源代码,也允许它用于个人和企业目的。 所有不同的 IDE 都有不同的用途,因此使用适当的平台构建用户友好的应用程序是开发人员的最终选择或优先考虑。 因此,始终建议您基本安装所有 IDE 平台,对其进行操作,然后根据您的项目要求和开发人员友好程度明智地选择最方便的平台。

作者简介

Kibo Hutchinson 是 TatvaSoft UK 的技术分析师,该公司是位于伦敦的基于 Java 和大数据开发公司。 她坚信应该共享知识,在这篇文章中,她正在分享对 Java 的见解。

Java S3 示例

原文: https://javatutorial.net/java-s3-example

在本教程中,我将解释如何通过 Amazon 提供的 Java API 使用 Amazon 的 S3 存储。 该示例说明了如何创建存储分区,列出存储分区的内容,在存储分区中创建文件夹,上传文件,为文件提供公共访问权限以及如何删除所有这些项目。

amazon s3 java example

设置项目

  1. 您将需要适用于 Java 的 AWS 开发工具包,此示例才能正常工作。 如果您现在尚未下载 SDK,请在此处下载。 您还需要将存档中的.JAR文件集成到您的项目中。 或者,您可以使用具有以下依赖项的 Maven

    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk</artifactId>
        <version>1.9.2</version>
    </dependency>
    
  2. 如果您没有,请在 Amazon IAM(https://console.aws.amazon.com/iam)中创建一个用户。 在这里您将获得一个“访问密钥”和“秘密访问密钥”。 您将需要此凭据才能连接到 S3。

  3. 将 IAM 中的“AWSConnector”和“ AmazonS3FullAccess”权限添加到新用户。 没有这个,您希望能够通过服务器进行身份验证。

使用 Amazon S3 进行身份验证

有 4 种不同的方法可针对 Amazon S3 验证您的请求

1. 使用默认的凭证配置文件 – 这是 Amazon 推荐的方法。 创建具有以下结构的文件并填写访问密钥:

# Move this credentials file to (~/.aws/credentials)
# after you fill in your access and secret keys in the default profile

# WARNING: To avoid accidental leakage of your credentials,
#          DO NOT keep this file in your source directory.
[default]
aws_access_key_id=
aws_secret_access_key=

默认情况下,将此文件保存为.aws文件夹中文件名credentials下的 Windows 用户或 Linux 中主目录的 C:\Users\user\.aws\credentials

如果使用此方法,则可以在代码中创建一个Credentials对象,如下所示:

AWSCredentials credentials = new ProfileCredentialsProvider().getCredentials();

2. 使用环境变量 – 设置系统中以下环境变量的值。AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY

3. Java 系统属性aws.accessKeyIdaws.secretKey。 使用SystemPropertiesCredentialsProvider在程序中加载变量

4. 以编程方式设置凭据 – 在此示例中,我将使用此方法,因为它更易于遵循

在代码中使用以下代码:

AWSCredentials credentials = new BasicAWSCredentials("YourAccessKeyID", "YourSecretAccessKey");

创建 S3 客户端

为了能够与 S3 通信,您必须使用AmazonS3的实现。 您将使用实例来解决对服务器的请求

AmazonS3 s3client = new AmazonS3Client(credentials);

创建桶

存储桶在整个 S3 领域中必须具有唯一的名称

String bucketName = "javatutorial-net-example-bucket";
s3client.createBucket(bucketName);

列出桶

您可以像这样从所有桶中获得列出

for (Bucket bucket : s3client.listBuckets()) {
	System.out.println(" - " + bucket.getName());
}

在 S3 存储桶中创建文件夹

使用此代码在存储桶中创建一个空文件夹

public static void createFolder(String bucketName, String folderName, AmazonS3 client) {
	// create meta-data for your folder and set content-length to 0
	ObjectMetadata metadata = new ObjectMetadata();
	metadata.setContentLength(0);

	// create empty content
	InputStream emptyContent = new ByteArrayInputStream(new byte[0]);

	// create a PutObjectRequest passing the folder name suffixed by /
	PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName,
				folderName + SUFFIX, emptyContent, metadata);

	// send request to S3 to create folder
	client.putObject(putObjectRequest);
}

在 S3 中上传文件

如果要将文件上传到文件夹,请使用此

String fileName = folderName + SUFFIX + "testvideo.mp4";
s3client.putObject(new PutObjectRequest(bucketName, fileName, 
		new File("C:\\Users\\user\\Desktop\\testvideo.mp4")));

只需删除文件名中的文件夹和后缀即可直接上传到存储桶。 如果要公开文件(Amazon S3 默认情况下文件为私有文件),请将其设置为PutObjectRequest(更多信息请参见下面的完整示例)

.withCannedAcl(CannedAccessControlList.PublicRead)

删除文件,文件夹和存储桶

要删除存储桶,请使用此功能。 储存桶必须为空,否则您无法将其删除

s3client.deleteBucket(bucketName);

要删除文件,请使用:

s3client.deleteObject(bucketName, fileName);

要删除文件夹,您必须先删除其中的所有文件。 请查看下面的完整示例以获取更多信息。

完整的例子

在这里,您可以在一个工作程序中找到以上所有片段。 出于可读性的考虑,排除了异常处理,请不要忘记在代码中添加异常处理

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.List;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3ObjectSummary;

public class AmazonS3Example {

	private static final String SUFFIX = "/";

	public static void main(String[] args) {
		// credentials object identifying user for authentication
		// user must have AWSConnector and AmazonS3FullAccess for 
		// this example to work
		AWSCredentials credentials = new BasicAWSCredentials(
				"YourAccessKeyID", 
				"YourSecretAccessKey");

		// create a client connection based on credentials
		AmazonS3 s3client = new AmazonS3Client(credentials);

		// create bucket - name must be unique for all S3 users
		String bucketName = "javatutorial-net-example-bucket";
		s3client.createBucket(bucketName);

		// list buckets
		for (Bucket bucket : s3client.listBuckets()) {
			System.out.println(" - " + bucket.getName());
		}

		// create folder into bucket
		String folderName = "testfolder";
		createFolder(bucketName, folderName, s3client);

		// upload file to folder and set it to public
		String fileName = folderName + SUFFIX + "testvideo.mp4";
		s3client.putObject(new PutObjectRequest(bucketName, fileName, 
				new File("C:\\Users\\user\\Desktop\\testvideo.mp4"))
				.withCannedAcl(CannedAccessControlList.PublicRead));

		deleteFolder(bucketName, folderName, s3client);

		// deletes bucket
		s3client.deleteBucket(bucketName);
	}

	public static void createFolder(String bucketName, String folderName, AmazonS3 client) {
		// create meta-data for your folder and set content-length to 0
		ObjectMetadata metadata = new ObjectMetadata();
		metadata.setContentLength(0);

		// create empty content
		InputStream emptyContent = new ByteArrayInputStream(new byte[0]);

		// create a PutObjectRequest passing the folder name suffixed by /
		PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName,
				folderName + SUFFIX, emptyContent, metadata);

		// send request to S3 to create folder
		client.putObject(putObjectRequest);
	}

	/**
	 * This method first deletes all the files in given folder and than the
	 * folder itself
	 */
	public static void deleteFolder(String bucketName, String folderName, AmazonS3 client) {
		List fileList = 
				client.listObjects(bucketName, folderName).getObjectSummaries();
		for (S3ObjectSummary file : fileList) {
			client.deleteObject(bucketName, file.getKey());
		}
		client.deleteObject(bucketName, folderName);
	}
}

如果您认为本教程有帮助,请查看我们的其他教程 - 我们确定您会在此页面上找到其他有趣的内容。 随时在“评论”部分中提问,或者通过共享本教程向我们展示一些爱意🙂

如何在 Ubuntu 上为多个站点配置 Apache

原文: https://javatutorial.net/configure-apache-multiple-sites-ubuntu

在本教程中,我将向您展示如何配置单个 Apache 2 Web 服务器以在 Ubuntu 16.04 LTS 上运行多个网站(虚拟主机)。

有时您可能想将不同的域指向单个虚拟主机。 这是价格有效的,并且可以通过简单的配置来完成。 您需要的是对 Ubuntu 服务器的 root 访问权限。

前提条件

本教程假定您已经在 Linux 主机上启动并运行了 Apache 2。 本教程还显示了如何为您的站点设置不同的 MySQL 用户,因此,如果要执行此步骤,则还应在服务器上安装 MySQL。

域名

首先,需要将您的域指向例如 https://javatutorial.net 的 Web 服务器 IP 地址。

  • 使用以下命令curl ipinfo.io/ip查找服务器的公共 IP 地址
  • 登录到您的域提供商(例如 GoDaddy 或您用来注册域的任何服务)
  • 转到 DNS 并更改 A 记录以指向您的服务器 IP

Change DNS A record

更改 DNS A 记录

我将此步骤列为 #1,因为 DNS 刷新可能需要数小时或数天。 请耐心等待,不要期望您的域会立即被重定向。

创建目录结构和用户权限

默认情况下,您的 Web 服务器为您的网站提供一个根目录,即/var/www/html/。 我们将对此进行更改,并为每个要添加的网站创建单独的文件夹。 例如/var/www/javatutorial

制作单独的文件夹

sudo mkdir /var/www/javatutorial

将目录的所有权授予 Apache Web 用户(即www-data

sudo chown YOUR_USER_NAME_HERE:www-data -R /var/www/javatutorial

将您的用户名添加到网络组

sudo usermod -aG www-data YOUR_USER_NAME_HERE

将虚拟主机添加到 Apache

转到 Apache 的配置文件夹/etc/apache2/sites-available 并创建一个名为 javatutorial.conf的新文件。

编辑javatutorial.conf的内容

<VirtualHost *:80>
    ServerAdmin admin@javatutorial.net
    ServerName javatutorial.net
    ServerAlias www.javatutorial.net
    DocumentRoot /var/www/javatutorial
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

启用新配置

sudo a2ensite javatutorial.conf

重新加载 Apache 以激活新配置

service apache2 reload

为新站点创建 MySQL 数据库和用户

我们将创建一个新的 MySQL 数据库和用户,并遵循以下凭据:

  • 数据库名称:javatut
  • 数据库用户:tutuser
  • 用户密码:tutpass123

以 root 身份登录到 MySQL

mysql -u root -p

现在,我们创建新的数据库和用户。 为用户设置密码,并授予该新用户使用数据库的权限

mysql> CREATE DATABASE javatut;
mysql> CREATE USER tutuser@localhost;
mysql> SET PASSWORD FOR dbuser@localhost= PASSWORD("tutpass123");
mysql> GRANT ALL PRIVILEGES ON javatut.* TO tutuser@localhost IDENTIFIED BY 'tutpass123';
mysql> FLUSH PRIVILEGES;

如何在 Liferay DXP 中替代现成的(OOTB)模块

https://javatutorial.net/override-out-of-the-box-ootb-modules-in-liferay-dxp

该博客涵盖有关在 Liferay DXP 中创建片段以及如何执行所需的覆盖的详细信息。

Liferay DXP 是最受欢迎的开放源代码之一,具有许多现成的(OOTB)模块,有时根据我们的特定要求,我们需要覆盖它们。 通常,使用 OSGi 片段是执行此类覆盖的方法。

该博客包括

什么是片段?

如何在 Liferay 7 中创建片段

片段在 Liferay 7 DXP 中的用途是:

  • 覆盖 Liferay OOTB 模块的 JSP
  • 覆盖语言属性
  • 用 Servlet 过滤器覆盖 HTTP 请求
  • 覆盖 Liferay Struts 动作
  • 替代 Liferay 模态监听器

什么是片段?

片段是 OSGi 模块的一种,类似于 mvcportlet,服务,激活器,面板应用程序等。可以说片段是主机模块的扩展。

对于 Liferay 7 之前的所有版本,都使用 Hook 覆盖 Liferay Portlet。 但是对于 Liferay 7,我们必须使用片段作为 Hook。 请注意,片段是扩展的主机模块,并且在部署时,片段模块定义将合并在主机模块中(仅当片段模块不与主机模块产生任何冲突时)。 如果发生任何类型的冲突,则直到其解决之前,片段都不会包含在主机模块中。 片段没有加载自己的类或捆绑程序激活器。

片段 jar 有自己的 OSGi 清单文件,该文件包含有关 OSGi 的信息。 请在下面找到MANIFEST.MF的重要信息:

Manifest-Version: 1.0

Bundle-ManifestVersion: 2

Bundle-Name: Liferay Fragment

Bundle-SymbolicName: azilen.login.fragment.module

Bundle-Version: 1.0.0

Bundle-RequiredExecutionEnvironment: JavaSE-1.6

Fragment-Host: com.liferay.login.web;bundle-version=1.0.5

Import-Package: org.apache.commons.logging;version=”1.0.4″

Export-Package: com.azilen.training;version=”1.0.0″

请在下面找到其关键属性的详细信息。

Fragment-Host:主机模块的捆绑符号名称

Bundle-Version:捆绑软件的初始版本

Bundle-Version:人类可读的片段模块名称

Bundle-SymbolicName:唯一标识 OSGi 容器中的片段。

Import-Package:片段中使用的外部软件包

Export-Package:对其他模块可见的片段包

Liferay 7 使用片段来执行诸如以下操作

  1. 覆盖 Liferay OOTB 模块的 JSP
  2. 覆盖语言属性
  3. 用 Servlet 过滤器覆盖 HTTP 请求
  4. 覆盖 Liferay Struts 动作
  5. 替代 Liferay 模态监听器
  6. 覆盖 Liferay 动作命令

如何在 Liferay 7 中创建片段

要将 Liferay 片段创建为模块,请使用以下命令

blade create -t fragment [-h hostBundleName] [-H hostBundleVersion] projectName

请注意,我们必须使用-t参数将刀片模块的类型指定为片段。 而-h参数将需要主机捆绑包符号名称和-H参数将需要将被覆盖的主机模块版本。 最后一个projectName是人类友好的片段模块名称。

如何覆盖 Liferay OOTB 模块的 JSP

让我们来看一个用例:我想覆盖 Liferay 登录模块,并且要根据自己的需求自定义外观。 因此,要创建的blade命令如下:

blade create -t fragment -h com.liferay.login.web -H 1.0.5 login-fragment-module

现在它将创建一个片段的骨架结构,您可以在bnd.bnd文件中看到主机模块(登录模块)的符号名称和版本。 可能会有一个查询,说明如何查找主机模块的符号名称和版本。 为了获得这些详细信息,我们必须使用编写的命令连接 gogo shell

telnet localhost 11311

然后运行lb命令,它将列出服务器中部署的所有模块。 您可以找到带有其状态和版本的主机模块。

219|Active | 10 | Liferay Login Web (1.0.5)

现在我们的片段结构已经准备就绪,我们都可以重写主机模块 jsp。 由于我们需要覆盖login.jsp,因此请从

Liferay-src/modules/apps/foundation/login/loginweb/src/main/resources/METAINF/resources/login.jsp

并将其粘贴到login-fragmentmodule/src/main/resources/META-INF/resources/中。

现在根据需要修改login.jsp并部署login-fragment-module,成功部署后,您应该在 OOTB 登录模块中进行更改

如何覆盖 Liferay DXP 的语言属性

Liferay 支持多种语言。 因此,我们具有 OOTB 模块的语言属性。 假设我们要更改某些标签,错误消息,成功消息等的属性值。我们可以灵活地覆盖这些属性值,并且可以根据我们的要求进行更改。

让我们来看一个用例:我们要更改登录 Portlet 身份验证失败消息。 该消息的属性是:authentication-failed。 我们想用我们的自定义消息覆盖这些属性。

blade create -t mvcportlet -p com.azilen.fragment.language -c CustomLanguageComponent languagefragment-module

请注意,此处创建的是-t mvcportlet而不是-t fragment,因为此处将使用 Resource bundle 类覆盖语言属性。

CustomLanguageComponent.Java
@Component(
    property = { "language.id=en_US" },
    service = ResourceBundle.class
)
public class CustomLanguageComponent extends ResourceBundle {
    ResourceBundle bundle = ResourceBundle.getBundle("content.Language",UTF8Control.INSTANCE);

    @Override
    protected Object handleGetObject(String key) {
        System.out.println("getting key"+key);
        return bundle.getObject(key);
    }
    @Override
    public Enumeration<String> getKeys() {
        return bundle.getKeys();
    }
}

可以看出,我们正在创建扩展了ResourceBundle的自定义类CustomLanguageComponent,并在@Component注解中指定了属性{"language.id=en_US"}。 我们指出要覆盖Language_en.properties文件。

现在,在/language-fragmentmodule/src/main/resources/content下创建Language_en.properties,并使用我们的自定义消息添加身份验证失败的属性。

authentication-failed=Authentication failed. Please try again (customized).

现在部署language-fragment-module,并且在登录模块中登录过程失败时,您将获得自定义消息。

如何使用 Servlet 过滤器覆盖

有时,我们需要拦截 http 请求,并需要在该请求上编写逻辑。 因此,我们可以使用BaseFilter实现它。

在这里,我们将拦截每个请求,仅在processFilter方法中打印日志。

blade create -t mvcportlet -p com.azilen.custom.filter -c CustomFilterPortlet custom filterfragment-module
CustomFilterPortlet.java

@Component(
    immediate = true,
    property = {
        "dispatcher=REQUEST", "dispatcher=FORWARD",
        "servlet-context-name=",
        "servlet-filter-name=Custom Filter",
        "url-pattern=/*"
    },
    service = Filter.class
)
public class CustomFilterPortlet extends BaseFilter {
    private static final Log _log = LogFactoryUtil.getLog(CustomFilterPortlet.class);

    @Override
    protected void processFilter(HttpServletRequest request, HttpServletResponse response,
        FilterChain filterChain)throws Exception {
        log.info(“Intercept request successfully !!!”);
        filterChain.doFilter(request, response);
    }
}

在这里,CustomFilterPortlet扩展了BaseFilter并覆盖了processFilter方法,我们可以在其中编写逻辑,并且必须在@Component属性中将 url 模式指定为url-pattern=/*

如何覆盖 Liferay Struts 动作

在 Liferay 6.2 和其他早期版本中,所有 Liferay 操作都由struts-config.xml中定义的 struts 操作处理。 另一方面,在 Liferay 7 DXP 中,大多数操作都在ActionCommand中进行了转换。Liferay 7 仍然具有struts-config.xml中定义的一些支持动作。

如果要覆盖该特定操作,则可以使用StrutsAction.class覆盖它。 请注意,StrutsAction.class只能覆盖struts-config.xml文件中定义的 struts 动作。

在这里,我们将覆盖“条款和条件”操作,该操作在用户首次登录且必须接受条款和条件时执行。

blade create -t mvcportlet -p com.azilen.custom.struts.action -c
CustomTermsOfUseActionPortlet struts-action-fragment
CustomTermsOfUseActionPortlet.Java
@Component(
    immediate=true,
    property={
        "path=/portal/update_terms_of_use"
    },
    service = StrutsAction.class
)
public class CustomTermsOfUseActionPortlet extends BaseStrutsAction {
    private static final Log _log =
        LogFactoryUtil.getLog(CustomTermsOfUseActionPortlet.class);
    @Override
    public String execute(StrutsAction originalStrutsAction, HttpServletRequest request,
        HttpServletResponse response)throws Exception {
        log.info("Calling Custom Termsof Use Action");
        //you logic goes here
        return originalStrutsAction.execute(request, response);
    }
}

在这里,CustomTermsOfUseActionPortlet扩展了BaseStrutsAction并覆盖了executes方法,我们可以在其中编写自定义逻辑。 我们需要在@Component的属性"path=/portal/update_terms_of_use"中指定要覆盖的 struts 操作路径。

如何覆盖 Liferay 模态监听器

有时,我们可能需要覆盖 Liferay 的 OOTB 实体,例如UserGroupDLFileEntry 等,以执行onAfterUpdateonBeforeUpdate之类的操作。 我们可以使用BaseModelListener<T>类覆盖这些方法。

在这里,我们将覆盖 Liferay UseronAfterUpdate方法,该方法将在更新任何用户时执行。

blade create -t mvcportlet -p com.azilen.modal.listener.portlet –c CustomUserModalListerPortlet custom-model-listener-module
@Component(
    immediate = true,
    service = ModelListener.class
)
public class CustomUserModalListerPortlet extends BaseModelListener<User> {

    @Override
    public void onAfterUpdate(User model) throws ModelListenerException {
        _log.info("user is updateing... !!!!");
        super.onAfterUpdate(model);
    }
    private static final Log _log =
        LogFactoryUtil.getLog(CustomUserModalListerPortlet.class);
}

在这里CustomUserModalListerPortlet扩展了BaseModelListener&lt;User&gt;并覆盖了onAfterUpdate方法,在这里我们可以编写自定义逻辑。 我们需要在@Component中将服务属性值定义为ModelListener.class

自定义 Liferay DXP 开放源代码以开发高度可扩展的现代应用程序具有极大的可能性。 程序员发现 Lifera 7 非常有趣,因为它使编码成为基于创意和逻辑思考的过程。 结果, Liferay DXP 开发在开发人员和行业中都越来越受欢迎。

作者简介

Sandip Patel 是一名技术爱好者,并且是拥有 7 年以上经验的 Liferay & MongoDB 认证专家。 他正在与 Azilen Technologies 合作,并且喜欢随时了解最新的 Liferay 技术和创新。

简单的 Git 教程

原文: https://javatutorial.net/simple-git-tutorial

在本教程中,您将学习非常基本的 Git 命令,使您可以在几分钟内运行 Git。

什么是 Git?

Git 是广泛使用的分布式修订控制系统。 它最初于 2005 年开发,自 2015 年 10 月 4 日以来最新版本是 2.7。 所有主要操作系统(如 Linux,OSX 和 Microsoft Windows)均支持该功能。

在 OSX 上安装 Git

在 Windows 上安装 Git

或在 Linux 上安装 git,运行以下命令:

$ sudo yum install git-all

或在基于 Debian 的发行版(如 Ubuntu)上使用

$ sudo apt-get install git-all

创建新的 Git 存储库

您可以通过在硬盘上创建一个文件夹来创建本地存储库,转到该文件夹​​并执行:

git init

尽管使用本地存储库在许多方面都非常熟练,并且您可以尝试使用它,但是我强烈建议使用远程 Git 服务器并托管 GitHub 等。 GitHub 有一个不错的界面来管理,创建和维护您的存储库,以及用于监视贡献和用户的高级工具。

Git 工作流程

有三种方法可以将代码从工作目录带到远程存储库:

Git workflow

Git 工作流程

工作目录 –它包含实际文件

索引 –是标记代码更改的登台区域

HEAD –保存您所做的最后一次提交

远程服务器 –是代码所在的最终目的地,因此您的更改可供其他开发人员使用

检出 Git 存储库

要制作现有存储库的工作本地副本,请执行以下操作:

git clone {path_to_repository}

这将在当前目录中下载存储库的副本。

例如,如果要克隆托管在 GitHub 中的存储库,请运行以下命令:

git clone https://github.com/JavaTutorialNetwork/Tutorials.git

在 GitHub 中,您可以在此处找到存储库路径:

GitHub repository path

GitHub 存储库路径

更新您的本地存储库

在开始对代码进行更改之前,最好先检查团队中其他开发人员所做的代码更新,这是一个好习惯。 为此,请执行:

git pull

第 1 步 – 将更改添加到索引

您可以使用以下任一方法将代码更改提交到索引:

git add <filename>

用于特定文件或

git add *

提交所有文件

第 2 步 – 将更改提交到HEAD

在此步骤中,您实际上将更改提交到HEAD。 在这之后,所有的工作都准备好转移到远程存储库中了

git commit -m "Message explaining your changes"

第 3 步 - 将更改推送到远程服务器

在这一步中,您将对远程 Git 服务器进行更改,以供其他开发人员使用

git push origin master

这会将更改推送到master 分支(默认)。 如果您想将它们推到另一个分支,只需更改名称

撤消本地更改

在某些情况下,例如您做错了一些事情,您将希望用 Git 远程存储库中的代码替换并覆盖本地更改。 为此,请执行:

git fetch origin
git reset --hard origin/master

这将清除所有本地工作(尚未推送到远程服务器的工作),并将工作目录同步到当前回购状态。

一如既往欢迎评论🙂

使用 Java 捕获网络数据包

原文: https://javatutorial.net/capture-network-packages-java

该示例演示了如何使用 pcap 和 Java 捕获网络数据包。

要运行示例,您将需要为操作系统安装 libpcap 。 对于 Windows,下载并安装 WinPcap

Ubuntu 用户可以运行以下命令来安装 libpcap:

sudo apt-get install libpcap-dev

我们将使用 jNetPcap 作为 Java 包装器。 以下示例要求版本 1.4

列出网络设备

import java.util.ArrayList;
import java.util.List;

import org.jnetpcap.Pcap;
import org.jnetpcap.PcapIf;

public class NetworkInterfaces {

	public static void main(String[] args) {
		List<PcapIf> alldevs = new ArrayList<PcapIf>(); // Will be filled with NICs
		StringBuilder errbuf = new StringBuilder(); // For any error msgs

		int r = Pcap.findAllDevs(alldevs, errbuf);
		if (r == Pcap.NOT_OK || alldevs.isEmpty()) {
			System.err.printf("Can't read list of devices, error is %s",
					errbuf.toString());
			return;
		}

		System.out.println("Network devices found:");

		int i = 0;
		for (PcapIf device : alldevs) {
			String description = (device.getDescription() != null) ? device
					.getDescription() : "No description available";
			System.out.printf("#%d: %s [%s]\n", i++, device.getName(),
					description);
		}
	}

}

捕捉数据包

以下完整示例捕获了前 10 个数据包:

import java.util.ArrayList;
import java.util.List;

import org.jnetpcap.Pcap;
import org.jnetpcap.PcapIf;
import org.jnetpcap.packet.PcapPacket;
import org.jnetpcap.packet.PcapPacketHandler;
import org.jnetpcap.protocol.network.Ip4;

public class PackageCapture {

	public static void main(String[] args) {
		List<PcapIf> alldevs = new ArrayList<PcapIf>(); // Will be filled with NICs
		StringBuilder errbuf = new StringBuilder(); // For any error msgs

		int r = Pcap.findAllDevs(alldevs, errbuf);
		if (r != Pcap.OK || alldevs.isEmpty()) {
			System.err.printf("Can't read list of devices, error is %s",
					errbuf.toString());
			return;
		}

		System.out.println("Network devices found:");

		int i = 0;
		for (PcapIf device : alldevs) {
			String description = (device.getDescription() != null) ? device
					.getDescription() : "No description available";
			System.out.printf("#%d: %s [%s]\n", i++, device.getName(),
					description);
		}

		PcapIf device = alldevs.get(0); // Get first device in list
		System.out.printf("\nChoosing '%s' on your behalf:\n",
				(device.getDescription() != null) ? device.getDescription()
						: device.getName());

		int snaplen = 64 * 1024; // Capture all packets, no trucation
		int flags = Pcap.MODE_PROMISCUOUS; // capture all packets
		int timeout = 10 * 1000; // 10 seconds in millis
		Pcap pcap = Pcap.openLive(device.getName(), snaplen, flags, timeout, errbuf);

		if (pcap == null) {
			System.err.printf("Error while opening device for capture: "
					+ errbuf.toString());
			return;
		}

		PcapPacketHandler<String> jpacketHandler = new PcapPacketHandler<String>() {

			public void nextPacket(PcapPacket packet, String user) {

				byte[] data = packet.getByteArray(0, packet.size()); // the package data
				byte[] sIP = new byte[4];
				byte[] dIP = new byte[4];

				Ip4 ip = new Ip4();
				if (packet.hasHeader(ip) == false) {
					return; // Not IP packet
				}

				ip.source(sIP);
				ip.destination(dIP);

				/* Use jNetPcap format utilities */
				String sourceIP = org.jnetpcap.packet.format.FormatUtils.ip(sIP);
				String destinationIP = org.jnetpcap.packet.format.FormatUtils.ip(dIP);

				System.out.println("srcIP=" + sourceIP + 
						" dstIP=" + destinationIP + 
						" caplen=" + packet.getCaptureHeader().caplen());
			}
		};

		// capture first 10 packages
		pcap.loop(10, jpacketHandler, "jNetPcap");

		pcap.close();
	}

}

如果要捕获特定的数据包,可以设置一个过滤器,如下所示:

PcapBpfProgram filter = new PcapBpfProgram();
String expression = "tcp port 3724 or tcp port 1119";
int optimize = 0; // 0 = false
int netmask = 0xFFFFFF00; // 255.255.255.0

if (pcap.compile(filter, expression, optimize, netmask) != Pcap.OK) {
	System.err.println(pcap.getErr());
	return;
}

if (pcap.setFilter(filter) != Pcap.OK) {
	System.err.println(pcap.getErr());
	return;
}

Selenium Java 教程

原文: https://javatutorial.net/selenium-java-tutorial

本教程将说明如何使用 Java 运行 Selenium WebDriver

Selenium 是用于测试 Web 应用程序的强大框架。 使用 Selenium,您可以自动浏览,单击和提交网页上的表单。 对网络应用程序进行更改后,最好通过一些手动和自动测试来运行它并验证一切是否正常运行。 本教程将向您展示如何使用 Java 编程语言编写测试脚本。 我假设您已经对 Java 有一定的经验。 如果没有阅读,请先阅读我们的 Java 初学者教程

Selenium Maven 构建

如果您使用 Maven 来构建项目,请在.pom文件中使用以下依赖项

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>2.44.0</version>
</dependency>

Selenium.jar文件

如果您喜欢老式的方法,则必须从 Selenium 网站下载所需的.jar

  1. 转到 Selenium 下载页面

  2. 下载 Java 2.xx zip 文件

    selenium-download

  3. selenium-java-2.44.0.jar和所有 jar 从libs文件夹复制到您的项目中

Selenium 控制台示例

这是一个基本的 Selenium Java 示例。 它使用默认的HtmlUnitDriver以类似控制台的样式提取页面标题。

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;

public class SeleniumConsoleExample {
	public static void main(String[] args) {
		// Create HTML Unit Driver - this is the build in Selenium client
        	WebDriver driver = new HtmlUnitDriver();

        	// go to url
        	driver.get("http://javatutorial.net");

        	// Check the title of the page
        	System.out.println("Page title is: " + driver.getTitle());

        	driver.quit();
	}
}

Selenium Firefox 示例

在许多情况下,您将需要 Selenium 与动态创建的元素一起使用。 为此,您将需要一个类似 Firefox 或 Google Chrome 的浏览器窗口。

以下示例需要在默认位置安装 Firefox Web 浏览器。

  1. Selenium 将打开一个单独的 Firefox 窗口并转到 https://javatutorial.net

  2. 查看此页面顶部的搜索按钮(放大镜),是 - 当前正在阅读的页面顶部 🙂 Selenium 将光标移至该位置以显示搜索字段

  3. 它将输入搜索词“java”并提交表格

  4. 等待 5 秒钟,然后关闭浏览器窗口

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class SeleniumFirefoxExample {
	public static void main(String[] args) throws Exception {
		// create a Firefox Web Driver
		WebDriver driver = new FirefoxDriver();
		// open the browser and go to JavaTutorial Network Website
		driver.get("https://javatutorial.net");

		// find the search button on the page
		WebElement searchButton = driver.findElement(By
				.className("search-submit"));
		// create an action handler
		Actions actions = new Actions(driver);
		// use the action handler to move the cursor to given element
		actions.moveToElement(searchButton).perform();

		// wait until the search field is presented on the webpage and create an
		// element
		WebElement searchField = (new WebDriverWait(driver, 10))
				.until(ExpectedConditions.presenceOfElementLocated(By.name("s")));

		// puts the text "java" into the search field
		searchField.sendKeys("java");
		// submit the search (submit the form)
		searchField.submit();

		// wait 5 seconds and close the browser
		Thread.sleep(5000);
		driver.quit();
	}
}

Selenium Chrome 示例

要使 Selenium 使用 Google Chrome 浏览器,您需要下载并运行独立的 Chrome WebDriver。

1.下载适用于您操作系统的 Chrome Web 驱动程序,该归档文件包含一个可执行文件

2.启动可执行文件 – 它将在端口 9515 上运行本地服务器

3.在您的代码中像这样创建 WebDriver:

URL local = new URL("http://localhost:9515");
WebDriver driver = new RemoteWebDriver(local, DesiredCapabilities.chrome());

这是与上述使用 Chrome 网络驱动程序相同的示例:

import java.net.URL;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class SeleniumChromeExample {
	public static void main(String[] args) throws Exception {
		// create a Chrome Web Driver
		URL local = new URL("http://localhost:9515");
		WebDriver driver = new RemoteWebDriver(local, DesiredCapabilities.chrome());

		// open the browser and go to JavaTutorial Network Website
		driver.get("http://javatutorial.net");

		// find the search button on the page
		WebElement searchButton = driver.findElement(By
				.className("search-submit"));
		// create an action handler
		Actions actions = new Actions(driver);
		// use the action handler to move the cursor to given element
		actions.moveToElement(searchButton).perform();

		// wait until the search field is presented on the webpage and create an
		// element
		WebElement searchField = (new WebDriverWait(driver, 10))
				.until(ExpectedConditions.presenceOfElementLocated(By.name("s")));

		// puts the text "java" into the search field
		searchField.sendKeys("java");
		// submit the search (submit the form)
		searchField.submit();

		// wait 5 seconds and close the browser
		Thread.sleep(5000);
		driver.quit();
	}
}

使用特定工作区运行 Eclipse

原文: https://javatutorial.net/run-eclipse-with-specific-workspace

如果您维护大量项目,则在不同的工作区中拆分工作是一个好习惯。 例如。 您有一个工作区用于 Android 开发,一个工作区用于测试,一个工作区用于生产。

工作区按目录组织。 您必须为每个工作区创建单独的目录。 之后,您可以使用-data命令行参数将日食指向特定的工作空间

[path to eclipse] -data [workspace path]

在 Windows 环境中,右键单击 Eclipse 快捷方式,然后选择“属性”。

Eclipse properties

Eclipse 属性对话框

例如,如果要使用 TestWorkspace 启动 Eclipse,请在“目标”字段中输入以下内容:

D:\Development\eclipse\eclipse.exe -data D:\Development\TestWorkspace

在 Eclipse 中安装 SVN

原文: https://javatutorial.net/install-svn-eclipse

默认情况下,Eclipse 不支持 SVN 存储库浏览。 幸运的是,有几个插件使之成为可能。

在本教程中,我将向您展示如何安装 Tigris 的 Subclipse 插件。 这简单!

1. 启动 Eclipse

2. 转到“帮助 -> 安装新软件”

eclipse_help_install_new_so

3. 在“使用”字段中输入 Eclipse 更新站点 URL。 如果您使用 Eclipse KEPLER,请使用 1.10.x 版。 对于早期的 Eclipse 版本,建议您使用 1.6.x 版本。 它与大多数 SVN 服务器兼容。

1.10.x 版本的链接: http://subclipse.tigris.org/update_1.10.x

1.8.x 版本的链接: http://subclipse.tigris.org/update_1.8.x

1.6.x 版本的链接: http://subclipse.tigris.org/update_1.6.x

1.4.x 版本的链接: http://subclipse.tigris.org/update_1.4.x

subclipse-url

4. 按下[Enter]键,不久您将看到要安装的组件列表。 选择第一个和第三个,然后单击“下一步”按钮(我在具有 JNA 库的 64 位计算机上遇到了一些问题,这就是为什么我不安装它)

subclipse-components

5. 在下一个屏幕上,再次单击“下一步”,同意许可协议,然后单击“完成”按钮

6. 等待一段时间,直到下载并安装了软件包。 您将需要重新启动 Eclipse 才能使更改生效。

7. 单击 Eclipse 右上角的“打开透视图”按钮

open perspective

...并在此窗口中选择“SVN 存储库浏览”

svn repository exploring

8. 右键单击“SVN 存储库”视图,然后选择“新建 -> 存储库位置…”。

new repository

9. 在下一个窗口中,输入要浏览/使用的 SVN 存储库 URL

如何运行 NodeJS 服务器

原文: https://javatutorial.net/how-to-run-nodejs-server

在此页面上,我将向您展示如何设置和运行 Node.js Web 服务器以在本地计算机上托管静态 Web 应用程序。

Node.js 轻巧高效。 我们可以使用它来将 Web 应用程序部署到我们的本地主机或远程主机。 它非常易于使用和设置

下载 Node.js

转到 Node.js 下载页面。 https://nodejs.org/download/ 。 每个操作系统都有 2 个选项 - 安装程序和独立可执行文件。 您可以下载适合您的操作系统的文件。

设置 Node.js

浏览到已安装(或解压缩)node.js 的文件夹。

在与节点可执行文件相同的文件夹中创建一个名为public_html的文件夹 - 我们将使用此文件夹进行 Web 项目

在与节点可执行文件相同的文件夹中创建具有以下内容的新文件webserver.js

var connect = require('connect');
var serveStatic = require('serve-static');

var app = connect();
app.use(serveStatic("public_html"));
app.listen(5100);

这个简单的 JavaScript 代码实现了一个 Web 服务器,该服务器为 http://localhost:5100 上托管的静态 HTML 文件提供 HTTP 请求。 假定您在node.exe(适用于 Windows)或节点可执行文件(OSX 和 Linux)所在的同一文件夹中创建public_html文件夹

现在,从 Node.js 安装文件夹中运行这两个命令(这将安装运行静态页面所需的两个模块)

npm install connect
npm install serve-static

使用以下命令启动新服务器

node webserver.js

创建示例页面并测试服务器

public_html文件夹中创建一个名为test.html的新文件,其内容如下:

<!DOCTYPE html>
<html>
<head>
	<title>Welocme page</title>
</head>
<body>
	Your simple Node.js server is up and running!
</body>
</html>

现在打开浏览器并输入 http://localhost:5100/test.html

如果一切顺利,您应该在浏览器中看到以下内容

Node.js test page

Node.js 测试页

如果您喜欢本教程,请分享并发表评论。

SQL 内连接示例

原文: https://javatutorial.net/sql-inner-join-example

本文介绍了 SQL INNER JOIN语法,并提供了有关如何使用INNER JOIN的示例

最常用的连接是INNER JOIN。 它通过组合两个或多个表的列值来创建新的结果表。

您可以使用以下链接查看不同类型的 SQL JOIN

  1. 内连接
  2. 左连接
  3. 右连接
  4. 外连接

内连接视觉表示

SQL inner join

SQL 内连接

内连接语法

该查询将返回左表(表 A)中所有与右表(表 B)中具有匹配记录的记录。 此连接的编写方式如下:

SELECT Table_A.column1, Table_B.column2...
FROM Table_A A
INNER JOIN Table_B B
ON A.Key = B.Key

内连接示例

我们将创建 3 个表

  1. CUSTOMER
  2. PRODUCT
  3. ORDER

客户可以订购产品。 在ORDER表中,我们保存了客户 ID 和客户已订购的每种产品的数量。

Database diagram showing customer, product and order relationship

数据库图显示客户,产品和订单关系

使用以下 SQL 脚本创建三个表。

创建CUSTOMER

CREATE TABLE `CUSTOMER` (
  `id` INT NOT NULL,
  `name` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`id`));

创建PRODUCT

CREATE TABLE `PRODUCT` (
  `id` INT NOT NULL,
  `name` VARCHAR(45) NOT NULL,
  `price` DECIMAL(7,2) NOT NULL,
  PRIMARY KEY (`id`));

创建ORDER

CREATE TABLE `ORDER` (
  `id` INT NOT NULL,
  `date` DATETIME NOT NULL,
  `customer_id` INT NOT NULL,
  `product_id` INT NOT NULL,
  `quantity` INT NOT NULL,
  PRIMARY KEY (`id`),
  INDEX `product_id_idx` (`product_id` ASC) VISIBLE,
  INDEX `customer_id_idx` (`customer_id` ASC) VISIBLE,
  CONSTRAINT `customer_id`
    FOREIGN KEY (`customer_id`)
    REFERENCES `CUSTOMER` (`id`),
  CONSTRAINT `product_id`
    FOREIGN KEY (`product_id`)
    REFERENCES `PRODUCT` (`id`));

CUSTOMER表中插入数据

INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('1', 'Jon Snow');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('2', 'Daenerys Targaryen');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('3', 'Sansa Stark');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('4', 'Arya Stark');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('5', 'Jorah Mormont');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('6', 'Bronn of the Blackwater');

PRODUCT表中插入数据

INSERT INTO `PRODUCT` (`id`, `name`, `price`) VALUES ('1', 'Dragon', '5000');
INSERT INTO `PRODUCT` (`id`, `name`, `price`) VALUES ('2', 'Castle', '1000');
INSERT INTO `PRODUCT` (`id`, `name`, `price`) VALUES ('3', 'Sword', '5');

ORDER表中插入数据

INSERT INTO `ORDER` (`id`, `date`, `customer_id`, `product_id`, `quantity`) VALUES ('1', '2019-01-08 00:00:00', '2', '1', '3');
INSERT INTO `ORDER` (`id`, `date`, `customer_id`, `product_id`, `quantity`) VALUES ('2', '2019-01-22 00:00:00', '6', '3', '1');
INSERT INTO `ORDER` (`id`, `date`, `customer_id`, `product_id`, `quantity`) VALUES ('3', '2019-02-15 00:00:00', '6', '2', '1');
INSERT INTO `ORDER` (`id`, `date`, `customer_id`, `product_id`, `quantity`) VALUES ('4', '2019-02-16 00:00:00', '1', '3', '1');

数据库表

现在这就是我们表中的内容:

CUSTOMER table

客户表

PRODUCT table

产品表

订单表

内连接表

现在,让我们使用INNER JOIN连接这些表

该查询返回客户详细信息,购买日期和数量

SELECT C.id, C.name, O.date, O.quantity
FROM `CUSTOMER` C
INNER JOIN `ORDER` O
ON C.id = O.customer_id;

Inner join result set

内连接结果集

连接多个表

下一个示例显示如何将 3 个表连接到一个结果集中。 以下查询将返回连接的整个购买,显示客户名称,购买日期,产品名称和数量

SELECT C.name, O.date, P.name, O.quantity
FROM `ORDER` O 
JOIN `CUSTOMER` C ON O.customer_id = C.id 
JOIN `PRODUCT` P ON O.product_id = P.id;

查询执行的结果:

Join multiple tables

连接多个表

免责声明:上面显示的示例已经在 MySQL 上进行了测试。 根据您的 SQL 数据库,CREATE TABLE语法可能有所不同。

SQL 左连接示例

原文: https://javatutorial.net/sql-left-join-example

本文介绍了 SQL LEFT JOIN语法,并提供了有关如何使用LEFT JOIN的示例

左连接返回左表中的所有值,以及右表中的匹配值。 如果右表中没有与左表中给定记录匹配的结果,则结果值将返回为 NULL。

左连接和左外部连接在术语方面相同。

您可以使用以下链接查看不同类型的 SQL JOIN

  1. 内连接
  2. 左连接
  3. 右连接
  4. 外连接

左连接视觉表示

SQL left join

SQL 左连接

左连接语法

该查询将返回左表(表 A)中的所有记录,无论这些记录中的任何一个在右表(表 B)中是否匹配

SELECT Table_A.column1, Table_B.column2...
FROM Table_A A
LEFT JOIN Table_B B
ON A.Key = B.Key

左连接示例

我们将创建 3 个表

  1. CUSTOMER
  2. PRODUCT
  3. ORDER

客户可以订购产品。 在ORDER表中,我们保存了客户 ID 和客户已订购的每种产品的数量。

Database diagram showing customer, product and order relationship

数据库图显示客户,产品和订单关系

使用以下 SQL 脚本创建三个表。

创建CUSTOMER

CREATE TABLE `CUSTOMER` (
  `id` INT NOT NULL,
  `name` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`id`));

创建PRODUCT

CREATE TABLE `PRODUCT` (
  `id` INT NOT NULL,
  `name` VARCHAR(45) NOT NULL,
  `price` DECIMAL(7,2) NOT NULL,
  PRIMARY KEY (`id`));

创建ORDER

CREATE TABLE `ORDER` (
  `id` INT NOT NULL,
  `date` DATETIME NOT NULL,
  `customer_id` INT NOT NULL,
  `product_id` INT NOT NULL,
  `quantity` INT NOT NULL,
  PRIMARY KEY (`id`),
  INDEX `product_id_idx` (`product_id` ASC) VISIBLE,
  INDEX `customer_id_idx` (`customer_id` ASC) VISIBLE,
  CONSTRAINT `customer_id`
    FOREIGN KEY (`customer_id`)
    REFERENCES `CUSTOMER` (`id`),
  CONSTRAINT `product_id`
    FOREIGN KEY (`product_id`)
    REFERENCES `PRODUCT` (`id`));

CUSTOMER表中插入数据

INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('1', 'Jon Snow');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('2', 'Daenerys Targaryen');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('3', 'Sansa Stark');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('4', 'Arya Stark');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('5', 'Jorah Mormont');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('6', 'Bronn of the Blackwater');

PRODUCT表中插入数据

INSERT INTO `PRODUCT` (`id`, `name`, `price`) VALUES ('1', 'Dragon', '5000');
INSERT INTO `PRODUCT` (`id`, `name`, `price`) VALUES ('2', 'Castle', '1000');
INSERT INTO `PRODUCT` (`id`, `name`, `price`) VALUES ('3', 'Sword', '5');

ORDER表中插入数据

INSERT INTO `ORDER` (`id`, `date`, `customer_id`, `product_id`, `quantity`) VALUES ('1', '2019-01-08 00:00:00', '2', '1', '3');
INSERT INTO `ORDER` (`id`, `date`, `customer_id`, `product_id`, `quantity`) VALUES ('2', '2019-01-22 00:00:00', '6', '3', '1');
INSERT INTO `ORDER` (`id`, `date`, `customer_id`, `product_id`, `quantity`) VALUES ('3', '2019-02-15 00:00:00', '6', '2', '1');
INSERT INTO `ORDER` (`id`, `date`, `customer_id`, `product_id`, `quantity`) VALUES ('4', '2019-02-16 00:00:00', '1', '3', '1');

数据库表

现在这就是我们表中的内容:

CUSTOMER table

客户表

PRODUCT table

产品表

订单表

左连接表

现在,让我们使用LEFT JOIN连接这些表

该查询返回客户详细信息和购买日期

SELECT `CUSTOMER`.id, `CUSTOMER`.name, `ORDER`.date
FROM `CUSTOMER`
LEFT JOIN `ORDER` 
ON `CUSTOMER`.id = `ORDER`.customer_id;

Left join result set

左连接结果集

免责声明:上面显示的示例已经在 MySQL 上进行了测试。 根据您的 SQL 数据库,CREATE TABLE语法可能有所不同。

SQL 右连接示例

原文: https://javatutorial.net/sql-right-join-example

本文介绍了 SQL RIGHT JOIN语法,并提供了有关如何使用RIGHT JOIN的示例

右连接返回右表中的所有值,以及左表中的匹配值。 如果左表中没有与右表中给定记录匹配的结果,则返回的结果将为NULL

RIGHT JOINRIGHT OUTER JOIN的术语相同。

您可以使用以下链接查看不同类型的 SQL JOIN

  1. 内连接
  2. 左连接
  3. 右连接
  4. 外连接

右连接视觉表示

SQL right join

SQL 右连接

右连接语法

该查询将返回左表(表 A)中的所有记录,无论这些记录中的任何一个在右表(表 B)中是否匹配

SELECT Table_A.column1, Table_B.column2...
FROM Table_A A
RIGHT JOIN Table_B B
ON A.Key = B.Key

右连接示例

我们将创建 3 个表

  1. CUSTOMER
  2. PRODUCT
  3. ORDER

客户可以订购产品。 在ORDER表中,我们保存了客户 ID 和客户已订购的每种产品的数量。

Database diagram showing customer, product and order relationship

数据库图显示客户,产品和订单关系

使用以下 SQL 脚本创建三个表。

创建CUSTOMER

CREATE TABLE `CUSTOMER` (
  `id` INT NOT NULL,
  `name` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`id`));

创建PRODUCT

CREATE TABLE `PRODUCT` (
  `id` INT NOT NULL,
  `name` VARCHAR(45) NOT NULL,
  `price` DECIMAL(7,2) NOT NULL,
  PRIMARY KEY (`id`));

创建ORDER

CREATE TABLE `ORDER` (
  `id` INT NOT NULL,
  `date` DATETIME NOT NULL,
  `customer_id` INT NOT NULL,
  `product_id` INT NOT NULL,
  `quantity` INT NOT NULL,
  PRIMARY KEY (`id`),
  INDEX `product_id_idx` (`product_id` ASC) VISIBLE,
  INDEX `customer_id_idx` (`customer_id` ASC) VISIBLE,
  CONSTRAINT `customer_id`
    FOREIGN KEY (`customer_id`)
    REFERENCES `CUSTOMER` (`id`),
  CONSTRAINT `product_id`
    FOREIGN KEY (`product_id`)
    REFERENCES `PRODUCT` (`id`));

CUSTOMER表中插入数据

INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('1', 'Jon Snow');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('2', 'Daenerys Targaryen');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('3', 'Sansa Stark');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('4', 'Arya Stark');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('5', 'Jorah Mormont');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('6', 'Bronn of the Blackwater');

PRODUCT表中插入数据

INSERT INTO `PRODUCT` (`id`, `name`, `price`) VALUES ('1', 'Dragon', '5000');
INSERT INTO `PRODUCT` (`id`, `name`, `price`) VALUES ('2', 'Castle', '1000');
INSERT INTO `PRODUCT` (`id`, `name`, `price`) VALUES ('3', 'Sword', '5');

ORDER表中插入数据

INSERT INTO `ORDER` (`id`, `date`, `customer_id`, `product_id`, `quantity`) VALUES ('1', '2019-01-08 00:00:00', '2', '1', '3');
INSERT INTO `ORDER` (`id`, `date`, `customer_id`, `product_id`, `quantity`) VALUES ('2', '2019-01-22 00:00:00', '6', '3', '1');
INSERT INTO `ORDER` (`id`, `date`, `customer_id`, `product_id`, `quantity`) VALUES ('3', '2019-02-15 00:00:00', '6', '2', '1');
INSERT INTO `ORDER` (`id`, `date`, `customer_id`, `product_id`, `quantity`) VALUES ('4', '2019-02-16 00:00:00', '1', '3', '1');

数据库表

现在这就是我们表中的内容:

CUSTOMER table

客户表

PRODUCT table

产品表

订单表

右连接表

现在,让我们使用RIGHT JOIN连接这些表

该查询返回客户详细信息和购买日期

SELECT `CUSTOMER`.id, `CUSTOMER`.name, `ORDER`.date
FROM `CUSTOMER`
RIGHT JOIN `ORDER` 
ON `CUSTOMER`.id = `ORDER`.customer_id;

Right join result set

右连接结果集

免责声明:上面显示的示例已经在 MySQL 上进行了测试。 根据您的 SQL 数据库,CREATE TABLE语法可能有所不同。

SQL 外连接示例

原文: https://javatutorial.net/sql-outer-join-example

本文介绍了 SQL OUTER JOIN语法,并提供了有关如何使用OUTER JOIN的示例

外连接连接表将包含两个表(A 和 B)中的所有记录,并为任何缺少的匹配项填充 NULL。

在术语方面,外连接和完全连接是相同的。

您可以使用以下链接查看不同类型的 SQL JOIN

  1. 内连接
  2. 左连接
  3. 右连接
  4. 外连接

外连接视觉表示

SQL outer join

SQL 外连接

外连接语法

该查询将返回两个表中所有记录的合并结果

SELECT Table_A.column1, Table_B.column2...
FROM Table_A A
FULL JOIN Table_B B
ON A.Key = B.Key

外连接示例

我们将创建 3 个表

  1. CUSTOMER
  2. PRODUCT
  3. ORDER

客户可以订购产品。 在ORDER表中,我们保存了客户 ID 和客户已订购的每种产品的数量。

Database diagram showing customer, product and order relationship

数据库图显示客户,产品和订单关系

使用以下 SQL 脚本创建三个表。

创建CUSTOMER

CREATE TABLE `CUSTOMER` (
  `id` INT NOT NULL,
  `name` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`id`));

创建PRODUCT

CREATE TABLE `PRODUCT` (
  `id` INT NOT NULL,
  `name` VARCHAR(45) NOT NULL,
  `price` DECIMAL(7,2) NOT NULL,
  PRIMARY KEY (`id`));

创建ORDER

CREATE TABLE `ORDER` (
  `id` INT NOT NULL,
  `date` DATETIME NOT NULL,
  `customer_id` INT NOT NULL,
  `product_id` INT NOT NULL,
  `quantity` INT NOT NULL,
  PRIMARY KEY (`id`),
  INDEX `product_id_idx` (`product_id` ASC) VISIBLE,
  INDEX `customer_id_idx` (`customer_id` ASC) VISIBLE,
  CONSTRAINT `customer_id`
    FOREIGN KEY (`customer_id`)
    REFERENCES `CUSTOMER` (`id`),
  CONSTRAINT `product_id`
    FOREIGN KEY (`product_id`)
    REFERENCES `PRODUCT` (`id`));

CUSTOMER表中插入数据

INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('1', 'Jon Snow');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('2', 'Daenerys Targaryen');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('3', 'Sansa Stark');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('4', 'Arya Stark');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('5', 'Jorah Mormont');
INSERT INTO `CUSTOMER` (`id`, `name`) VALUES ('6', 'Bronn of the Blackwater');

PRODUCT表中插入数据

INSERT INTO `PRODUCT` (`id`, `name`, `price`) VALUES ('1', 'Dragon', '5000');
INSERT INTO `PRODUCT` (`id`, `name`, `price`) VALUES ('2', 'Castle', '1000');
INSERT INTO `PRODUCT` (`id`, `name`, `price`) VALUES ('3', 'Sword', '5');

ORDER表中插入数据

INSERT INTO `ORDER` (`id`, `date`, `customer_id`, `product_id`, `quantity`) VALUES ('1', '2019-01-08 00:00:00', '2', '1', '3');
INSERT INTO `ORDER` (`id`, `date`, `customer_id`, `product_id`, `quantity`) VALUES ('2', '2019-01-22 00:00:00', '6', '3', '1');
INSERT INTO `ORDER` (`id`, `date`, `customer_id`, `product_id`, `quantity`) VALUES ('3', '2019-02-15 00:00:00', '6', '2', '1');
INSERT INTO `ORDER` (`id`, `date`, `customer_id`, `product_id`, `quantity`) VALUES ('4', '2019-02-16 00:00:00', '1', '3', '1');

数据库表

现在这就是我们表中的内容:

CUSTOMER table

客户表

PRODUCT table

产品表

订单表

外连接表

现在,让我们使用OUTER JOIN连接这些表。

该查询返回客户详细信息,购买日期和数量

SELECT C.id, C.name, O.date, O.quantity
FROM `CUSTOMER` C
FULL JOIN `ORDER` O
ON C.id = O.customer_id;

注意:MySQL 不支持外连接,但是您仍然可以通过使用UNION ALL达到相同的结果,如下所示:

SELECT C.id, C.name, O.date, O.quantity
   FROM `CUSTOMER` C
   LEFT JOIN `ORDER` O
   ON C.id = O.customer_id
UNION ALL
   SELECT C.id, C.name, O.date, O.quantity
   FROM `CUSTOMER` C
   RIGHT JOIN `ORDER` O
   ON C.id = O.customer_id;

Outer join result set

外连接结果集

免责声明:上面显示的示例已经在 MySQL 上进行了测试。 根据您的 SQL 数据库,CREATE TABLE语法可能有所不同。

树莓派

Raspberry Pi 3 规格

原文: https://javatutorial.net/raspberry-pi-3

对所有 Raspberry Pi 迷来说都是好消息 – Raspberry Pi 3 Model B 现在正式发售

RaspberryPi 3 Model B

Raspberry Pi 3 模型 B

Raspberry Pi 2 发行一年后,以及最初的 Raspberry Pi Model B 首次发行后正好四年,自 2016 年 2 月 29 日以来,现已正式发售最畅销的信用卡大小的第三代计算机

四年来,Raspberry Pi 开始了一场革命。 全世界的人们都在用小型木板建造无数的项目,例如机器人,自动宠物喂食器,比特币农场,海盗无线电发射器等等。 有了这个板,“您的想象力是唯一的极限”一词成真了。 根据制造商的说法,Raspberry Pi 3 将带来巨大的性能提升,因此请保留所有即将出现的新发明。

Raspberry Pi 3

树莓派 3

新型号的价格为 $35 ,与现有 Raspberry Pi 2 的价格相同。创作者说,他们已经设法改善了制造工艺。 由于它,Pi 3 以与版本 2 相同的价格提供了 Pi 1 的 10 倍的功能。

由于世界范围内的需求仍然很高,因此不会停止生产旧型号。 Pi 1 Model B+ 将继续以 25 美元的价格出售,Pi 2 Model B+ 将保持 35 美元的价格。

Raspberry Pi 3 有什么新功能?

  • 新的 1.2GHz 64 位四核 ARM Cortex-A53 CPU。 该型号为 Broadcom BCM2837,ARM 7 版处理器
  • 1 GB 的 RAM 类型 DDR2 PoP(包装上的包装)
  • Broadcom VideoCore IV GPU 能够以 60 fps 播放 1080p 视频
  • 1 x 10/100 以太网连接
  • 集成 802.11n 无线 LAN
  • 集成蓝牙 4.1
  • 4 个 2.0 USB
  • 1 个 HDMI

还与 Raspberry Pi 1 和 2 完全兼容。 所有连接器都位于同一位置,并且具有相同的功能,并且该板仍可通过 5V 微型 USB 电源适配器运行。

Raspberry Pi 3 ports

Raspberry Pi 3 端口

去哪买?

由于需求量大,目前大多数零售商缺货。 但是,您可能会遇到一些运气,并在接下来的几天内实现交付。

这是零售商列表。 如果您找到其他来源,请在以下评论中添加它们:

RS

将 Raspbian 安装到 SD 卡

原文: https://javatutorial.net/install-raspbian-to-sd-card

本教程将向您展示如何将 Raspbian OS 安装到 SD 卡

Raspberry Pi SD Card

前提条件

现在,您将需要一台内置 SD 卡或内置 SD 卡的 PC / Mac。 我建议至少使用 4GB SD 卡 Class 10。该卡必须是 FAT 32 格式,然后才能对其应用 Raspbian 映像。

下载 Raspbian

尽管有几种可能的 Raspberry Pi 操作系统可供下载,但我还是建议您使用 Raspbian –它具有许多高级功能,并且是 NOOBS 出现之前的官方 Raspberry OS。

要下载 Raspbian 映像,请转到下载页面,然后选择“ZIP 或 Torrent”。 如果您下载 ZIP,请解压缩以解压缩.img文件

使用 Windows 将 Raspian 映像安装到 SD 卡

win32-imagewriter

  1. 下载 Win32DiskImager 实用程序并安装它

  2. 以管理员身份运行程序

  3. 浏览您最近下载的.img文件

  4. 在设备–下拉列表中选择 SD 卡的名称

  5. 按“写入”按钮

使用 Mac OS 将 Raspian 映像安装到 SD 卡

  1. 从 Apple 菜单中,选择“关于本机”,然后单击“系统报告”。

  2. 单击读卡器,然后在窗口右上方搜索您的 SD 卡。 单击它,然后在右下方搜索 BSD 名称; 它看起来像diskn,其中n是一个数字(例如disk2)。 确保记下这个数字

  3. 打开磁盘工具并卸载 SD 卡。 不要弹出

  4. 打开终端并运行:

    sudo dd bs=1m if=path_of_your_image.img of=/dev/diskn
    

    不要忘记将第 2 步中的磁盘名称替换为 diskn

  5. 在将映像内容移至 SD 卡之前,请耐心等待,具体取决于您的硬件,此过程可能需要 20 分钟或更长时间

在我的下一个教程“Raspberry 首次启动” 中,我将说明如何插入电缆并首次启动 Raspberry。

Raspberry Pi 首次启动

原文: https://javatutorial.net/raspberry-pi-first-start

本教程介绍了如何为首次启动准备 Raspberry Pi,如何连接外围设备并首次启动 Raspbian。

你需要什么

1. USB 鼠标

2. USB 键盘

3. 局域网电缆

4. HDMI 线

5. HDMI 监视器或电视

6. 已安装 Raspbian 的 SD 卡(有关详细信息,请阅读本教程

7. 微型 USB 电源适配器。 您可以使用手机电源适配器执行此操作,也可以使用 USB 转 micro USB 电缆连接到计算机。 但是,某些计算机 USB 希望为您的 Raspberry 提供足够的电源。

连接电缆并开始

Rasberry-Pi-ports

  1. 根据上图连接鼠标和键盘

  2. 使用局域网电缆将 Raspberry 连接到路由器

  3. 插入装有 Raspbian 映像的 SD 卡(请阅读本教程,以了解如何在 SD 卡上安装 Raspbian)

  4. 使用 HDMI 电缆将 Raspberry 连接到显示器或电视

  5. 将电源连接到 Raspberry micro USB 端口。 当给树莓供电时,它会自动启动。 您可以拔下电缆以将其关闭。

树莓首次启动

首次使用 Raspbian OS 启动 Raspberry 时,将看到以下屏幕

注意:如果第一次启动时未显示该屏幕,则可以使用以下命令进行调用:

sudo raspi-config

raspberian-expand-filesystem

我在这里要做的是按键盘上的Enter键,并选择选项 1 – 扩展文件系统。 展开完成后,您可能需要浏览其他选项,例如更改 root 密码等。

完成后,使用键盘上的Tab键转到<Finish>,然后按Enter

操作系统将重新启动,几秒钟后,您将看到登录提示

raspbian-login

默认的 Raspbian 用户是:pi

密码为:raspberry

好的! 如果需要,现在可以通过键入以下内容来启动图形界面 GUI:

startx

raspbian-startx

您还可以通过运行以下命令来检查软件更新:

sudo apt-get update && sudo apt-get upgrade

在我的下一个教程中,我将向您展示如何使用 SSH 和 PuTTY 远程连接到 Raspberry。

远程连接到 Raspberry Pi

原文: https://javatutorial.net/connect-remotely-to-raspberry-pi

在本教程中,我将向您展示如何从 PC 或 Mac 远程连接到 Raspberry Pi。

首次启动 Raspberry 之后,您无需使其与鼠标,键盘和显示器一直保持连接状态–您可以使用 Mac 或 PC 进行远程控制。 对于本教程,仅保留 LAN 电缆和电源连接。 当然,您还必须启动 Raspberry。 绿色指示灯亮起后,即可开始远程连接。

在 Raspbian 上启用 SSH

从 2016 年 11 月版本开始,Raspbian 默认禁用 SSH 服务器。 可以启用:

从桌面手动

  1. Preferences菜单启动Raspberry Pi Configuration
  2. 转到Interfaces标签
  3. 选择SSH旁边的Enabled
  4. 点击OK

或者,可以使用raspi-config

  1. 在终端窗口中输入sudo raspi-config
  2. 选择Interfacing Options
  3. 导航并选择SSH
  4. 选择Yes
  5. 选择Ok
  6. 选择Finish

用于无头设置

可以通过将名为ssh的文件(没有任何扩展名)放置在 SD 卡的启动分区上来启用 SSH。 Pi 启动时,它会寻找ssh文件。 如果找到,则启用 SSH,并删除该文件。 文件的内容无关紧要:它可以包含文本,也可以完全不包含任何文本。

与电脑连接

PuTTY 是 Windows 的免费 SSH 客户端。 从官方页面下载可执行文件(putty.exe)。

启动 PuTTY。 在“主机名(或 IP 地址)”下输入 Raspberry 的 IP,并将端口保留为 22。现在按“打开”按钮。

putty-config

在下一个屏幕中,输入您的用户名和密码。

默认的 Raspbian 用户是:pi

密码为:raspberry

putty-login

好的! 现在您已连接,您可以执行所需的任何 linux 命令。

注意:我建议从路由器为 Raspberry 分配一个静态 IP。 这样,您无需在路由器每次为其分配新 IP 时检查 Raspberry 的 IP。

在 PC 和 Raspberry Pi 之间传输文件

我想向您展示的另一个有用的工具是 WinSCP。 这是一个安全的 FTP 客户端,使您能够从 Raspberry Pi 传输文件或将文件传输到 Raspberry Pi。

您可以从官方项目网站下载 WinSCP。

winscp-raspberry

下载并安装后,输入 Raspberry 的 IP,用户名和密码,然后单击“登录”按钮。

从 Mac 连接

打开终端并输入:

ssh pi@192.168.1.134

系统将提示您输入密码。

不要忘记在此处替换pi@192.168.1.134的用户名pi(如果已更改)和该 IP,以您当前的 Raspberry Pi IP

建立 Raspberry Pi 远程桌面连接

原文: https://javatutorial.net/raspberry-pi-remote-desktop-connection

以前,我们已经介绍了如何通过 SSH 访问 Raspberry Pi。

远程访问 Raspberry Pi 无需拥有 2 个屏幕或在 2 个系统之间切换。 在本文中,我将教您如何通过 VNC 为 Raspberry Pi 创建远程桌面连接。

要求

  1. 两个程序:(1)我们需要控制的计算机的 VNC 服务器,以及(2)我们将要控制的小工具上的 VNC Viewer。
  2. Raspberry Pi 存储设备(例如 Micro-SD
  3. 树莓派板
  4. 电脑

幸运的是,Raspbian 已预装了 VNC Connect,它是 RealVNC 的远程访问软件。 VNC Connect 具有 VNC 查看器和 VNC 服务器。 现在,运行此终端命令以检查您是否具有最新的 VNC Connect 版本。

sudo apt-get update
sudo qpt-get install realvnc-vnc-server realvnc-vnc-viewer

步骤 1:激活 VNC

就像我们在 SSH 指南中所做的(首先启用 SSH)一样,通过(a)GUI 或(b)通过终端启用 VNC。 我将在下面讨论如何使用任何一种概述的方法。

(a)通过 GUI 启用 VNC

在您的计算机上,依次转到“首选项>”和“ Raspberry Pi 设置” >,然后单击“接口”。在此同时,选择“ VNC:已启用”。

(b)使用终端启用 VNC

在计算机上,启动 Terminal 并输入以下命令:

sudo raspi-config

转到“高级选项”,然后选择 VNC。 在弹出的提示上,单击“是”,最后选择“完成”退出。

步骤 2:现在通过 VNC Viewer 连接 Raspberry Pi

同样,有两种方法可以通过(i)直接连接和(ii)云连接通过 VNC Viewer 访问远程桌面到 Raspberry Pi。 我将简要讨论这两种方法。

(i)直接连接

如果您使用的是家庭网络,则可以直接建立直接连接。 这是采取的步骤:

    1. 在 Raspberry Pi 终端上,运行以下命令:
hostname -I

终端将显示 IP 地址(专用)。 保存以备后用!

  1. 现在,转到用于命令 Raspberry Pi 的设备并在其上安装 VNC Viewer。在此处下载您的 VNC Viewer
  2. 接下来,输入 VNC Viewer 的 IP 地址(专用)(上面刚刚保存的 IP 地址)
  3. 最后,VNC Server 将要求您使用 Raspberry Pi 的凭据(用户名&密码)进行身份验证。 如果您尚未更改 Pi 的登录凭据,则为“ pi” &“树莓”。

(ii)建立云连接

RealVNC 将允许您注册和使用免费帐户用于非商业目的或用于教育目的。

值得注意的是,云连接是安全的,不需要配置路由器端口转发,甚至不需要知道 Raspberry Pi 的 IP。

但是,云连接不适合家庭网络连接,并且可能比直接连接慢。 建立云端连线的方法如下:

  1. 在此处创建一个 RealVNC
  2. 使用 RealVNC 帐户登录 Raspberry Pi 上的 VNC 服务器。
  3. 接下来,将出现一个屏幕,我们需要从“选择连接方式”选项中选择“直接&云连接”。
  4. 现在,下载您的 VNC Viewer 并将其安装在用于命令 Raspberry Pi 的小工具上。
  5. 使用 RealVNC 帐户登录 VNC 查看器。 单击 Raspberry Pi 图标。
  6. 使用用户名&密码对 Raspberry Pi 进行身份验证(如果适用,请使用默认设置)。

如果目前为止一切正确,我们将在您的设备上看到 Raspberry Pi 的桌面。

步骤 3:最后,创建虚拟桌面

  1. 在 Raspberry Pi 的终端上,运行 vncserver 并记录 Pi 的 IP 地址和屏幕上显示的数字。
  2. 接下来,在小工具上,我们将用于命令 Raspberry Pi,在 VNC Viewer 中键入 IP 地址和端口号。
  3. 输入 Raspberry Pi 身份验证:用户名&密码。 请记住,默认的 Raspberry Pi 凭据分别是“ pi”和“ raspberry”。
  4. 做完了!

Raspberry Pi Java 教程

原文: https://javatutorial.net/raspberry-pi-java-tutorial

在本教程中,我将向您展示如何使用 Raspberry Pi 和 Java 来闪烁 LED 灯。 这将是一个完整的分步教程,从连接电缆开始,通过 GPIO 解释,最后编写 Java 代码。 在本教程的最后,我将向您展示如何使用连接到 Raspberry 的 LED 灯编写完整的 Java 程序。

介绍

您可以建立的最简单的电路之一是连接到光源和开关的电池(电阻器用于保护 LED):

simple-led-circuit

在上图中,Raspberry Pi 替换了开关和电池。

要求

带有 Raspbian 操作系统的 Raspberry Pi 板(了解如何安装和配置 Raspbian

1 x LED 灯

2 x 母对母跳线电缆(您可以在网上购买 40 支,价格低于 2 美元)

required-components

Raspberry Pi GPIO

根据该模型,Raspberry Pi 在板的边缘,黄色视频输出插座旁边提供了不同数量的 GPIO(通用输入/输出)引脚。

Raspberry Pi Pins

这些引脚是 Pi 与外界之间的物理接口。 每个引脚可以打开或关闭,或者在计算方面变为高电平或低电平。 当引脚为高电平时,它输出 3.3 伏特(3v3);当引脚处于高电平时,它输出 3 伏特。 当引脚为低电平时,它关闭。 26 个引脚中的 17 个(用于型号 A 和 B)是 GPIO 引脚; 其他是电源或接地引脚。 型号 A +和 B +有 40 个引脚,其中 26 个是 GPIO 引脚。 本教程适用于所有 Raspberry Pi 型号。

Raspberry Pi Pin Numbers

连线

看下图。 我们将使用跳线将 LED 阴极(-)连接到 Raspberry Pi 的 6 号针脚,将阳极(+)连接到#12 的针脚。

connect-led-to-raspberry

首先将电缆连接到 LED。 我将红色电缆连接到阳极,将棕色电缆连接到阴极。 您可以使用任何喜欢的颜色。

cables-connected-to-led

现在,将电缆的另一端连接到 Raspberry 板的针脚 6 和 12

led-connected-to-raspberry

组装完成。 现在打开 Pi。

在 Raspberry Pi 上安装 Pi4J

在本教程中,我们将使用 Pi4J。 Pi4J 是一种开源 Java API,它与设备进行低级通信,并为我们提供了一种抽象和面向对象的方法,以使用 Java 编程语言来控制 Pi 的 GPIO。

最简单的安装方法是在您的 Pi 上运行以下命令。 这将下载所需的所有依赖项和文件,并将它们放在/opt/pi4j/lib文件夹中。 如果此方法不适合您,则可以在此处探索其他安装选项

curl -s get.pi4j.com | sudo bash

Pi4J 为 GPIO 引脚提供名称和编号,如下所示:

pi4j-pin-numbers

编写代码

首先将 Pi4J 库包含到您的项目中。 如果使用 Maven,则可以将此依赖项添加到 POM 文件中:

<dependency>
	<groupId>com.pi4j</groupId>
	<artifactId>pi4j-core</artifactId>
	<version>${project.version}</version>
</dependency>

您也可以使用老式的方法:

1)从下载页面下载 pi4j ZIP 文件

2)复制以下 JAR 文件并将其包含在您的项目中(在下载的档案的 lib 文件夹中找到):

pi4j-libs

编译代码需要 JAR 文件。

现在,我们有了所有的依赖关系,让我们编写代码。 我们的程序将执行以下操作:

1)开启 LED 2 秒钟

2)关闭 LED 并等待 1 秒钟

3)开启 LED 1 秒钟

import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;

public class LedControl {

    public static void main(String[] args) throws InterruptedException {

        // get a handle to the GPIO controller
    	final GpioController gpio = GpioFactory.getInstance();

        // creating the pin with parameter PinState.HIGH
        // will instantly power up the pin
        final GpioPinDigitalOutput pin = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_01, "PinLED", PinState.HIGH);
        System.out.println("light is: ON");

        // wait 2 seconds
        Thread.sleep(2000);

        // turn off GPIO 1
        pin.low();
        System.out.println("light is: OFF");

        // wait 1 second
        Thread.sleep(1000);

        // turn on GPIO 1 for 1 second and then off
        System.out.println("light is: ON for 1 second");
        pin.pulse(1000, true);

        // release the GPIO controller resources
        gpio.shutdown();
    }
}

像这样在 Raspberry 上执行程序

sudo java -classpath .:classes:/opt/pi4j/lib/'*' LedControl

现在,您应该看到指示灯先亮 2 秒钟,然后亮 1 秒钟。

使用 PWM 的 Raspberry Pi LED 亮度调节

原文: https://javatutorial.net/raspberry-pi-dim-led-pwm-java

在本教程中,我将向您展示如何使用 PWM 控制电压以使 LED 变暗。

打开和关闭 LED 很容易。 您可以在我的上一教程中了解如何执行此操作。 现在,我将向您展示如何控制电压电平以使 LED 灯变弱或变强。 通常,Raspberry GPIO 使用 3.3 的电压。 当该引脚处于上升状态时,输出电压等于 3.3,而当该引脚处于下降状态时,电压为 0。那么如何将电压更改为例如 3.3V 的 50% ? 我们可以使用脉宽调制(PWM)进行此操作。根据 Wikipedia,PWM 是:“一种用于将消息编码为脉冲信号的技术。 尽管这种调制技术可用于编码信息以进行传输,但其主要用途是允许控制提供给电气设备,尤其是惯性负载(如电机)的功率。

在 Raspberry Pi 中,只有一个引脚支持硬件 PWM。 硬件 PWN 引脚产生非常干净的信号。 虽然您可以制作一个软件 PWM,但所有引脚都可以产生 PWM。 软件的 PWM 引脚没有如此清晰的信号,您必须自行设定时序。

我们将使用与先前教程中完全相同的电路。 看下图

connect-led-to-raspberry

以下代码示例将使 LED 逐渐变亮,然后完全熄灭 3 次。 我将 Pi4j API 用于 Java 绑定。 如果您想知道如何使用 Pi4j 安装,配置和运行项目,请参阅我的上一教程

import com.pi4j.wiringpi.Gpio;
import com.pi4j.wiringpi.SoftPwm;

public class DimLEDPWM {

	private static int PIN_NUMBER = 1;

	public static void main(String[] args) throws InterruptedException {
		// initialize wiringPi library, this is needed for PWM
		Gpio.wiringPiSetup();

		// softPwmCreate(int pin, int value, int range)
		// the range is set like (min=0 ; max=100)
		SoftPwm.softPwmCreate(PIN_NUMBER, 0, 100);

		int counter = 0;
		while (counter < 3) {

			// fade LED to fully ON
			for (int i = 0; i <= 100; i++) {
				// softPwmWrite(int pin, int value)
				// This updates the PWM value on the given pin. The value is
				// checked to be in-range and pins
				// that haven't previously been initialized via softPwmCreate
				// will be silently ignored.
				SoftPwm.softPwmWrite(PIN_NUMBER, i);
				Thread.sleep(25);
			}

			// fade LED to fully OFF
			for (int i = 100; i >= 0; i--) {
				SoftPwm.softPwmWrite(PIN_NUMBER, i);
				Thread.sleep(25);
			}

			counter++;
		}
	}
}

您可以使用以下命令在 Raspberry 上运行该程序:

sudo java -classpath .:classes:/opt/pi4j/lib/'*' DimLEDPWM

Raspberry Pi 控制电机速度

原文: https://javatutorial.net/raspberry-pi-control-motor-speed

在本教程中,我将向您展示如何使用 Raspberry Pi 控制直流电机的速度。

如果您正在寻找有关如何同时控制电机的速度和方向的教程,请查看我关于该主题的最新教程。 Raspberry Pi 用 Java 控制直流电机的速度和方向

控制电机是使用 Raspberry Pi 可以做的最令人兴奋的事情之一。 电机是耗电的组件。 它们通常需要比 Raspberry 提供的 3V3 更高的功率。 这就是我们将电机连接到外部电源(电池)的原因。 您可以使用本教程中描述的相同技术来处理需要外部电源的任何组件。

构建电路

在做任何事情之前,我们都必须将它们挂钩。 对于本教程,您将需要

  • 直流电机
  • 外部电源(电池)–您可能需要根据电机使用不同的电压
  • 达灵顿数组芯片(ULN2003)–在本教程的后面,我将为您提供更多详细信息
  • 几根电线

看下图。 它显示了如何构建电路。

raspberry-pi-connect-motor-board

这是我们的电路原理图

raspberry-pi-connect-motor-schematic

达灵顿数组芯片

ULN2003 是七对晶体管,可让我们以安全的方式通过 GPIO 端口使用 3V3 切换更高的电压。 我们可以改用标准晶体管,但为什么可以订购价格低于 0.20 美元的 ULN2003 并可以同时控制 7 台电机,为什么还要打扰呢。

ULN2003 的另一重要之处在于,它可以保护您的 Raspberry GPIO 端口免受电感负载(继电器,螺线管,电机等)关闭时可能出现的电压尖峰的影响。

控制马达

我们将使用软件 PWM 来控制电机速度。 如果您想了解更多有关 PWM 的信息,请阅读我以前的教程具有 PWM 和 Java 的 Raspberry Pi 调光 LED。 我们将使用 Pi4j API 用 Java 编写速度控制程序。 如果您想知道如何使用 Pi4j 安装,配置和运行项目,请参阅本教程

在 Pi4j 中,PWM 值从 0 到 100.在以下示例程序中,我们将利用此值并首先以 25% 的速度旋转电机,然后将其旋转至半速(50% ),然后转至全速(100% ),然后 终于把它拒绝了。

import com.pi4j.wiringpi.Gpio;
import com.pi4j.wiringpi.SoftPwm;

public class MotorPWM {

	private static int PIN_NUMBER = 1;

	public static void main(String[] args) throws InterruptedException {

		System.out.println("Started");

		// initialize wiringPi library, this is needed for PWM
		Gpio.wiringPiSetup();

		// softPwmCreate(int pin, int value, int range)
		// the range is set like (min=0 ; max=100)
		SoftPwm.softPwmCreate(PIN_NUMBER, 0, 100);

		setSpeed(25);
		setSpeed(50);
		setSpeed(100);
		setSpeed(0);

		System.out.println("Finished");
	}

	private static void setSpeed(int speed) throws InterruptedException {
		System.out.println("Speed is set to " + speed + "%");
		// softPwmWrite(int pin, int value)
		// This updates the PWM value on the given pin. The value is checked to
		// be in-range and pins that haven't previously been initialized via 
		// softPwmCreate will be silently ignored.
		SoftPwm.softPwmWrite(PIN_NUMBER, speed);
		// wait 3 seconds
		Thread.sleep(3000);
	}
}

您可以使用以下命令在 Raspberry 上运行该程序:

sudo java -classpath .:classes:/opt/pi4j/lib/'*' MotorPWM

观看视频以查看最终结果

https://www.youtube.com/embed/OqBoNk0HCY8?feature=oembed

Raspberry Pi 用 Java 控制直流电机的速度和方向

https://javatutorial.net/raspberry-pi-control-dc-motor-speed-and-direction-java

在本教程中,我将向您展示如何使用 Raspberry Pi 和 Java 控制直流电机的方向和速度。

我收到了一些要求创建有关使用 Raspberry Pi 和 Java 控制电机速度和方向的教程的请求,所以我们开始吧! 在本教程中,我将向您展示如何使用 L293D 芯片同时控制和两个电机的的方向和速度

硬体需求

您将需要以下组件来遵循本教程:

  • 已安装最新 Raspbian 的 Raspberry Pi(了解如何安装和配置 Raspbian
  • 用于连接所有组件的面包板
  • 一颗 L293D 芯片
  • 1 或 2 个直流电机(第二个为可选),额定电压为 4.5V 至 36V
  • 电池组可为您的电机提供正确的电压
  • 几根电缆可以连接一切

Hardware components

硬件部件

L293D

L293D 是用于直流或步进电机的双 H 桥电机驱动器,这意味着您可以双向驱动两个直流电机或一个步进电机。 L293D 的优点在于,它内置有回弹保护功能,可防止损坏 Raspberry Pi。

切勿将电机直接连接到 Raspberry Pi。 这可能会严重损坏您的 Pi!

L293D Datasheet

L293D 资料表

该芯片有两个+ V 引脚。 引脚号 8(+ Vmotor)为电机供电,而引脚 16 为芯片本身供电。 我们将引脚 8 连接到电池组,将引脚 16 连接到 Raspberry 的 5V 引脚。

选择合适的直流电机

您需要选择 4.5V 至 36V 的直流电机。 L293D 无法在 3V 电机上正常工作,并且每个通道的限制为 600mA。

软件需求

我的所有教程都使用 Pi4J 。 Pi4J 是一个很棒的库,您可以使用 Java 编程语言来控制 Pi 的 GPIO 引脚。 您可以在 Raspberry Pi Java 教程入门中找到有关如何在 Raspberry 和 IDE 上安装和配置 Pi4J 的详细说明。

组装电路

组装电路时,请务必断开 Raspberry Pi 的电源! 否则可能会损坏 Pi 或组件。 插入 Pi 之前,请务必仔细检查接线!

请使用下图组装电路。

Hardware setup for Raspberry Pi 3 to control one DC motor with L293D and Java in both directions

Raspberry Pi 3 的硬件设置,以通过 L293D 和 Java 双向控制一台直流电机

在本教程中,我将使用 GPIO 引脚的物理编号。 物理编号指的是通过简单地从左上角的插针 1 算起并向下计数的插针。

查看下图,该图显示了物理引脚编号和 Pi4J 映射。 例如,物理针脚编号 12 在 Pi4J 中被命名为针脚#1。 在本教程后面的部分中编写 Java 程序时,请牢记这一点。 您可以在 Pi4J 官方网站中找到有关引脚编号的更多详细信息

Raspberry Pi 3 Model B Pins and Pi4J mapping

Raspberry Pi 3 Model B 引脚和 Pi4J 映射

注意:本教程是针对 Raspberry Pi 3 B 型制作的,当然,您可以在 Raspberry Pi 1 或 2 中构建相同的电路并使用相同的 Java 代码 - 只需注意引脚编号即可。

  1. 将 L293D 引脚#16 连接到 Pi 物理引脚#2(5.0 VDC 电源)
  2. 将 L293D 的针脚 4,针脚 5,针脚 12 和针脚 13 连接到 Pi 物理针脚 6(接地)
  3. 将 L293D 的 8 号针脚连接到电池组
  4. 将 L293D 的针脚#3 和#6 连接到电机
  5. 将 L293D 引脚 1 连接到 Pi 物理引脚 22
  6. 将 L293D 引脚 2 连接到 Pi 物理引脚 18
  7. 将 L293D 针脚#7 连接到 Pi 物理针脚#16

我还将在此处发布电路原理图以供参考

Raspberry Pi and L293D one motor schematic

Raspberry Pi 和 L293D 一台电机原理图

具有 1 个电机的组装电路的照片

Picture of the 1 motor setup

1 电机设置的图片

Java 程序:控制一台直流电机的方向

这里是有趣的部分。 连接完所有内容后,您可以打开自己喜欢的 Java IDE 并编写代码。 下面的代码将使电机沿一个方向旋转 3 秒钟,然后使电机沿相反方向旋转 6 秒钟。

import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.RaspiPin;

/**
 * Controls motor direction of a single motor
 * @author https://javatutorial.net
 */
public class ControlOneMotorDirection {

	public static void main(String[] args) throws InterruptedException {
		// get a handle to the GPIO controller
		final GpioController gpio = GpioFactory.getInstance();

		final GpioPinDigitalOutput pinA = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_04, "PinA");
		final GpioPinDigitalOutput pinB = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_05, "PinB");
		final GpioPinDigitalOutput pinE = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_06, "PinE");

		System.out.println("rotate motor clockwise for 3 seconds");
		pinA.high();
		pinB.low();
		pinE.high();

		// wait 3 seconds
		Thread.sleep(3000);

		System.out.println("rotate motor in oposite derection for 6 seconds");
		pinA.low();
		pinB.high();

		// wait 6 seconds
		Thread.sleep(6000);

		// stop motor
		System.out.println("Stopping motor");
		pinE.low();

		gpio.shutdown();
	}
}

首先,我们将数字输出 pinA 映射到 GPIO 引脚 4,将 pinB 映射到 GPIO 引脚 5,将 pinE 映射到 GPIO 引脚 6。 如果您想知道为什么在代码中使用引脚 4、5 和 6,请再次查看上面发布的 Pi4J 映射图。 pinE 名称来自“ pin enable”。

如果 pinE 为高电平,则说明电机已打开。 将 pinE 置于低电平将关闭电机。 我们通过将引脚 A 或 B 之一切换到高电平并将另一个引脚切换到低电平来确定旋转方向。 例如,如果我们将 pinA 设置为高电平并将 pinB 设置为低电平,则电机将顺时针旋转。 交换销钉,电机将以相反的方向旋转。

使用以下命令在 Raspberry 上执行程序

sudo java -classpath .:classes:/opt/pi4j/lib/'*' ControlOneMotorDirection

以下视频演示了结果

https://www.youtube.com/embed/pim_hLJD5IE

添加第二台电机(可选)

使用 L293D,我们可以独立控制 2 个电机的方向,那么为什么不尝试这样做呢? 在电路中添加第二个电机很容易–只需将第二个电机插入面包板,并使用 3 条额外的电缆将 L293D 芯片的另外 3 个引脚连接到 Raspberry Pi。

Raspberry Pi control 2 motors

树莓派控制 2 台电机

这是组装电路的图片– 2 个电机设置

Raspberry Pi circuit with L293D and two DC motors

具有 L293D 和两个直流电机的 Raspberry Pi 电路

Java 程序:控制两个直流电机的方向

我们将我们的第一电机称为motor1,第二个电机称为motor2。 我们为 Raspberry Pi 分配了 3 个 GPIO 引脚,分别是 0、2 和 3。

下面的 Java 程序将两个电机沿一个方向旋转 3 秒钟,然后将第一电机反向旋转 3 秒钟,将第二电机旋转 6 秒钟。

import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.RaspiPin;

/**
 * Controls motor direction of a two DC motors
 * @author https://javatutorial.net
 */
public class ControlTwoMotorsDirection {

	public static void main(String[] args) throws InterruptedException {
		// get a handle to the GPIO controller
		final GpioController gpio = GpioFactory.getInstance();

		final GpioPinDigitalOutput motor1pinA = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_04, "m1A");
		final GpioPinDigitalOutput motor1pinB = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_05, "m1B");
		final GpioPinDigitalOutput motor1pinE = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_06, "m1E");
		final GpioPinDigitalOutput motor2pinA = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_00, "m2A");
		final GpioPinDigitalOutput motor2pinB = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_02, "m2B");
		final GpioPinDigitalOutput motor2pinE = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_03, "m2E");

		System.out.println("rotate both motors clockwise for 3 seconds");
		motor1pinA.high();
		motor1pinB.low();
		motor1pinE.high();
		motor2pinA.high();
		motor2pinB.low();
		motor2pinE.high();

		// wait 3 seconds
		Thread.sleep(3000);

		System.out.println("rotate motor 1 in oposite derection for 3 seconds "
				+ "and motor 2 in oposite direction for 6 seconds");
		motor1pinA.low();
		motor1pinB.high();
		motor2pinA.low();
		motor2pinB.high();

		// wait 3 seconds
		Thread.sleep(3000);
		System.out.println("Stopping motor 1");
		motor1pinE.low();

		// wait 3 seconds
		Thread.sleep(3000);
		System.out.println("Stopping motor 2");
		motor2pinE.low();

		gpio.shutdown();
	}
}

我们在此处使用相同的规则:如果 pinE(启用)为高,则表明电机已打开。 将 pinE 置于低电平将关闭电机。 我们通过将引脚 A 或 B 之一切换到高电平并将另一个引脚切换到低电平来确定旋转方向。

使用以下命令在 Raspberry 上执行程序

sudo java -classpath .:classes:/opt/pi4j/lib/'*' ControlTwoMotorsDirection

以下视频演示了结果

https://www.youtube.com/embed/b7Fx7Q_qfUs

Java 程序:控制两个直流电机的速度和方向

最后,我将向您展示如何控制两个直流电机的速度和方向。 我们将为两个电机设置使用相同的电路。 另外,我们将以编程方式依靠 Soft PWM 来控制电机的速度。 您可以在我的教程中阅读有关 PWM 的更多信息。具有 PWM 和 Java 的 Raspberry Pi 调光 LED

看下面的 java 代码。 注意,电机 1 和 2 的引脚 A 和 B 设置为 Soft PWM 引脚。 对于使能引脚(motor1pinEmotor2pinE),我们使用与先前代码完全相同的定义。

一旦执行,程序将:

  1. 以 15% 的速度顺时针旋转电机 1 2 秒钟
  2. 以 60% 的速度顺时针旋转电机 1 2 秒钟
  3. 以全速将电机 1 顺时针旋转 2 秒
  4. 以 50% 的速度沿相反方向旋转电机 1 3 秒钟
  5. 停止马达 1
  6. 以 30% 的速度顺时针旋转电机 2 2 秒
  7. 以相反的方向将电机 2 全速旋转 3 秒钟
  8. 停止马达 2
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.RaspiPin;
import com.pi4j.wiringpi.SoftPwm;

/**
 * Controls motor speed and direction of two DC motors
 * @author https://javatutorial.net
 */
public class ControlMotorsDirectionAndSpeed {

	private static int MOTOR_1_PIN_A = 4;
	private static int MOTOR_1_PIN_B = 5;
	private static int MOTOR_2_PIN_A = 0;
	private static int MOTOR_2_PIN_B = 2;

	public static void main(String[] args) throws InterruptedException {
		// get a handle to the GPIO controller
		final GpioController gpio = GpioFactory.getInstance();

		// init soft PWM pins
		// softPwmCreate(int pin, int value, int range)
		// the range is set like (min=0 ; max=100)
		SoftPwm.softPwmCreate(MOTOR_1_PIN_A, 0, 100);
		SoftPwm.softPwmCreate(MOTOR_1_PIN_B, 0, 100);
		SoftPwm.softPwmCreate(MOTOR_2_PIN_A, 0, 100);
		SoftPwm.softPwmCreate(MOTOR_2_PIN_B, 0, 100);

		// init GPIO pins
		final GpioPinDigitalOutput motor1pinE = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_06, "m1E");
		final GpioPinDigitalOutput motor2pinE = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_03, "m2E");

		System.out.println("rotate motor 1 clockwise at 15% speed for 2 seconds");
		motor1pinE.high();
		SoftPwm.softPwmWrite(MOTOR_1_PIN_A, 15);

		// wait 2 seconds
		Thread.sleep(2000);

		System.out.println("rotate motor 1 clockwise at 60% speed for 2 seconds");
		SoftPwm.softPwmWrite(MOTOR_1_PIN_A, 60);

		// wait 2 seconds
		Thread.sleep(2000);

		System.out.println("rotate motor 1 clockwise at full speed for 2 seconds");
		SoftPwm.softPwmWrite(MOTOR_1_PIN_A, 100);

		// wait 2 seconds
		Thread.sleep(2000);

		System.out.println("rotate motor 1 in opposite direction at 50% speed for 3 seconds");
		SoftPwm.softPwmWrite(MOTOR_1_PIN_A, 0);
		SoftPwm.softPwmWrite(MOTOR_1_PIN_B, 50);

		// wait 3 seconds
		Thread.sleep(3000);

		// disable motor 1
		SoftPwm.softPwmWrite(MOTOR_1_PIN_B, 0);
		motor1pinE.low();

		System.out.println("rotate motor 2 clockwise at 30% speed for 2 seconds");
		motor2pinE.high();
		SoftPwm.softPwmWrite(MOTOR_2_PIN_A, 30);

		// wait 2 seconds
		Thread.sleep(2000);

		System.out.println("rotate motor 2 in opposite direction at 100% speed for 3 seconds");
		SoftPwm.softPwmWrite(MOTOR_2_PIN_A, 0);
		SoftPwm.softPwmWrite(MOTOR_2_PIN_B, 100);

		// wait 3 seconds
		Thread.sleep(3000);

		// disable motor 2
		SoftPwm.softPwmWrite(MOTOR_2_PIN_B, 0);
		motor2pinE.low();

		gpio.shutdown();
	}
}

使用以下命令在 Raspberry 上执行程序

sudo java -classpath .:classes:/opt/pi4j/lib/'*' ControlMotorsDirectionAndSpeed

运行程序时,您应该看到此控制台输出

Program console output

程序控制台输出

以下视频演示了结果

https://www.youtube.com/embed/Jfuu-h_NYY0

结论

你还在读这个吗? 谢谢! 这是一个很长的教程🙂现在,在您知道如何使用 Raspberry Pi 控制电机之后,也许您可​​以考虑构建一些很酷的项目甚至是一个小型机器人并与我们分享结果🙂

与往常一样,我喜欢阅读您的评论并回答您的问题。 如果您喜欢本教程或其他教程,请传播!

您可以在 GitHub 中找到所有项目文件: https://github.com/JavaTutorialNetwork/Tutorials/tree/master/RaspberryPiControlMotors

资料来源:

使用 Pi 和 Python 控制直流电机

posted @ 2024-11-01 16:29  绝不原创的飞龙  阅读(8)  评论(0编辑  收藏  举报