JavaTutorialNetwork-中文系列教程-二-
JavaTutorialNetwork 中文系列教程(二)
如何在 Java 中使用 MySQL 连接器
https://javatutorial.net/how-to-use-the-mysql-connector-in-java
在通过 Java 程序测试 MySQL 连接之前,我们需要将 MySQL JDBC 库添加到类路径中。 我们将需要从下载页面下载mysql-connector-java-*.jar
文件:
现在,根据您的工作环境(例如 Eclipse 或命令行),您将必须执行以下任一操作:
- 如果使用 Eclipse IDE,请将 JAR 文件作为库添加到项目属性中的“构建路径”。
- 如果使用命令控制台,请在执行应用程序时在
-cp
或-classpath
参数中指定 JAR 文件的路径。
命令行执行的示例如下所示:
java -cp .;/xxx/xxx/xxx/mysql-connector-java-*.jar com.nameapp.ClassName
现在我们已经澄清了这一点,让我们从 Java 类连接到 MySQL 数据库。
在 Eclipse 中创建项目,然后右键单击项目名称并选择“属性”。 之后,转到“Java 构建路径”并通过单击“添加外部 JAR ..”添加.jar
文件。 您可以查看以下图像以显示步骤:
(1)
(2)
做完了 现在我们添加了 JAR 文件,是时候创建我们的 MySQL 数据库了。 我假设您已经下载了 MySQL 工作台。 如果不是,请从此处下载。
要创建数据库,只需键入
create database demoapp;
然后,要验证确实已创建数据库,请键入
show databases;
您应该看到类似以下的内容:
如您所见,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());
}
}
}
输出:
现在忽略警告。
细分
我们将本地主机的 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
文件。 出现以下屏幕
步骤 1:运行.exe
文件
单击“下一步”,然后选择已选中的 Android SDK(如果尚未安装)。 更好的是保留默认设置。
确保还检查了 Android 虚拟设备。
步骤 2:选择组件
下一步是接受许可和协议。 点击“我同意”
步骤 3:接受许可
下一步是设置安装位置。 在单击“下一步”之前,请确保磁盘具有最小的所需空间。 对于 Android Studio,安装位置必须至少有 500MB 可用空间。 要安装 Android SDK,所选位置必须至少具有 3.25GB 的可用空间。
步骤 4:安装位置
下一步是选择要在其中创建快捷方式的开始菜单文件夹。 如果您不想创建快捷方式,只需标记,不要创建快捷方式。
步骤 5:选择开始菜单文件夹
然后点击“安装”按钮。
它将开始安装。 完成后,将出现以下窗口。
步骤 6:完成
这将通知您安装已完成。 单击“完成”。 确保已选中“启动 Android Studio”。 将出现以下 Android Studio 的初始屏幕。
步骤 7:Android Studio 启动画面
步骤 3)配置 Android Studio
首次运行时,系统会要求您提供 Android Studio 设置。
步骤 8:导入设置
如果您之前没有任何设置,请点击第二个选项(我没有 Studio 的早期版本,或者我不想导入设置)。
选择一个主题,然后单击下一步。
步骤 9:选择主题
在第一次运行时,它需要下载一些必要的组件,直到完成。
步骤 10:下载组件
一切都完成了。
步骤 11:完成
点击“完成”并开始构建您的 Android 应用。
Android Studio 用户界面简介
Android Studio 是一个集成开发环境(IDE)。 您已经在本教程中看到了下载和安装。 让我们学习一些 Android Studio 的基础知识。 这是一个正在运行的 Android Studio 的屏幕截图。
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 次之后将显示“您现在是开发人员”。
步骤 1:USB 调试
- 您会注意到“开发人员的选项”现在可用。
步骤 2:USB 调试
- 转到“开发人员选项”并启用“USB 调试”
步骤 3:USB 调试
单击“确定”。
步骤 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 屏幕
将出现一个窗口“Select Deployment Target”,并出现可用设备的列表。 选择您的设备,然后单击“OK”。 Android Studio 将在您的 Android 设备上运行您的应用程序。
部署目标
如果您想保存此设置供以后的应用程序,请单击“将相同的选择用于以后的启动”。
参考文献
适用于 Windows 的 Samsung 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 意图
意图有两个基本组成部分
数据:要传送的数据。
操作:要执行的操作。
有两种主要类型的意图,显式意图和隐式意图。
<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 布局
线性布局:将组件组织成单个水平或垂直行。 完整示例可在这里找到
相对布局:它指定组件相对于彼此的位置。 完整示例可在这里找到
Web 视图:用于网页。 完整示例可在这里找到
创建一个简单的 Android 应用
本教程介绍了如何在 Android Studio 中创建简单的 Android 应用。
在 Android Studio 中创建应用非常容易。 在开始实际编程之前,请确保已正确设置环境和 Android SDK 路径。 您可以按照本教程中的步骤进行操作。 让我们从头开始。
创建 Android 项目
创建一个新项目。
- 转到“文件菜单 => 新建”,然后选择“新建项目”。
- 输入应用程序名称,然后选择项目的位置。单击,然后单击。(应用程序名称将在您的应用程序中显示为顶部横幅)。
步骤 1:新应用
- 为您的项目选择“目标设备”,然后单击“Next”。
第 2 步:定位 Android 设备
- 然后为您的项目选择一个活动。 因为这是基本教程,所以我选择一个空的活动。
步骤 3:添加活动
- 下一步是命名活动和活动的布局。 (活动是 java 类,您将在其中进行所有编码,而布局是 xml 格式的设计)。
步骤 4:自订活动
- 单击“完成”。
- 这是一个空的活动的样子
项目画面
项目的层次结构
首先,探索您应用的层次结构
项目层次结构
xml
:它定义应用程序的属性。layout
:布局文件夹包含所有布局文件,用于设计应用程序的形状和外观。values
:此文件夹包含其他 xml 文件,例如strings.xml
,styles.xml
和colors.xml
。 这些资源文件对于项目的代码和样式很有用。Java
:此文件夹包含所有 Java 类。gradle
:它包含SDKversion
,applicationId
和BuilToolVersion
。
现在开始编码。
创建界面
打开布局文件,然后单击“设计”视图。
从面板窗口中将文本视图拖到屏幕上。 单击Textview
,然后可以在属性窗口中更改其属性,如字体大小,字体颜色。
同样,也拖动文本字段和按钮并将其排列。 设置其属性,使屏幕如下所示。
设计画面
在单击按钮后出现另一个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");
}
});
}
}
以下是屏幕快照的工作原理。
应用画面
当用户单击“确定”按钮时,将执行动作监听器,并说“欢迎”。
应用画面
阅读本教程,立即开始制作您的第一个应用程序。 您可以从链接下载完整的项目。
运行和调试 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 应用)。 这是结果
- 我的设备显示在部署目标窗口中。 选择它并运行。
选择部署目标
它将开始在您的设备中安装您的应用程序。 在这里安装后,它会创建快捷方式。
应用程式捷径
在 Android 设备上运行的应用
在 Android 设备上运行的应用
调试 Android 应用程序
调试是发现错误的过程。AndroidStudio 还提供了一种机制,可以调试在虚拟 Android 设备或硬件 Android 设备上运行的应用。 Android 调试器提供以下功能。
- 选择设备来调试您的应用
- 在代码中设置断点
- 在运行时检查表达式流。
- 允许捕获屏幕截图和视频
在开始调试之前,请确保该构建变量将debuggable
属性设置为true
。
为此,转到“构建 => 选择构建变量”。 要开始调试,请单击菜单栏上的“调试”图标。 在 Android 设备上构建并安装后,它将打开调试窗口。
- 选择屏幕菜单上的调试图标。
- 在“部署目标”窗口中选择您的设备。
- 然后选择要附加到调试器的进程。
选择进程
- 单击“确定”。
- 您将看到调试窗口,控制台将显示已连接到设备。
控制台消息
下图显示了调试器窗口,其中显示了当前线程。
调试器窗口
单击“终止”以终止调试会话。
在虚拟设备上运行 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 中打开您的项目(如果没有该项目,则可以按照本教程的进行创建)
- 单击菜单栏中的“运行”图标,或右键单击项目的根目录,然后单击“运行”。
- 将出现一个新窗口,用于选择部署目标(如果您是第一次使用,可能会遇到一个错误,提示某些必需的文件丢失了,您可以通过单击“下载”按钮进行下载)。
选择部署目标
- 它显示了可用虚拟设备的列表。 您可以选择任何人。
- 如果要使用此部署目标,请始终仅单击“对以后的启动使用相同的选择”。
- 点击“确定”
- 如果看不到任何必需的虚拟设备,则可以为您创建一个。
- 在菜单栏中选择“AVD 管理器”。
创建虚拟设备
- 单击“创建虚拟设备”
- 从列表中选择硬件,然后单击“下一步”
选择硬件
- 选择“系统映像”(选择推荐的一个),然后单击“下一步”
系统映像
- 验证配置,然后单击“完成”
验证配置
- 现在,单击“运行”,然后选择新创建的虚拟设备作为目标设备。
- 仿真器将以以下方式启动
加载模拟器
- APK 文件将被安装。
仿真器
- 它将以
在模拟器上的应用
Android Studio 还允许我们自定义您的模拟器。 您可以在仿真器右侧看到一个垂直菜单栏。 这用于自定义您的应用,例如更改方向,音量设置,拍照等。 因此,您可以使用 Android 虚拟设备轻松,快速地运行,调试应用。
Android 活动示例
本教程介绍了什么是 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 活动生命周期
图中的矩形代表 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 意图示例
本教程通过示例说明了 Android 的意图,类型和方法。
Android 意图
意图是用于向另一个组件请求操作的对象。 目的是一种数据结构,其中包含要执行的操作的抽象描述。 它用于从其他 Android 组件请求功能。 简而言之,意图是做某事的意图。 通过使用意图,我们可以做很多事情,例如从一个活动转到另一个活动,通过相机应用程序拍照,网络搜索,在地图上搜索位置等等。 这使开发人员可以轻松地重新混合不同的应用程序。
意图类型
有两种类型的意图,显式和隐式意图。
显式意图
在显式意图中,目标组件名称在创建意图时直接传递到意图中。 当一个活动调用另一个活动时,通常使用显式意图。 例如,我们有两个活动 - 登录活动和主页活动,登录应用程序将用户带到主页后,请参见下图。
显式意图
这是在登录活动中应如何调用的代码。
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 联系人
目标方法
有用于向活动,服务和广播接收者传达意图的单独机制。 这是几种方法的解释
Context.startActivity()
:此方法用于启动新活动,目的是作为参数传递的。
Context.startService()
:此方法用于启动新服务,目的对象作为参数传递。
Context.sendBroadcast()
:此方法用于将消息发送到任何广播接收器。 意图对象作为参数传递。
意图对象有两个主要组成部分。
动作:显示要执行的动作。 它是意图对象的必修部分。 要执行的动作可以是ACTION_VIEW
,ACTION_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);
}
});
}
}
这是它的样子
意图示例
选择浏览器
Java 教程
您可以从链接下载此代码。
Android 服务示例
本教程介绍了 Android 中的服务及其生命周期,并提供了有关如何创建服务的示例。
Android 服务与 Android 活动有很大不同。 这是 Android 应用程序开发的概念。 让我们讨论一下。
Android 服务
服务用于实现或执行在我们的应用中运行的后台操作。 它是一个应用程序组件,用于执行长时间运行的重要后台任务,例如播放音乐,下载文件或执行网络事务。 由于服务在后台运行,因此与活动不同,它没有任何用户界面。 它使我们能够在应用程序中启用多任务处理。 尽管应用程序已关闭或服务已完成工作或已明确停止,但服务仍在后台继续运行。 因此,它比不活动的应用程序具有更高的优先级。 您还可以将其设置为与正在运行的前台任务相同的优先级。 让我们讨论一下服务类型。
Android 服务的类型
Android 中提供三种不同类型的服务。
调度:在诸如jobScheduler
之类的 API 中计划了一项服务,然后将其称为计划服务。 系统检查jobScheduler
并在适当的时间执行服务。
启动:如果服务可以由应用程序组件启动,则将其称为已启动服务。 活动调用startService(0
方法,然后在后台运行。 通常,此服务执行单个操作。
绑定:如果应用程序组件将服务绑定到bindService()
,则称为绑定。 它具有一个客户端服务器接口,该接口允许组件与服务进行交互。
Android 服务的生命周期
Android 服务生命周期与 Android 活动完全不同。 如果使用startService()
创建服务或使用bindService()
创建服务,则其生命周期可能会有所不同。 下图显示了两个生命周期。
服务生命周期
让我们讨论服务生命周期的回调方法。 当使用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 服务
服务
您可以从此链接下载代码。
Android 线性布局示例
在先前的教程中,您了解了 Android 意图,服务和活动。 本教程和接下来的几本教程将介绍有关 Android 中不同布局的信息。
布局是事物以特定方式进行排列的方式。 Android 还提供了不同的布局,以不同的方式排列不同的组件。 其中一些是线性布局,相对布局,Web 视图布局等。布局对于 UI 应用程序的开发非常重要。 本教程的主要重点是线性布局。
线性布局
Android 中的线性布局使我们可以将组件水平排列在单列中或垂直排列在单行中。 垂直或水平方向取决于属性android:orientation
。线性布局简单易用,如果窗口的长度超过屏幕的长度,则会创建滚动条。 垂直线性布局每行只有一项。 线性布局具有许多不同的属性,可用于根据需要自定义线性布局。 下图显示了水平和垂直线性布局。
线性布局
线性布局的属性
以下是 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>
这是输出的样子
垂直线性布局
这是另一个显示水平线性布局的示例。 以下是activity_linear_horizontal.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>
这是输出的样子
水平线性布局
您可以从链接下载示例代码。 有关更多 Android 布局,请遵循以下教程。
Android 相对布局示例
原文: https://javatutorial.net/android-relative-layout-example
本教程通过示例说明了 Android 中的相对布局。
Android 中的布局对于基于 GUI 的应用程序非常重要。 在上一教程中,我们学习了线性布局,本教程介绍了 Android 中的相对布局。
相对布局
顾名思义,相对布局显示组件之间的相对位置。 可以相对于连续元素或父组件来指定位置。 相对布局是 Android 提供的最灵活的布局。 它使您可以在屏幕上放置元素。 默认情况下,它将所有组件设置在布局的左上方。 下图显示了相对布局的外观,
相对布局
相对布局属性
以下是相对布局的属性。
Id
:定义布局 IDGravity
*它指定对象在 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()
:它将子视图的重力设置为居中,向左或向右。setHorizontalGravity()
:用于水平定位元素。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>
这是输出的样子
相对布局示例
您可以从链接下载源代码。
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 视图示例
您可以通过单击链接下载此代码。
Android 列表视图示例
您已经学习了 Android 的许多其他布局,本教程通过示例说明了 android 中的列表视图。
ListView
您要在应用中显示列表吗? Android 通过提供列表视图布局来解决其问题。 它是一种布局,在垂直可滚动列表中显示项目。 列表中的每个项目都位于列表中上一个项目的下方。 列表项存储在数组中,并由使用适配器从列表中拉出项目,然后将其插入列表。 列表视图是AdapterView
的子类。 自定义列表在移动应用程序中非常常见,列表视图提供了一种创建自定义列表的简便方法。 它是最常用的布局之一,例如,当您要显示一组日期时,没有什么比列表更合适的了。 下图显示了列表视图的外观
列表显示
列表视图的属性
这是列表视图的一些重要 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);
}
}
这是输出的样子
列表视图示例
您可以通过以下链接下载此示例代码。
Android 网格视图示例
Android 网格视图是许多应用程序中最常用的布局之一。 本教程通过示例说明了网格视图的布局。
GridView
网格视图是 android 中的布局,可让您将组件排列在二维可滚动网格中。GirdView
中的组件不一定是静态的,它可以存储在ListAdapter
中(适配器就像数据和 UI 组件之间的桥梁)。 下图显示了 android 中GridView
的示例。
Android GridView
网格视图在计算器,日历等许多应用程序中非常常见。
网格视图的属性
以下是 Android 网格视图布局的一些 XML 属性。
android:gravity
,代表每个单元格(如中心,底部,顶部,左侧等)中的重力。android:columnWidth
,用于指定每个单元格的列宽。android:horizontalSpacing
,指定网格列之间的水平空间。android:verticalSpacing
,用于指定网格行之间的垂直空间。android:numColumns
,指定要显示的列数。
网格视图的方法
网格视图有多种使用方法,其中一些在此处说明
getAccessibilityClassName()
:返回对象的类名称。getAdapter()
:返回与其关联的适配器。getColumnWidth()
:返回网格上列的宽度。getGravity()
:返回网格组件的重力,即它们如何水平对齐。getHorizontalSpacing()
:返回网格组件之间的水平间距。getNumColumns()
:获取网格中的列数。setAdapter(ListAdapter adapter)
:用于在网格视图后面设置数据。setColumnWidth(int columnWidth)
:用于设置列宽。setGravity(in gravity)
:用于设置网格组件的重力。setHorizontalSpacing(int horizontalSpacing)
:用于设置水平间距以将项目放置在网格中。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();
}
});
}
}
这是输出的样子
网格视图示例
您可以通过单击链接下载此代码。
带有ListAdapter
的 Android ListView
示例
原文: https://javatutorial.net/android-listview-with-listadapter-example
在上一个教程中,我们通过一个简单的示例了解了列表视图布局。 本教程介绍了用于创建自定义列表的列表适配器。
Android ListAdapter
列表视图非常简单,您要自定义列表吗?ListAdapter
用于自定义列表视图的布局。 它的行为就像是数据源和列表视图之间的桥梁。 它的父类是BaseAdapter
。 当您要为列表中的各个行指定布局时使用。 不要将其与ArrayAdapter
混淆,ListAdapter
是一个接口,而ArrayAdapter
是可处理数据数组的类。 下图显示了使用ListAdapter
的自定义列表视图。
列表适配器
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>
运行您的应用程序,这里是输出
列表适配器示例
您可以通过单击链接下载此代码。
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 和密码。 当用户单击“确定”按钮时,这些值将保存到数据库中。 下图显示了数据库中的注册表的外观
登录表
第 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();
}
}
现在运行您的应用程序并进行测试。 这是正在运行的应用程序的屏幕截图
登入
错误的 ID 或密码
注册
您可以从链接下载此代码。
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
,则图像将显示幻灯片动画。 现在运行它,这是输出
动画示例
这是它闪烁时的输出
闪烁动画
您可以通过单击链接下载本教程。
资源
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());
}
}
现在运行您的应用,这是输出
通知示例
单击“通知”按钮后,新的通知将出现在状态栏中。 这是它的样子
新通知
您可以通过单击链接下载此项目。
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++;
}
});
}
}
在这里运行您的应用程序,输出结果看起来像
事件处理
单击按钮后,文本颜色将更改
事件处理颜色变化
事件处理示例
事件处理:洋红色
事件处理:蓝色
您可以通过单击链接下载此代码。
如何在 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);
}
}
运行您的应用,这是输出
带附件的电子邮件示例
点击“添加附件”
添加附件
现在点击“发送”按钮
发电子邮件
您可以通过单击链接下载此项目。
参考文献
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 是因为它易于使用和开放源代码平台。 与新手一起工作可能会有点麻烦,但是稳定地使用它会成为一种很棒的经验。
NetBeans
NetBeans 最初是 Sun 系统的一部分,现在已经落入 Oracle 的掌控之中。 它是一个免费的开源 IDE 平台。 该 IDE 用于为所有版本的 JAVA 开发软件。 它还支持您可以使用的各种插件。
该平台可作为开发 JAVA swing 桌面应用程序的框架。 使用插件和基于平台的应用程序进行开发的 JAVA SE 中的 NetBeans IDE 不需要其他 SDK。
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
最近,它发布了版本 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 示例
在本教程中,我将解释如何通过 Amazon 提供的 Java API 使用 Amazon 的 S3 存储。 该示例说明了如何创建存储分区,列出存储分区的内容,在存储分区中创建文件夹,上传文件,为文件提供公共访问权限以及如何删除所有这些项目。
设置项目
-
您将需要适用于 Java 的 AWS 开发工具包,此示例才能正常工作。 如果您现在尚未下载 SDK,请在此处下载。 您还需要将存档中的
.JAR
文件集成到您的项目中。 或者,您可以使用具有以下依赖项的 Maven<dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk</artifactId> <version>1.9.2</version> </dependency>
-
如果您没有,请在 Amazon IAM(https://console.aws.amazon.com/iam)中创建一个用户。 在这里您将获得一个“访问密钥”和“秘密访问密钥”。 您将需要此凭据才能连接到 S3。
-
将 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_ID
和AWS_SECRET_ACCESS_KEY
3. Java 系统属性 – aws.accessKeyId
和aws.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
更改 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 使用片段来执行诸如以下操作:
- 覆盖 Liferay OOTB 模块的 JSP
- 覆盖语言属性
- 用 Servlet 过滤器覆盖 HTTP 请求
- 覆盖 Liferay Struts 动作
- 替代 Liferay 模态监听器
- 覆盖 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 实体,例如User
,Group
,DLFileEntry
等,以执行onAfterUpdate
或onBeforeUpdate
之类的操作。 我们可以使用BaseModelListener<T>
类覆盖这些方法。
在这里,我们将覆盖 Liferay User
的onAfterUpdate
方法,该方法将在更新任何用户时执行。
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<User>
并覆盖了onAfterUpdate
方法,在这里我们可以编写自定义逻辑。 我们需要在@Component
中将服务属性值定义为ModelListener.class
。
自定义 Liferay DXP 开放源代码以开发高度可扩展的现代应用程序具有极大的可能性。 程序员发现 Lifera 7 非常有趣,因为它使编码成为基于创意和逻辑思考的过程。 结果, Liferay DXP 开发在开发人员和行业中都越来越受欢迎。
作者简介:
Sandip Patel 是一名技术爱好者,并且是拥有 7 年以上经验的 Liferay & MongoDB 认证专家。 他正在与 Azilen Technologies 合作,并且喜欢随时了解最新的 Liferay 技术和创新。
简单的 Git 教程
在本教程中,您将学习非常基本的 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 工作流程
工作目录 –它包含实际文件
索引 –是标记代码更改的登台区域
HEAD
–保存您所做的最后一次提交
远程服务器 –是代码所在的最终目的地,因此您的更改可供其他开发人员使用
检出 Git 存储库
要制作现有存储库的工作本地副本,请执行以下操作:
git clone {path_to_repository}
这将在当前目录中下载存储库的副本。
例如,如果要克隆托管在 GitHub 中的存储库,请运行以下命令:
git clone https://github.com/JavaTutorialNetwork/Tutorials.git
在 GitHub 中,您可以在此处找到存储库路径:
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 捕获网络数据包
该示例演示了如何使用 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 教程
本教程将说明如何使用 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
。
-
下载 Java 2.xx zip 文件
-
将
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 浏览器。
-
Selenium 将打开一个单独的 Firefox 窗口并转到 https://javatutorial.net
-
查看此页面顶部的搜索按钮(放大镜),是 - 当前正在阅读的页面顶部 🙂 Selenium 将光标移至该位置以显示搜索字段
-
它将输入搜索词“java”并提交表格
-
等待 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 属性对话框
例如,如果要使用 TestWorkspace 启动 Eclipse,请在“目标”字段中输入以下内容:
D:\Development\eclipse\eclipse.exe -data D:\Development\TestWorkspace
在 Eclipse 中安装 SVN
默认情况下,Eclipse 不支持 SVN 存储库浏览。 幸运的是,有几个插件使之成为可能。
在本教程中,我将向您展示如何安装 Tigris 的 Subclipse 插件。 这简单!
1. 启动 Eclipse
2. 转到“帮助 -> 安装新软件”
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
4. 按下[Enter]
键,不久您将看到要安装的组件列表。 选择第一个和第三个,然后单击“下一步”按钮(我在具有 JNA 库的 64 位计算机上遇到了一些问题,这就是为什么我不安装它)
5. 在下一个屏幕上,再次单击“下一步”,同意许可协议,然后单击“完成”按钮
6. 等待一段时间,直到下载并安装了软件包。 您将需要重新启动 Eclipse 才能使更改生效。
7. 单击 Eclipse 右上角的“打开透视图”按钮
...并在此窗口中选择“SVN 存储库浏览”
8. 右键单击“SVN 存储库”视图,然后选择“新建 -> 存储库位置…”。
9. 在下一个窗口中,输入要浏览/使用的 SVN 存储库 URL
如何运行 NodeJS 服务器
在此页面上,我将向您展示如何设置和运行 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 测试页
如果您喜欢本教程,请分享并发表评论。
SQL 内连接示例
本文介绍了 SQL INNER JOIN
语法,并提供了有关如何使用INNER JOIN
的示例
最常用的连接是INNER JOIN
。 它通过组合两个或多个表的列值来创建新的结果表。
您可以使用以下链接查看不同类型的 SQL 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 个表
CUSTOMER
PRODUCT
ORDER
客户可以订购产品。 在ORDER
表中,我们保存了客户 ID 和客户已订购的每种产品的数量。
数据库图显示客户,产品和订单关系
使用以下 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');
数据库表
现在这就是我们表中的内容:
客户表
产品表
订单表
内连接表
现在,让我们使用INNER JOIN
连接这些表
该查询返回客户详细信息,购买日期和数量
SELECT C.id, C.name, O.date, O.quantity
FROM `CUSTOMER` C
INNER JOIN `ORDER` O
ON C.id = O.customer_id;
内连接结果集
连接多个表
下一个示例显示如何将 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;
查询执行的结果:
连接多个表
免责声明:上面显示的示例已经在 MySQL 上进行了测试。 根据您的 SQL 数据库,CREATE TABLE
语法可能有所不同。
SQL 左连接示例
本文介绍了 SQL LEFT JOIN
语法,并提供了有关如何使用LEFT JOIN
的示例
左连接返回左表中的所有值,以及右表中的匹配值。 如果右表中没有与左表中给定记录匹配的结果,则结果值将返回为 NULL。
左连接和左外部连接在术语方面相同。
您可以使用以下链接查看不同类型的 SQL 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 个表
CUSTOMER
PRODUCT
ORDER
客户可以订购产品。 在ORDER
表中,我们保存了客户 ID 和客户已订购的每种产品的数量。
数据库图显示客户,产品和订单关系
使用以下 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');
数据库表
现在这就是我们表中的内容:
客户表
产品表
订单表
左连接表
现在,让我们使用LEFT JOIN
连接这些表
该查询返回客户详细信息和购买日期
SELECT `CUSTOMER`.id, `CUSTOMER`.name, `ORDER`.date
FROM `CUSTOMER`
LEFT JOIN `ORDER`
ON `CUSTOMER`.id = `ORDER`.customer_id;
左连接结果集
免责声明:上面显示的示例已经在 MySQL 上进行了测试。 根据您的 SQL 数据库,CREATE TABLE
语法可能有所不同。
SQL 右连接示例
本文介绍了 SQL RIGHT JOIN
语法,并提供了有关如何使用RIGHT JOIN
的示例
右连接返回右表中的所有值,以及左表中的匹配值。 如果左表中没有与右表中给定记录匹配的结果,则返回的结果将为NULL
。
RIGHT JOIN
和RIGHT OUTER JOIN
的术语相同。
您可以使用以下链接查看不同类型的 SQL 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 个表
CUSTOMER
PRODUCT
ORDER
客户可以订购产品。 在ORDER
表中,我们保存了客户 ID 和客户已订购的每种产品的数量。
数据库图显示客户,产品和订单关系
使用以下 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');
数据库表
现在这就是我们表中的内容:
客户表
产品表
订单表
右连接表
现在,让我们使用RIGHT JOIN
连接这些表
该查询返回客户详细信息和购买日期
SELECT `CUSTOMER`.id, `CUSTOMER`.name, `ORDER`.date
FROM `CUSTOMER`
RIGHT JOIN `ORDER`
ON `CUSTOMER`.id = `ORDER`.customer_id;
右连接结果集
免责声明:上面显示的示例已经在 MySQL 上进行了测试。 根据您的 SQL 数据库,CREATE TABLE
语法可能有所不同。
SQL 外连接示例
本文介绍了 SQL OUTER JOIN
语法,并提供了有关如何使用OUTER JOIN
的示例
外连接连接表将包含两个表(A 和 B)中的所有记录,并为任何缺少的匹配项填充 NULL。
在术语方面,外连接和完全连接是相同的。
您可以使用以下链接查看不同类型的 SQL JOIN
:
外连接视觉表示
SQL 外连接
外连接语法
该查询将返回两个表中所有记录的合并结果
SELECT Table_A.column1, Table_B.column2...
FROM Table_A A
FULL JOIN Table_B B
ON A.Key = B.Key
外连接示例
我们将创建 3 个表
CUSTOMER
PRODUCT
ORDER
客户可以订购产品。 在ORDER
表中,我们保存了客户 ID 和客户已订购的每种产品的数量。
数据库图显示客户,产品和订单关系
使用以下 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');
数据库表
现在这就是我们表中的内容:
客户表
产品表
订单表
外连接表
现在,让我们使用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;
外连接结果集
免责声明:上面显示的示例已经在 MySQL 上进行了测试。 根据您的 SQL 数据库,CREATE TABLE
语法可能有所不同。
树莓派
Raspberry Pi 3 规格
对所有 Raspberry Pi 迷来说都是好消息 – Raspberry Pi 3 Model B 现在正式发售
Raspberry Pi 3 模型 B
Raspberry Pi 2 发行一年后,以及最初的 Raspberry Pi Model B 首次发行后正好四年,自 2016 年 2 月 29 日以来,现已正式发售最畅销的信用卡大小的第三代计算机。
四年来,Raspberry Pi 开始了一场革命。 全世界的人们都在用小型木板建造无数的项目,例如机器人,自动宠物喂食器,比特币农场,海盗无线电发射器等等。 有了这个板,“您的想象力是唯一的极限”一词成真了。 根据制造商的说法,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 端口
去哪买?
由于需求量大,目前大多数零售商缺货。 但是,您可能会遇到一些运气,并在接下来的几天内实现交付。
这是零售商列表。 如果您找到其他来源,请在以下评论中添加它们:
将 Raspbian 安装到 SD 卡
本教程将向您展示如何将 Raspbian OS 安装到 SD 卡
前提条件
现在,您将需要一台内置 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 卡
-
下载 Win32DiskImager 实用程序并安装它
-
以管理员身份运行程序
-
浏览您最近下载的
.img
文件 -
在设备–下拉列表中选择 SD 卡的名称
-
按“写入”按钮
使用 Mac OS 将 Raspian 映像安装到 SD 卡
-
从 Apple 菜单中,选择“关于本机”,然后单击“系统报告”。
-
单击读卡器,然后在窗口右上方搜索您的 SD 卡。 单击它,然后在右下方搜索 BSD 名称; 它看起来像
diskn
,其中n
是一个数字(例如disk2
)。 确保记下这个数字 -
打开磁盘工具并卸载 SD 卡。 不要弹出
-
打开终端并运行:
sudo dd bs=1m if=path_of_your_image.img of=/dev/diskn
不要忘记将第 2 步中的磁盘名称替换为 diskn
-
在将映像内容移至 SD 卡之前,请耐心等待,具体取决于您的硬件,此过程可能需要 20 分钟或更长时间
在我的下一个教程“Raspberry 首次启动” 中,我将说明如何插入电缆并首次启动 Raspberry。
Raspberry Pi 首次启动
本教程介绍了如何为首次启动准备 Raspberry Pi,如何连接外围设备并首次启动 Raspbian。
你需要什么
1. USB 鼠标
2. USB 键盘
3. 局域网电缆
4. HDMI 线
5. HDMI 监视器或电视
6. 已安装 Raspbian 的 SD 卡(有关详细信息,请阅读本教程)
7. 微型 USB 电源适配器。 您可以使用手机电源适配器执行此操作,也可以使用 USB 转 micro USB 电缆连接到计算机。 但是,某些计算机 USB 希望为您的 Raspberry 提供足够的电源。
连接电缆并开始
-
根据上图连接鼠标和键盘
-
使用局域网电缆将 Raspberry 连接到路由器
-
插入装有 Raspbian 映像的 SD 卡(请阅读本教程,以了解如何在 SD 卡上安装 Raspbian)
-
使用 HDMI 电缆将 Raspberry 连接到显示器或电视
-
将电源连接到 Raspberry micro USB 端口。 当给树莓供电时,它会自动启动。 您可以拔下电缆以将其关闭。
树莓首次启动
首次使用 Raspbian OS 启动 Raspberry 时,将看到以下屏幕
注意:如果第一次启动时未显示该屏幕,则可以使用以下命令进行调用:
sudo raspi-config
我在这里要做的是按键盘上的Enter
键,并选择选项 1 – 扩展文件系统。 展开完成后,您可能需要浏览其他选项,例如更改 root 密码等。
完成后,使用键盘上的Tab
键转到<Finish>
,然后按Enter
。
操作系统将重新启动,几秒钟后,您将看到登录提示
默认的 Raspbian 用户是:pi
密码为:raspberry
好的! 如果需要,现在可以通过键入以下内容来启动图形界面 GUI:
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 服务器。 可以启用:
从桌面手动
- 从
Preferences
菜单启动Raspberry Pi Configuration
- 转到
Interfaces
标签 - 选择
SSH
旁边的Enabled
- 点击
OK
或者,可以使用raspi-config
- 在终端窗口中输入
sudo raspi-config
- 选择
Interfacing Options
- 导航并选择
SSH
- 选择
Yes
- 选择
Ok
- 选择
Finish
用于无头设置
可以通过将名为ssh
的文件(没有任何扩展名)放置在 SD 卡的启动分区上来启用 SSH。 Pi 启动时,它会寻找ssh
文件。 如果找到,则启用 SSH,并删除该文件。 文件的内容无关紧要:它可以包含文本,也可以完全不包含任何文本。
与电脑连接
PuTTY 是 Windows 的免费 SSH 客户端。 从官方页面下载可执行文件(putty.exe
)。
启动 PuTTY。 在“主机名(或 IP 地址)”下输入 Raspberry 的 IP,并将端口保留为 22。现在按“打开”按钮。
在下一个屏幕中,输入您的用户名和密码。
默认的 Raspbian 用户是:pi
密码为:raspberry
好的! 现在您已连接,您可以执行所需的任何 linux 命令。
注意:我建议从路由器为 Raspberry 分配一个静态 IP。 这样,您无需在路由器每次为其分配新 IP 时检查 Raspberry 的 IP。
在 PC 和 Raspberry Pi 之间传输文件
我想向您展示的另一个有用的工具是 WinSCP。 这是一个安全的 FTP 客户端,使您能够从 Raspberry Pi 传输文件或将文件传输到 Raspberry Pi。
您可以从官方项目网站下载 WinSCP。
下载并安装后,输入 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)我们需要控制的计算机的 VNC 服务器,以及(2)我们将要控制的小工具上的 VNC Viewer。
- Raspberry Pi 存储设备(例如 Micro-SD )
- 树莓派板
- 电脑
幸运的是,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)直接连接
如果您使用的是家庭网络,则可以直接建立直接连接。 这是采取的步骤:
-
- 在 Raspberry Pi 终端上,运行以下命令:
hostname -I
终端将显示 IP 地址(专用)。 保存以备后用!
- 现在,转到用于命令 Raspberry Pi 的设备并在其上安装 VNC Viewer。在此处下载您的 VNC Viewer。
- 接下来,输入 VNC Viewer 的 IP 地址(专用)(上面刚刚保存的 IP 地址)
- 最后,VNC Server 将要求您使用 Raspberry Pi 的凭据(用户名&密码)进行身份验证。 如果您尚未更改 Pi 的登录凭据,则为“ pi” &“树莓”。
(ii)建立云连接
RealVNC 将允许您注册和使用免费帐户用于非商业目的或用于教育目的。
值得注意的是,云连接是安全的,不需要配置路由器端口转发,甚至不需要知道 Raspberry Pi 的 IP。
但是,云连接不适合家庭网络连接,并且可能比直接连接慢。 建立云端连线的方法如下:
- 在此处创建一个 RealVNC。
- 使用 RealVNC 帐户登录 Raspberry Pi 上的 VNC 服务器。
- 接下来,将出现一个屏幕,我们需要从“选择连接方式”选项中选择“直接&云连接”。
- 现在,下载您的 VNC Viewer 并将其安装在用于命令 Raspberry Pi 的小工具上。
- 使用 RealVNC 帐户登录 VNC 查看器。 单击 Raspberry Pi 图标。
- 使用用户名&密码对 Raspberry Pi 进行身份验证(如果适用,请使用默认设置)。
如果目前为止一切正确,我们将在您的设备上看到 Raspberry Pi 的桌面。
步骤 3:最后,创建虚拟桌面
- 在 Raspberry Pi 的终端上,运行 vncserver 并记录 Pi 的 IP 地址和屏幕上显示的数字。
- 接下来,在小工具上,我们将用于命令 Raspberry Pi,在 VNC Viewer 中键入 IP 地址和端口号。
- 输入 Raspberry Pi 身份验证:用户名&密码。 请记住,默认的 Raspberry Pi 凭据分别是“ pi”和“ raspberry”。
- 做完了!
Raspberry Pi Java 教程
在本教程中,我将向您展示如何使用 Raspberry Pi 和 Java 来闪烁 LED 灯。 这将是一个完整的分步教程,从连接电缆开始,通过 GPIO 解释,最后编写 Java 代码。 在本教程的最后,我将向您展示如何使用连接到 Raspberry 的 LED 灯编写完整的 Java 程序。
介绍
您可以建立的最简单的电路之一是连接到光源和开关的电池(电阻器用于保护 LED):
在上图中,Raspberry Pi 替换了开关和电池。
要求
带有 Raspbian 操作系统的 Raspberry Pi 板(了解如何安装和配置 Raspbian )
1 x LED 灯
2 x 母对母跳线电缆(您可以在网上购买 40 支,价格低于 2 美元)
Raspberry Pi GPIO
根据该模型,Raspberry Pi 在板的边缘,黄色视频输出插座旁边提供了不同数量的 GPIO(通用输入/输出)引脚。
这些引脚是 Pi 与外界之间的物理接口。 每个引脚可以打开或关闭,或者在计算方面变为高电平或低电平。 当引脚为高电平时,它输出 3.3 伏特(3v3);当引脚处于高电平时,它输出 3 伏特。 当引脚为低电平时,它关闭。 26 个引脚中的 17 个(用于型号 A 和 B)是 GPIO 引脚; 其他是电源或接地引脚。 型号 A +和 B +有 40 个引脚,其中 26 个是 GPIO 引脚。 本教程适用于所有 Raspberry Pi 型号。
连线
看下图。 我们将使用跳线将 LED 阴极(-)连接到 Raspberry Pi 的 6 号针脚,将阳极(+)连接到#12 的针脚。
首先将电缆连接到 LED。 我将红色电缆连接到阳极,将棕色电缆连接到阴极。 您可以使用任何喜欢的颜色。
现在,将电缆的另一端连接到 Raspberry 板的针脚 6 和 12
组装完成。 现在打开 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 库包含到您的项目中。 如果使用 Maven,则可以将此依赖项添加到 POM 文件中:
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-core</artifactId>
<version>${project.version}</version>
</dependency>
您也可以使用老式的方法:
1)从下载页面下载 pi4j ZIP 文件
2)复制以下 JAR 文件并将其包含在您的项目中(在下载的档案的 lib 文件夹中找到):
编译代码需要 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 亮度调节
在本教程中,我将向您展示如何使用 PWM 控制电压以使 LED 变暗。
打开和关闭 LED 很容易。 您可以在我的上一教程中了解如何执行此操作。 现在,我将向您展示如何控制电压电平以使 LED 灯变弱或变强。 通常,Raspberry GPIO 使用 3.3 的电压。 当该引脚处于上升状态时,输出电压等于 3.3,而当该引脚处于下降状态时,电压为 0。那么如何将电压更改为例如 3.3V 的 50% ? 我们可以使用脉宽调制(PWM)进行此操作。根据 Wikipedia,PWM 是:“一种用于将消息编码为脉冲信号的技术。 尽管这种调制技术可用于编码信息以进行传输,但其主要用途是允许控制提供给电气设备,尤其是惯性负载(如电机)的功率。
在 Raspberry Pi 中,只有一个引脚支持硬件 PWM。 硬件 PWN 引脚产生非常干净的信号。 虽然您可以制作一个软件 PWM,但所有引脚都可以产生 PWM。 软件的 PWM 引脚没有如此清晰的信号,您必须自行设定时序。
我们将使用与先前教程中完全相同的电路。 看下图
以下代码示例将使 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)–在本教程的后面,我将为您提供更多详细信息
- 几根电线
看下图。 它显示了如何构建电路。
这是我们的电路原理图
达灵顿数组芯片
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
- 电池组可为您的电机提供正确的电压
- 几根电缆可以连接一切
硬件部件
L293D
L293D 是用于直流或步进电机的双 H 桥电机驱动器,这意味着您可以双向驱动两个直流电机或一个步进电机。 L293D 的优点在于,它内置有回弹保护功能,可防止损坏 Raspberry Pi。
切勿将电机直接连接到 Raspberry Pi。 这可能会严重损坏您的 Pi!
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 之前,请务必仔细检查接线!
请使用下图组装电路。
Raspberry Pi 3 的硬件设置,以通过 L293D 和 Java 双向控制一台直流电机
在本教程中,我将使用 GPIO 引脚的物理编号。 物理编号指的是通过简单地从左上角的插针 1 算起并向下计数的插针。
查看下图,该图显示了物理引脚编号和 Pi4J 映射。 例如,物理针脚编号 12 在 Pi4J 中被命名为针脚#1。 在本教程后面的部分中编写 Java 程序时,请牢记这一点。 您可以在 Pi4J 官方网站中找到有关引脚编号的更多详细信息。
Raspberry Pi 3 Model B 引脚和 Pi4J 映射
注意:本教程是针对 Raspberry Pi 3 B 型制作的,当然,您可以在 Raspberry Pi 1 或 2 中构建相同的电路并使用相同的 Java 代码 - 只需注意引脚编号即可。
- 将 L293D 引脚#16 连接到 Pi 物理引脚#2(5.0 VDC 电源)
- 将 L293D 的针脚 4,针脚 5,针脚 12 和针脚 13 连接到 Pi 物理针脚 6(接地)
- 将 L293D 的 8 号针脚连接到电池组
- 将 L293D 的针脚#3 和#6 连接到电机
- 将 L293D 引脚 1 连接到 Pi 物理引脚 22
- 将 L293D 引脚 2 连接到 Pi 物理引脚 18
- 将 L293D 针脚#7 连接到 Pi 物理针脚#16
我还将在此处发布电路原理图以供参考
Raspberry Pi 和 L293D 一台电机原理图
具有 1 个电机的组装电路的照片
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。
树莓派控制 2 台电机
这是组装电路的图片– 2 个电机设置
具有 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 引脚。 对于使能引脚(motor1pinE
和motor2pinE
),我们使用与先前代码完全相同的定义。
一旦执行,程序将:
- 以 15% 的速度顺时针旋转电机 1 2 秒钟
- 以 60% 的速度顺时针旋转电机 1 2 秒钟
- 以全速将电机 1 顺时针旋转 2 秒
- 以 50% 的速度沿相反方向旋转电机 1 3 秒钟
- 停止马达 1
- 以 30% 的速度顺时针旋转电机 2 2 秒
- 以相反的方向将电机 2 全速旋转 3 秒钟
- 停止马达 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
运行程序时,您应该看到此控制台输出
程序控制台输出
以下视频演示了结果
https://www.youtube.com/embed/Jfuu-h_NYY0
结论
你还在读这个吗? 谢谢! 这是一个很长的教程🙂现在,在您知道如何使用 Raspberry Pi 控制电机之后,也许您可以考虑构建一些很酷的项目甚至是一个小型机器人并与我们分享结果🙂
与往常一样,我喜欢阅读您的评论并回答您的问题。 如果您喜欢本教程或其他教程,请传播!
您可以在 GitHub 中找到所有项目文件: https://github.com/JavaTutorialNetwork/Tutorials/tree/master/RaspberryPiControlMotors
资料来源: