我正在尝试从低功耗蓝牙回调函数 onCharacteristicRead() 进行 Intent 调用。请告诉我哪里错了。
我不确定它是否与我们为 Intent 类提供的上下文或其他东西有关。
它向我显示以下错误:
"Unable to start activity ComponentInfo::java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference"
下面是代码示例:
package com.example.pushkara.msable;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.ParcelUuid;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.logging.ConsoleHandler;
@TargetApi(18)
public class MainActivity extends AppCompatActivity {
private BluetoothAdapter mBluetoothAdapter;
private int REQUEST_ENABLE_BT = 1;
private Handler mHandler;
private static final long SCAN_PERIOD = 5000;
private BluetoothLeScanner mLEScanner;
private ScanSettings settings;
private List<ScanFilter> filters;
private BluetoothGatt mGatt;
private MsaScanCallback mScanCallback;
private Button mCheckInButton;
private Button mCheckOutButton;
private Button mNewButton;
private Boolean buttonvalue = false;
public static TextView mSecurityCode;
public static TextView rssiNdistance;
public final static UUID UUID_MSA_APP = UUID.fromString("13333333-3333-3333-3333-333333333337");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mCheckInButton = (Button)findViewById(R.id.checkIn);
mCheckOutButton = (Button)findViewById(R.id.checkOut);
mSecurityCode= (TextView)findViewById(R.id.securityCode);
rssiNdistance= (TextView)findViewById(R.id.rssiNdistance);
mCheckOutButton.setOnClickListener(new MsaCheckInCheckout(false));
mCheckInButton.setOnClickListener(new MsaCheckInCheckout(true));
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("This app needs location access");
builder.setMessage("Please grant location access so this app can detect msa server.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@TargetApi(Build.VERSION_CODES.M)
@Override
public void onDismiss(DialogInterface dialog) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
}
});
builder.show();
}
}
mHandler = new Handler();
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, "BLE Not Supported",
Toast.LENGTH_SHORT).show();
finish();
}
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
}
catch(Exception ex){
Log.i("msable"," [@@MA]::::Exception 1" +ex.toString());
mSecurityCode.setText("[@@MA]Exc1" + ex.toString());
}
}
private final ConnectDevice connectToDeviceCallback = new ConnectDevice() {
@Override
public void OnConnectToDevice(BluetoothDevice device){
connectToDevice(device);
}
};
public class MsaCheckInCheckout implements View.OnClickListener {
private boolean mCheckIn;
public MsaCheckInCheckout(boolean isCheckIn){
mCheckIn =isCheckIn;
}
@Override
public void onClick (View v) {
try {
// your code here;
Log.i("CLICK", mCheckIn + "");
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
} else {
if (Build.VERSION.SDK_INT >= 21) {
if (mGatt != null) {
mGatt.close();
mGatt = null;
}
mScanCallback = new MsaScanCallback(connectToDeviceCallback);
mLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
ScanFilter filter = new ScanFilter.Builder().setServiceUuid(new ParcelUuid(UUID_MSA_APP)).build();
filters = new ArrayList<>();
filters.add(filter);
}
scanLeDevice(true);
}
}
catch(Exception ex){
Log.i("msable","[@@MA] ::::Exception 2" +ex.toString());
mSecurityCode.setText("[@@MA]Ex2" + ex.toString());
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
try {
switch (requestCode) {
case 1: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d("1", "coarse location permission granted");
} else {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Functionality limited");
builder.setMessage("Since location access has not been granted, this app will not be able to discover msa server");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
}
});
builder.show();
}
}
}
}
catch(Exception ex){
Log.i("msable","[@@MA] ::::Exception 3" +ex.toString());
mSecurityCode.setText("[@@MA]Ex3" + ex.toString());
}
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
scanLeDevice(false);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mGatt == null) {
return;
}
mGatt.close();
mGatt = null;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
try {
if (requestCode == REQUEST_ENABLE_BT) {
if (resultCode == Activity.RESULT_CANCELED) {
//Bluetooth not enabled.
finish();
return;
}
}
super.onActivityResult(requestCode, resultCode, data);
}
catch(Exception ex){
Log.i("msable","[@@MA] ::::Exception 4" +ex.toString());
mSecurityCode.setText("[@@MA]Ex4" + ex.toString());
}
}
private void scanLeDevice(final boolean enable) {
try {
Log.i("BLE", "**** scanLeDevice");
if(mBluetoothAdapter != null || mLEScanner !=null) {
Log.i("BLE", "**** Object not null proceed to stop scan");
if (enable) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
Log.i("BLE", "mBluetoothAdapter STOP SCAN");
} else {
Log.i("BLE", "mLEScanner STOP SCAN");
if(mLEScanner !=null) {
Log.i("BLE", "mLEScanner not null proceed for stop ");
}
else
{
Log.i("BLE", "mLEScanner is null !!!!!");
}
mLEScanner.stopScan(mScanCallback);
}
}
}, SCAN_PERIOD);
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.startLeScan(mLeScanCallback);
Log.i("BLE", "mBluetoothAdapter START SCAN");
} else {
Log.i("START SCAN", "START SCAN");
mLEScanner.startScan(filters, settings, mScanCallback);
}
} else {
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
mLEScanner.stopScan(mScanCallback);
}
}
}
else
{
Log.i("BLE","**** Object is null");
}
}
catch(Exception ex){
Log.i("msable","[@@MA] ::::Exception 5" +ex.toString());
mSecurityCode.setText("[@@MA]Ex5" + ex.toString());
}
}
double getDistance(int rssi) {
return Math.pow(10d, ((double) -52 - rssi) / (10 * 2));
}
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, final int rssi,
byte[] scanRecord) {
try {
Log.i("BLE","**** onLeScan LeScanCallback");
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.i("onLeScan", device.toString());
double distance = getDistance(rssi);
rssiNdistance.setText("rssi:"+rssi+" distance:"+distance);
if (distance <= 1) {
connectToDevice(device);
}
else{
mSecurityCode.setText("Out of Range!!!");
}
}
});
}
catch(Exception ex){
Log.i("msable","[@@MA] ::::Exception 6" +ex.toString());
mSecurityCode.setText("[@@MA]Ex6" + ex.toString());
}
}
};
public void connectToDevice(BluetoothDevice device) {
Log.i("BLE","**** connectToDevice");
if (mGatt == null) {
mGatt = device.connectGatt(this, false, gattCallback);
scanLeDevice(false);// will stop after first device detection
}else{
Log.i("gatt status","ATT");
}
}
private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
try {
Log.i("BLE","**** gattCallback onConnectionStateChange Status: "+status);
Log.i("onConnectionStateChange", "Status: " + status);
switch (newState) {
case BluetoothProfile.STATE_CONNECTED:
Log.i("gattCallback", "STATE_CONNECTED");
gatt.discoverServices();
break;
case BluetoothProfile.STATE_DISCONNECTED:
Log.e("gattCallback", "STATE_DISCONNECTED");
break;
default:
Log.e("gattCallback", "STATE_OTHER");
}
}
catch(Exception ex){
Log.i("msable","[@@MA] ::::Exception 7" +ex.toString());
mSecurityCode.setText("[@@MA]Ex7" + ex.toString());
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
try {
Log.i("BLE","**** onServicesDiscovered Status: "+status);
List<BluetoothGattService> services = gatt.getServices();
for (BluetoothGattService bg : services) {
Log.i(bg.toString(), bg.getUuid().toString());
if (UUID_MSA_APP.equals(bg.getUuid())) {
Log.i("MSA APP", "found");
BluetoothGattCharacteristic msacode = bg.getCharacteristics().get(0);
//gatt.setCharacteristicNotification(msacode, true);
gatt.readCharacteristic(msacode);
Log.i("BLE", "**** BluetoothGattCharacteristic msacode: " + msacode.toString());
}
else{
Log.i("MSA APP", "UUID_MSA_APP not Matching found");
}
}
}
catch(Exception ex){
Log.i("msable","[@@MA] ::::Exception 8" +ex.toString());
mSecurityCode.setText("[@@MA]Ex8" + ex.toString());
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic
characteristic, int status) {
try {
Log.i("BLE","**** onCharacteristicRead Status: "+status);
final byte[] data = characteristic.getValue();
if (data != null && data.length > 0) {
final StringBuilder stringBuilder = new StringBuilder(data.length);
for (byte byteChar : data)
stringBuilder.append(String.format("%02X ", byteChar));
Log.i("onCharacteristicRead", new String(data));
runOnUiThread(new Runnable() {
@Override
public void run() {
mSecurityCode.setText(new String(data));
Intent intent = new Intent(MainActivity.this, newActivity.class);
intent.putExtra("UniqueCode", new String(data));
startActivity(intent);
}
});
}
gatt.disconnect();
}
catch(Exception ex){
Log.i("msable","[@@MA] ::::Exception 9" +ex.toString());
mSecurityCode.setText("[@@MA]Ex9" + ex.toString());
}
}
};
}
最佳答案
在回调中需要给 Intent 一个静态上下文并且必须设置 Intent FLAG_ACTIVITY_NEW_TASK 标志。
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic
characteristic, int status) {
try {
//Reads the requested characteristic and get the characteristic value.
final byte[] data = characteristic.getValue();
if (data != null && data.length > 0) {
final StringBuilder stringBuilder = new StringBuilder(data.length);
for (byte byteChar : data)
stringBuilder.append(String.format("%02X ", byteChar));
Intent intent = new Intent(callBackContext, InOutActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
callBackContext.startActivity(intent);
}
}
catch(Exception ex){
dbObj.PutLog("[@@MA]EX7" + ex.toString());
}
finally{
if(gatt != null){
dbObj.PutLog("[MA] 5 CLOSE GATT");
gatt.disconnect();
gatt.close();
}
}
}
};
这里 callBackContext.startActivity(intent); 是给 intent 的静态上下文。这解决了我的目的
关于java - 蓝牙回调函数 onCharacteristicRead 没有对使用 <API 21 的另一个 Activity 进行 Intent 调用。不在 Marshmallow 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39762963/
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我有一个奇怪的问题:我在rvm上安装了rubyonrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
这是一道面试题,我没有答对,但还是很好奇怎么解。你有N个人的大家庭,分别是1,2,3,...,N岁。你想给你的大家庭拍张照片。所有的家庭成员都排成一排。“我是家里的friend,建议家庭成员安排如下:”1岁的家庭成员坐在这一排的最左边。每两个坐在一起的家庭成员的年龄相差不得超过2岁。输入:整数N,1≤N≤55。输出:摄影师可以拍摄的照片数量。示例->输入:4,输出:4符合条件的数组:[1,2,3,4][1,2,4,3][1,3,2,4][1,3,4,2]另一个例子:输入:5输出:6符合条件的数组:[1,2,3,4,5][1,2,3,5,4][1,2,4,3,5][1,2,4,5,3][
我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r