作为人类,我们往往会忘记一些小而重要的事物,而要解决此问题,我们会尝试将这些事物写下并粘贴到我们经常看到的地方。在这个数字时代,我们最有可能看到的东西是笔记本电脑,计算机或手机屏幕。为此,我们都曾经在Windows上使用Sticky Notes或在Mac上使用Stickies,今天在本文中,我们将讨论如何为Android构建此类应用程序。
方法
现在,如果我们想到的是粘性的东西,即粘附在屏幕上的东西,那么在Android中,我们想到的组件是主屏幕小部件。主屏幕小部件是粘贴在屏幕上的最佳交互式组件,可以用任何方式调整其大小。我们将创建一个也具有自己的小部件的应用程序。我们将首先在主应用程序中编写一些文本,然后将其保存到内存中的文件中。此刻,我们将使用用户刚刚保存的文本来更新小部件。还有霍里!我们的粘滞便笺已准备就绪。
什么是主屏幕小部件?
这里要注意的一件事是,在Android视图中也称为Widget,因此为了避免混淆,我们使用了术语Home Screen Widgets。这些是提供交互式组件的广播接收器。它们通常显示某种信息,并鼓励用户与其进行交互。例如,它可能显示时间,天气或电子邮件,并且一旦单击它们,托管它们的主应用程序就会启动。窗口小部件使用RemoteViews来构建其用户界面。具有与原始应用程序相同的权限,RemoteView可以通过其他方法运行。结果,该小部件将在创建它的应用程序的权限下运行。窗口小部件的用户界面由广播接收机确定。此接收器将其布局放大为RemoteView对象。
分步实施
步骤1:创建一个新项目
要在Android Studio中创建新项目,请参阅如何在Android Studio中创建/启动新项目。请注意,选择Java作为编程语言。
步骤2:使用AndroidManifest.xml文件
添加用于从存储中读取和写入文件的用户权限。同样,为了注册窗口小部件,我们必须创建一个具有意图过滤器的广播接收器。
XML
Java
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
// Implementation of App Widget functionality
public class AppWidget extends AppWidgetProvider {
// Create an Intent to launch activity
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// Perform this loop procedure for each App Widget
// that belongs to this provider
for (int appWidgetId : appWidgetIds) {
// Create an Intent to launch MainActivity
Intent launchActivity = new Intent(context, MainActivity.class);
// Attaching a Pending Intent
// to trigger it when
// application is not alive
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, launchActivity, 0);
// Get the layout for the App Widget and attach
// an on-click listener to the button
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
remoteViews.setOnClickPendingIntent(R.id.appwidget_text, pendingIntent);
// Tell the AppWidgetManager to perform an
// update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
}
}
Java
import android.content.Context;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import static android.content.Context.MODE_PRIVATE;
class StickyNote {
// this function will return
// the content from the text
// file(if any)
String getStick(Context context) {
// get the file from path
File fileEvents = new File(context.getFilesDir().getPath() + "/gfg.txt");
// create a StringBuilder to store the text from file
StringBuilder text = new StringBuilder();
try {
// use the BufferedReader
// to Read the file
// efficiently
BufferedReader br = new BufferedReader(new FileReader(fileEvents));
String line;
// read a single line at a time
// append newline character after each line
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
}
// close the BufferedReader
br.close();
} catch (IOException e) {
e.printStackTrace();
}
// finally return the
// string i.e. the retrieved data
// from file
return text.toString();
}
// this function saves the new
// content in the file if it
// exists or will create a new one
void setStick(String textToBeSaved, Context context) {
String text = textToBeSaved;
// create the FileOutputStream
// to efficiently write the file
FileOutputStream fos = null;
try {
// get the file from storage
fos = context.getApplicationContext().openFileOutput("gfg.txt", MODE_PRIVATE);
// write to the file at once
fos.write(text.getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Java
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.widget.EditText;
import android.widget.RemoteViews;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
EditText mEditText;
// creating a new note
StickyNote note = new StickyNote();
@Override
protected void
onCreate(android.os.Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
super.onCreate(savedInstanceState);
// getting the reference of the EditText
mEditText = findViewById(R.id.editText);
// retrieve the text from the saved file in
// memory(if any) and set it to the edittext
mEditText.setText(note.getStick(this));
}
// function to update the
// Widget(Sticky Note) every time
// user saves the note
public void updateWidget() {
// the AppWidgetManager helps
// us to manage all the
// widgets from this app
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);
// the RemoteViews class allows us to inflate a
// layout resource file hierarchy and provides some
// basic operations for modifying the content of the
// inflated hierarchy
RemoteViews remoteViews = new RemoteViews(this.getPackageName(), R.layout.new_app_widget);
// by using ComponentName class we can get specific
// application component and to identify the
// component we pass the package name and the class
// name inside of that package
ComponentName thisWidget = new ComponentName(this, AppWidget.class);
// update the text of the textview of the widget
remoteViews.setTextViewText(R.id.appwidget_text, mEditText.getText().toString());
// finally us the AppWidgetManager instance to
// update all the widgets
appWidgetManager.updateAppWidget(thisWidget, remoteViews);
}
// this function saves
// the current status
// of the EditText
public void saveButton(android.view.View v) {
// update the content of file stored in the memory
note.setStick(mEditText.getText().toString(), this);
updateWidget();
Toast.makeText(this, "Updated Successfully!!", Toast.LENGTH_SHORT).show();
}
}
XML
步骤3:建立小工具
请按照本文创建Android应用程序的基本小部件中提到的步骤,将小部件添加到您的项目中。文件new_app_widget_info.xml包含确定小部件外观的代码,就像在小部件列表中显示的一样。
步骤4:使用AppWidget类
该类将在上一步中形成。转到AppWidget。 Java文件并参考以下代码。下面是AppWidget的代码。 Java文件。在代码内部添加了注释,以更详细地了解代码。
Java
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
// Implementation of App Widget functionality
public class AppWidget extends AppWidgetProvider {
// Create an Intent to launch activity
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// Perform this loop procedure for each App Widget
// that belongs to this provider
for (int appWidgetId : appWidgetIds) {
// Create an Intent to launch MainActivity
Intent launchActivity = new Intent(context, MainActivity.class);
// Attaching a Pending Intent
// to trigger it when
// application is not alive
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, launchActivity, 0);
// Get the layout for the App Widget and attach
// an on-click listener to the button
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
remoteViews.setOnClickPendingIntent(R.id.appwidget_text, pendingIntent);
// Tell the AppWidgetManager to perform an
// update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
}
}
步骤5:创建StickyNote类
这是一个帮助程序类,提供了在文件中保存,更新和检索内容的功能。转到StickyNote。 Java文件并参考以下代码。以下是StickyNote的代码。 Java文件。在代码内部添加了注释,以更详细地了解代码。
Java
import android.content.Context;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import static android.content.Context.MODE_PRIVATE;
class StickyNote {
// this function will return
// the content from the text
// file(if any)
String getStick(Context context) {
// get the file from path
File fileEvents = new File(context.getFilesDir().getPath() + "/gfg.txt");
// create a StringBuilder to store the text from file
StringBuilder text = new StringBuilder();
try {
// use the BufferedReader
// to Read the file
// efficiently
BufferedReader br = new BufferedReader(new FileReader(fileEvents));
String line;
// read a single line at a time
// append newline character after each line
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
}
// close the BufferedReader
br.close();
} catch (IOException e) {
e.printStackTrace();
}
// finally return the
// string i.e. the retrieved data
// from file
return text.toString();
}
// this function saves the new
// content in the file if it
// exists or will create a new one
void setStick(String textToBeSaved, Context context) {
String text = textToBeSaved;
// create the FileOutputStream
// to efficiently write the file
FileOutputStream fos = null;
try {
// get the file from storage
fos = context.getApplicationContext().openFileOutput("gfg.txt", MODE_PRIVATE);
// write to the file at once
fos.write(text.getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
步骤6:使用MainActivity。 Java文件
转到MainActivity。 Java文件并参考以下代码。下面是MainActivity的代码。 Java文件。在代码内部添加了注释,以更详细地了解代码。
Java
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.widget.EditText;
import android.widget.RemoteViews;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
EditText mEditText;
// creating a new note
StickyNote note = new StickyNote();
@Override
protected void
onCreate(android.os.Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
super.onCreate(savedInstanceState);
// getting the reference of the EditText
mEditText = findViewById(R.id.editText);
// retrieve the text from the saved file in
// memory(if any) and set it to the edittext
mEditText.setText(note.getStick(this));
}
// function to update the
// Widget(Sticky Note) every time
// user saves the note
public void updateWidget() {
// the AppWidgetManager helps
// us to manage all the
// widgets from this app
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);
// the RemoteViews class allows us to inflate a
// layout resource file hierarchy and provides some
// basic operations for modifying the content of the
// inflated hierarchy
RemoteViews remoteViews = new RemoteViews(this.getPackageName(), R.layout.new_app_widget);
// by using ComponentName class we can get specific
// application component and to identify the
// component we pass the package name and the class
// name inside of that package
ComponentName thisWidget = new ComponentName(this, AppWidget.class);
// update the text of the textview of the widget
remoteViews.setTextViewText(R.id.appwidget_text, mEditText.getText().toString());
// finally us the AppWidgetManager instance to
// update all the widgets
appWidgetManager.updateAppWidget(thisWidget, remoteViews);
}
// this function saves
// the current status
// of the EditText
public void saveButton(android.view.View v) {
// update the content of file stored in the memory
note.setStick(mEditText.getText().toString(), this);
updateWidget();
Toast.makeText(this, "Updated Successfully!!", Toast.LENGTH_SHORT).show();
}
}
第7步:我们的小部件的布局文件
由于我们只希望窗口小部件保留文本,因此我们仅将TextView添加到布局资源文件中,该文件会不时更新。
XML格式
输出:
Github项目链接
对于所有可绘制的资源文件,请参考以下GitHub链接:https://github.com/raghavtilak/StickyNotes
未来范围
- 您可以添加功能来更改小部件的外观,例如文本样式,背景颜色,透明度,宽度等。
- 您可以对UI进行一些改进。
- 您可以通过将数据保存到数据库中并提取它们来创建多个便笺。
- 另外,您可以尝试向Widget添加一些不同的视图。