错误:java.lang.IllegalArgumentException: Service not registered

当前位置:首页 » Android
In 学习, 笔记  @2015-08-20

问题

在做Service的绑定和解绑小项目测试的时候,绑定成功,解绑也成功,但是如果解除绑定后再点击给解除绑定的指令(项目中就是点击按钮解除绑定),会报这个错误:

AndroidRuntime(7090): java.lang.IllegalArgumentException: Service not registered: 
com.m1910.servicetest.MainActivity$1@41ddfcc0

错误提示Service没有注册,事实上我在Manifest.xml中已经注册过这个Service了。

修改前代码:

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.start_service:
            Intent startIntent = new Intent(this, MyService.class);
            startService(startIntent);// 启动服务
            break;
        case R.id.stop_service:
            Intent stopIntent = new Intent(this, MyService.class);
            stopService(stopIntent);// 停止服务
            break;
        case R.id.bind_service:
            Intent bindIntent = new Intent(this, MyService.class);
                        // 绑定服务
            bindService(bindIntent, connection, BIND_AUTO_CREATE);
            break;
        case R.id.unbind_service:
            unbindService(connection);// 解绑服务   
            break;
        default:
            break;
        }
    }

原因

查询官方文档中关于unbindService()这个方法的介绍:

public abstract void unbindService (ServiceConnection conn)

Added in API level 1
Disconnect from an application service. You will no longer receive calls as the service is restarted, and the service is now allowed to stop at any time.

Parameters
conn    The connection interface previously supplied to bindService(). This parameter must not be null.

最后一句看到这个传入的conn参数不能为null,也就是必须有绑定存在,才能解绑,小项目中绑定成功后第一次点击解绑不会报错,解绑后这个参数就是null了,再次点击解绑就会报错,那么我们为解绑加一个判断就可以了。

修改后代码如下:

private boolean isBound = false;

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.start_service:
            Intent startIntent = new Intent(this, MyService.class);
            startService(startIntent);// 启动服务
            break;
        case R.id.stop_service:
            Intent stopIntent = new Intent(this, MyService.class);
            stopService(stopIntent);// 停止服务
            break;
        case R.id.bind_service:
            Intent bindIntent = new Intent(this, MyService.class);
                        // 绑定服务
            isBound = bindService(bindIntent, connection, BIND_AUTO_CREATE);
            break;
        case R.id.unbind_service:
            if (isBound) {
                unbindService(connection);// 解绑服务
                isBound = false;
            }
            break;
        default:
            break;
        }
    }

网上也有人用getApplicationContext().unbindService(mConnection);这样来做,什么意思我也不太懂,不过最终效果一样也是要加一个是否为空的判断。

Android笔记:Notification的使用总结

当前位置:首页 » Android
In 学习, 笔记  @2015-08-19

关于Android通知栏Notification使用的总结。

重点知识点:

  • 使用Notification.builder类的系列set方法设置通知栏的参数;
  • setContentIntent()方法添加PendingIntent达到点击启动Activity的功能。
  • 调用builder.build()方法返回一个notification对象;
  • 然后利用notification的一些属性设置它的声音,震动,灯光,点击关闭等等特性。
    Android通知栏Notification使用的总结

notification点击后消失两种方法:

  1. 在点击启动的新Activity中调用notificationManager.cancel();
  2. 给notification.flags = Notification.FLAG_AUTO_CANCEL;

notification常驻状态栏的两个flag

  1. FLAG_ONGOING_EVENT //提示用户程序正在运行,如正在通话……
  2. FLAG_NO_CLEAR //clear按钮将无法清除这个notification

案例代码:

package com.m1910.notificationtest;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener {

    private Button sendNotice;
    String tickerText = "This is ticker text.";
    String contentTitle = "This is content title.";
    String contentText = "This is content Text.";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sendNotice = (Button) findViewById(R.id.send_notice);
        sendNotice.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.send_notice:
            // 实例化一个NotificationManager对象。
            NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            // 创建intent用来启动NotificationActivity
            Intent intent = new Intent(this, NotificationActivity.class);
            // 将intent传入到PendingIntent对象中用getActivity()方法实例化一个PendingIntent对象。
            // 这里还可以使用getService()以及getBroadcast()方法,传入的参数一样。
            PendingIntent pi = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
            // 实例化一个Builder对象。
            Notification.Builder nBuilder = new Notification.Builder(this);
            // 利用Builder对象的一系列set方法设置参数,其中注意使用setContentIntent()传入上面的PendingIntent对象pi;
            // builder()方法返回一个Notification对象
            Notification notification = nBuilder.setContentTitle(contentTitle).setContentText(contentText)
                    .setTicker(tickerText).setSmallIcon(R.drawable.ic_launcher).setContentIntent(pi).build();
            // 设置提示音
            notification.defaults = Notification.DEFAULT_SOUND;
            // 设置点击后自动清除通知
            notification.flags = Notification.FLAG_AUTO_CANCEL;
            // 调用NotificationManager的notify()方法启动这个notification;
            // 第一个参数APP中这个notification唯一标识符,第二个是要显示的Notification对象。
            manager.notify(1, notification);
            break;
        default:
            break;
        }
    }
}

Notification进阶部分:

  1. 如网易云音乐那样的可操作的通知栏需要用到相对比较复杂的布局使用Notification.BuildersetContent(RemoteViews views)设置自定义布局,暂时还没做过;
  2. android4.1之后,有小布局,大布局,下滑后的通知栏,选中的状态栏,以及锁屏状态的通告,这些都是可以深入研究的方向。
  3. 前台服务的使用,创建服务的时候调用startForeground()方法启动notification,让服务在状态栏常驻。
标签: , , , ,   评论: 8枚 

Android编程遇到的小问题20150819

当前位置:首页 » Android
In 学习, 笔记  @2015-08-18

问题一:
代码:

notification = new Notification.Builder(ctx)
                .setContentTitle("Title").setContentText("Text")
                .setSmallIcon(R.drawable.ic_launcher).build();

提示错误:

Call requires API level 16 (current min is 14): android.app.Notification.Builder#build

原因见文档:
public Notification build ()
Combine all of the options that have been set and return a new Notification object.
Added in API level 16
Notification 的 build ()方法是在API level 16才有的;
而我的适配版本是API level 14,需要使用getNotification ()才行。

问题二:
adb服务出现异常,如果想手工关闭adb服务,可以使用下面的命令:

关闭adb服务命令:adb kill-server
启动adb服务命令:adb start-server

问题三:
eclipse下按alt+/快捷键无代码提示故障:
也不知道为啥会出现这个问题,我的情况解决方法如下:
Window – Preferences – General – Keys
1/Restore Defaults恢复默认设置;
2/把word completion的快捷键设置alt+C
3/把Content Assist的快捷键由ctrl+space改成alt+/
4/window->Preferences->Java->Editor->Content Assist->Enable auto activation 选项要打上勾;

标签: , ,   评论: 2枚