Working in the Background

本文详细介绍了Android应用中服务与通知的基本概念、创建与使用方法,包括服务的启动与停止、绑定活动到服务、显示与定制Toast、使用NotificationManager创建并配置通知等关键操作。同时,阐述了如何利用NotificationManager实现通知的个性化展示,并通过AlarmManager实现定时任务。文章旨在为Android开发者提供全面的服务与通知管理解决方案。

Creating a Service

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class MyService extends Service {
@Override
public void onCreate() {
// TODO: Actions to perform when service is created.
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Replace with service binding implementation.
return null;
}
}

 

Starting a Service

// Implicitly start a Service
Intent myIntent = new Intent(MyService.ORDER_PIZZA);
myIntent.putExtra("TOPPING", "Margherita");
startService(myIntent);
// Explicitly start a Service
startService(new Intent(this, MyService.class));

 

Stopping a Service

ComponentName service = startService(new Intent(this, BaseballWat
// Stop a service using the service name.
stopService(new Intent(this, service.getClass()));
// Stop a service explicitly.
try {
Class serviceClass = Class.forName(service.getClassName());
stopService(new Intent(this, serviceClass));
} catch (ClassNotFoundException e) {}

 

Binding Activities to Services

private final IBinder binder = new MyBinder();
@Override
public IBinder onBind(Intent intent) {
return binder;
}
public class MyBinder extends Binder {
MyService getService() {
return MyService.this;
}
}

 

The connection between the Service and Activity is represented as a ServiceConnection.
You’ll need to implement a new ServiceConnection, overriding the onServiceConnected and
onServiceDisconnected methods to get a reference to the Service instance once a connection has been
established

 

// Reference to the service
private MyService serviceBinder;
// Handles the connection between the service and activity
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// Called when the connection is made.
serviceBinder = ((MyService.MyBinder)service).getService();
}
public void onServiceDisconnected(ComponentName className) {
// Received when the service unexpectedly disconnects.
serviceBinder = null;
}
};

 

Intent bindIntent = new Intent(MyActivity.this, MyService.class);
bindService(bindIntent, mConnection, Context.BIND_AUTO_CREATE);

 

 

Displaying a Toast

Context context = getApplicationContext();
String msg = "To health and happiness!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, msg, duration);
toast.show();

 

Customizing a Toast

Context context = getApplicationContext();
String msg = "To the bride and groom!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, msg, duration);
int offsetX = 0;
int offsetY = 0;
toast.setGravity(Gravity.BOTTOM, offsetX, offsetY);
toast.show();

 

toast.setView(ll);

toast.show();

 

Using the Notification Manager

String svcName = Context.NOTIFICATION_SERVICE;
NotificationManager notificationManager;
notificationManager = (NotificationManager)getSystemService(svcName);

 

Creating a Notification

int icon = R.drawable.icon;
// Text to display in the status bar when the notification is launched
String tickerText = "Notification";
// The extended status bar orders notification in time order
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);

 

Configuring the Extended Status Notification Display

You can configure the appearance of the Notification within the extended status window in two ways:
1. Use the setLatestEventInfo method to update the details displayed in the standard extended
status Notification display.
2. Set the contentView and contentIntent properties to assign a custom UI for the extended
status display using a Remote View.

 

Setting Notification values

Context context = getApplicationContext();
// Text to display in the extended status window
String expandedText = "Extended status text";
// Title for the expanded status
String expandedTitle = "Notification Title";
// Intent to launch an activity when the extended text is clicked
Intent intent = new Intent(this, MyActivity.class);
PendingIntent launchIntent = PendingIntent.getActivity(context, 0, intent, 0);
notification.setLatestEventInfo(context,expandedTitle,expandedText,launchIntent);

 

Applying a custom layout to the Notification status window

 

Notification notification = new Notification(R.drawable.icon,
"Custom Content",
System.currentTimeMillis());
notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT;
notification.contentView = new RemoteViews(this.getPackageName(),
R.layout.my_status_window_layout);
Intent intent = new Intent(this, MyActivity.class);
PendingIntent.getActivity(this, 0, intent, 0));
notification.contentIntent = pendingIntent;

notification.contentView.setImageViewResource(R.id.status_icon,
R.drawable.icon);
notification.contentView.setTextViewText(R.id.status_text,
"Current Progress:");
notification.contentView.setProgressBar(R.id.status_progress,
100, 50, false);

 

 

Triggering a Notification

int notificationRef = 1;
notificationManager.notify(notificationRef, notification);

 

notificationManager.cancel(notificationRef);

 

Using the Defaults

 Using the defaults property you can combine:

➤ Notification.DEFAULT_LIGHTS
➤ Notification.DEFAULT_SOUND
➤ Notification.DEFAULT_VIBRATE

 

notification.defaults = Notification.DEFAULT_SOUND |
Notification.DEFAULT_VIBRATE;

 

Uri ringURI =
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

notification.sound = ringURI;

 

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

long[] vibrate = new long[] { 1000, 1000, 1000, 1000, 1000 };
notification.vibrate = vibrate;

 

The following code snippet shows how to turn on the red device LED:
notification.ledARGB = Color.RED;
notification.ledOffMS = 0;
notification.ledOnMS = 1;
notification.flags = notification.flags | Notification.FLAG_SHOW_LIGHTS;

 

USING ALARMS

AlarmManager alarms =
(AlarmManager)getSystemService(Context.ALARM_SERVICE);

 

RTC_WAKEUP Wake the device from sleep to fire the Pending Intent at the clock time specified.
RTC Fire the Pending Intent at the time specified, but do not wake the device.
ELAPSED_REALTIME Fire the Pending Intent based on the amount of time elapsed since the
device was booted, but do not wake the device. The elapsed time includes any period of time
the device was asleep. Note that the time elapsed is calculated based on when the device was
last booted.
ELAPSED_REALTIME_WAKEUP After a specified length of time has passed since device boot,
wake the device from sleep and fire the Pending Intent.

 

Creating an Alarm

int alarmType = AlarmManager.ELAPSED_REALTIME_WAKEUP;
long timeOrLengthofWait = 10000;
String ALARM_ACTION = "ALARM_ACTION";
Intent intentToFire = new Intent(ALARM_ACTION);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intentToFire, 0);
alarms.set(alarmType, timeOrLengthofWait, pendingIntent);

 

alarms.cancel(pendingIntent);

 

 

Setting and canceling an Alarm

AlarmManager alarms =
(AlarmManager)getSystemService(Context.ALARM_SERVICE);
String MY_RTC_ALARM = "MY_RTC_ALARM";
String ALARM_ACTION = "MY_ELAPSED_ALARM";
PendingIntent rtcIntent =
PendingIntent.getBroadcast(this, 0,
new Intent(MY_RTC_ALARM), 1);

PendingIntent elapsedIntent =
PendingIntent.getBroadcast(this, 0,
new Intent(ALARM_ACTION), 1);
// Wakeup and fire intent in 5 hours.
Date t = new Date();
t.setTime(java.lang.System.currentTimeMillis() + 60*1000*5);
alarms.set(AlarmManager.RTC_WAKEUP, t.getTime(), rtcIntent);
// Fire intent in 30 mins if already awake.
alarms.set(AlarmManager.ELAPSED_REALTIME, 30*60*1000, elapsedIntent);
// Cancel the first alarm.
alarms.cancel(rtcIntent);

 

Setting Repeating Alarms

To set a repeating alarm, use the setRepeating or setInexactRepeating method on the Alarm Manager

 

INTERVAL_FIFTEEN_MINUTES
INTERVAL_HALF_HOUR
INTERVAL_HOUR
INTERVAL_HALF_DAY
INTERVAL_DAY

 

// Fire an intent exactly every hour if already awake.
alarms.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
60*60*1000, 60*60*1000, elapsedIntent);
// Wakeup and fire an alarm about every hour
alarms.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
60*60*1000, AlarmManager.INTERVAL_DAY,
elapsedIntent);

 

 

 

在使用 Git 进行版本控制时,如果在子文件夹而非 Git 仓库根目录打开工作区,可能会遇到提示信息 `Workspace Not at Git Root: Please open the root folder of your Git repository instead of a subfolder`。这一问题通常出现在使用集成开发环境(IDE)如 Visual Studio Code 打开项目时,如果工作区文件(`.code-workspace`)被保存在子目录中,而不是 Git 仓库的根目录,就会触发此提示[^4]。 ### 问题原因 Git 仓库的根目录是指包含 `.git` 文件夹的那个目录。当使用 IDE 打开一个子目录作为工作区时,IDE 无法正确识别 Git 仓库的上下文,导致无法正常进行 Git 操作(如查看提交历史、提交更改等)。此外,IDE 可能无法正确加载 `.gitignore` 文件或 `.vscode/settings.json` 等配置文件,进而导致警告信息,例如: ``` warning: in the working copy of '.gitignore', LF will be replaced by CRLF the next time Git touches it warning: in the working copy of '.vscode/settings.json', LF will be replaced by CRLF the next time Git touches it ``` 这些警告表明 Git 正在尝试修改文件中的换行符格式,但由于工作区不在 Git 根目录,可能导致配置文件的行为异常[^4]。 ### 解决方案 要解决此问题,需要确保工作区文件(`.code-workspace`)位于 Git 仓库的根目录中。以下是具体的解决步骤: 1. **关闭当前工作区**:在 Visual Studio Code 中关闭当前打开的工作区。 2. **打开根目录**:导航到 Git 仓库的根目录,并在此目录中打开 Visual Studio Code。可以通过命令行执行以下命令: ```bash cd /path/to/your/git/repository code . ``` 3. **重新创建工作区文件**:如果之前的工作区文件是在子目录中创建的,请删除它,并在根目录中重新创建新的工作区文件。可以通过菜单 `File > Save Workspace As...` 来保存新的工作区文件。 4. **验证 Git 状态**:确保 Git 仓库状态正常,可以使用以下命令查看提交历史: ```bash git log ``` 如果一切正常,应该能够看到最近的提交记录[^1]。 5. **检查配置文件**:确认 `.gitignore` 和 `.vscode/settings.json` 文件没有被 Git 修改。可以通过以下命令查看文件状态: ```bash git status ``` 如果这些文件被标记为“modified”,可以使用 `git checkout` 命令恢复它们的原始状态: ```bash git checkout -- .gitignore git checkout -- .vscode/settings.json ``` 6. **禁用自动换行符转换(可选)**:如果你希望 Git 不自动转换换行符,可以在 Git 配置中禁用此功能: ```bash git config core.autocrlf false ``` 请注意,禁用此功能后,不同操作系统之间的换行符可能会不一致,需手动处理。 ### 总结 通过将工作区文件放置在 Git 仓库的根目录中,可以避免因工作区不在 Git 根目录而导致的 Git 操作问题和配置文件异常。同时,确保 Git 的自动换行符转换功能根据实际需求进行适当配置,以避免不必要的警告信息。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值