我正在为华为手表2开发。当出现警报短信时,手表应切换到AlertScreen,并开始振动。 99%的时间都可以工作,但是有时并没有发生振动。我已经对代码进行了很多次重构,但是无法弄清楚错误在哪里。
MainActivity
我正在注册一个用于接收SMS的侦听器,然后调用startAlert
函数以开始振动:
public class MainActivity extends FragmentActivity {
private final FragmentManager supportFragmentManager = getSupportFragmentManager();
private final SmsBroadcastReceiver smsBroadcastReceiver = new SmsBroadcastReceiver();
private final AlertFragment alertFragment = new AlertFragment();
private static final String SENDER_PHONE_NUMBER = MyApplication.getAppContext().getResources().getString(R.string.sender_phone);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
supportFragmentManager.beginTransaction().replace(R.id.fragment_container, new MainFragment()).commit();
registerReceiver(smsBroadcastReceiver, new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION));
smsBroadcastReceiver.setListener(new SmsListener() {
@Override
public void messageReceived(final String phoneNumber) {
startAlert(phoneNumber);
}
});
}
private void startAlert(final String phoneNumber) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (alertFragment.isRunning || phoneNumber.equals(SENDER_PHONE_NUMBER)) {
supportFragmentManager.beginTransaction().replace(R.id.fragment_container, alertFragment).commitAllowingStateLoss();
alertFragment.startAlert(phoneNumber);
}
}
}, 4000);
}
}
AlertFragment:
在startAlert
的此片段中,我向executorService
添加了一个辅助类,这将开始实际的振动。 isRunning
变量在此处,因为在运行时,如果手表从另一个数字接收到新消息,则通常会停止振动。
public class AlertFragment extends Fragment {
private Button cancelButton;
private Future longRunningTaskFuture;
private ConnectionService mService;
private PowerManager powerManager;
private FragmentManager supportFragmentManager;
private PowerManager.WakeLock wakeLock;
AlertHelper longRunningTask = new AlertHelper();
public boolean isRunning = false;
private boolean mBound = false;
private final String TYPE = "feedback";
private static final String SENDER_PHONE_NUMBER = MyApplication.getAppContext().getResources().getString(R.string.sender_phone);
private View.OnClickListener onAlertButtonPressedListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
mService.sendMessage(new Message(TYPE, "1").toJson());
supportFragmentManager.beginTransaction().replace(R.id.fragment_container, new MainFragment()).commit();
stopAlert();
}
};
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onStart() {
super.onStart();
supportFragmentManager = getActivity().getSupportFragmentManager();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
wakeUpWatch();
Intent intent = new Intent(context, ConnectionService.class);
context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.alert_fragment, container, false);
if (view != null) {
cancelButton = (Button) view.findViewById(R.id.stop_button);
cancelButton.setOnClickListener(onAlertButtonPressedListener);
}
((DrawerLock) getActivity()).setDrawerLocked(true);
return view;
}
@Override
public void onSaveInstanceState(Bundle outState) {
//No call for super(). Bug on API Level > 11.
}
@Override
public void onDestroyView() {
super.onDestroyView();
((DrawerLock) getActivity()).setDrawerLocked(false);
}
public void startAlert(String phoneNumber) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
// submit task to threadpool:
if (isRunning || phoneNumber.equals(SENDER_PHONE_NUMBER)) {
longRunningTaskFuture = executorService.submit(longRunningTask);
isRunning = true;
}
}
public void stopAlert() {
longRunningTaskFuture.cancel(true);
longRunningTaskFuture = null;
isRunning = false;
longRunningTask.vibrator.cancel();
releaseWakeLock();
}
private void wakeUpWatch() {
Intent intent = new Intent(getActivity().getApplicationContext(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // You need this if starting
// the activity from a service
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
startActivity(intent);
powerManager = (PowerManager) MyApplication.getAppContext().getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_BRIGHT_WAKE_LOCK,"MyWakelockTag");
wakeLock.acquire();
}
private void releaseWakeLock() {
if (wakeLock != null && wakeLock.isHeld()) {
wakeLock.release();
}
}
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className,
IBinder service) {
ConnectionService.LocalBinder binder = (ConnectionService.LocalBinder) service;
mService = binder.getServiceInstance();
mBound = true;
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
}
最后,AlertHelper
类实际上将开始振动:
public class AlertHelper implements Runnable {
Vibrator vibrator = (Vibrator) MyApplication.getAppContext().getSystemService(Context.VIBRATOR_SERVICE);
public volatile boolean isRunning;
private final long[] mVibratePattern = new long[]{0, 400, 800, 600, 800, 800, 800, 1000};
private final int[] mAmplitudes = new int[]{0, 255, 0, 255, 0, 255, 0, 255};
@Override
public void run() {
this.isRunning = true;
if (this.vibrator != null) {
this.vibrator.vibrate(VibrationEffect.createWaveform(mVibratePattern, mAmplitudes, 0));
}
}
}
所以我不知道,振动通常按其应有的方式起作用,但有时却不起作用。在每个实现中,我总是遇到这个错误,因此我开始认为这可能是我不知道的错误。这里有什么解决方案?
编辑:
该错误不在MainActivity中,因为屏幕始终在按需更改,因此问题必须出在警报类上