Android Wear设备振动器并非始终以编程方式振动

时间:2018-11-23 15:42:39

标签: java android wear-os android-vibration

我正在为华为手表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中,因为屏幕始终在按需更改,因此问题必须出在警​​报类上

0 个答案:

没有答案