最近,做一个调用系统自带相机的那么一个功能,遇到的坑,在此记录一下。
设备:红米note4
问题起因
因为自定义的相机,很难满足客户的所有需要,比如:自拍杆的支持,优化方面等等。这些方面自定义的相机都不比系统自带的好,因为有些系统都是商家定制的,难免会出现一个奇葩的问题。比如:你在这款手机上运行,无任何问题,然而你换一款手机后,问题就出现了。
比如:小米的红米系列,你启用系统自带拍照功能后,当前的所有进程都会被结束了(包含:其它正在运行的程序)。当你拍照完成,返回时,问题出现了,总会报些空指针。
虽然调用了系统相机,进程会被结束掉,但返回时被结束的进程被重新启动,但这时你之前保存的值都没了(activity会重新启动oncreate流程,application会重新初始化)。
当然你会说,完全可以在activity中的onSaveInstanceState方法中保存值,等恢复再取出。但如果是application呢?那又怎么恢复。如果你的业务够复杂,那数据真不好恢复,比如:你的主体是activity,activity中又有若干个Fragment,各个Fragment又取值于application,这些就麻烦多多,恢复都麻烦。
解决方案
在前台运行服务
看官方描述:https://developer.android.com/guide/components/services.html
前台服务被认为是用户主动意识到的一种服务,因此在内存不足时,系统也不会考虑将其终止。 前台服务必须为状态栏提供通知,放在“正在进行”标题下方,这意味着除非服务停止或从前台移除,否则不能清除通知。
例如,应该将通过服务播放音乐的音乐播放器设置为在前台运行,这是因为用户明确意识到其操作。 状态栏中的通知可能表示正在播放的歌曲,并允许用户启动 Activity 来与音乐播放器进行交互。
需要在服务里使用startForeground方法
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);
实现代码
NotificationService.java
package xxx;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.hkcg.mrsi.MyApplication;
import com.hkcg.mrsi.R;
/**
*
* @author Aaron
* @version 1.0
* @createTime 2016-12-20
* @desc <br>
* @usage
*/
public class NotificationService extends Service {
private static Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
private static NotificationManager mNotificationManager = (NotificationManager) MyApplication.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
private static final String TAG = "NotificationService";
@Override
public void onCreate() {
// TODO Auto-generated method stub
Log.i(TAG, "onCreate");
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand");
Notification notification = createNotificationTip(0x689,this, "title", "为确保正常运行,请不要结束程序运行。",null);
startForeground(0x689, notification);
flags = START_STICKY;
return super.onStartCommand(intent, flags, startId);
}
public Notification createNotificationTip(int id,Context context, String title, String content, Integer icon) {
icon = icon == null ? R.drawable.ic_launcher : icon;
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(icon)//小图标
.setContentTitle(title) // 标题
.setContentText(content)// 内容
.setOngoing(true) // 是否正在进行
.setPriority(Notification.PRIORITY_MAX);//通知优先级
Notification notification = mBuilder.build();
mNotificationManager.notify(id, notification);
return notification;
}
}
AndroidManifest.xml
<service
android:name="com.hkcg.mrsi.loc.NotificationService"
android:enabled="true" >
</service>
调用
startService(new Intent(this, NotificationService.class));