I used accessibility service to get all texts on screen. After minutes working normally, it caused ANR with some GC allocated... logs and few seconds after, it crashed with this error:
#Override
public void onAccessibilityEvent(final AccessibilityEvent event) {
try {
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (powerManager == null || !powerManager.isInteractive()) {
return;
}
if (FirebaseAuth.getInstance().getCurrentUser() == null) return;
CharSequence eventPackageName = event.getPackageName();
if (eventPackageName != null) {
if (eventPackageName.equals(BuildConfig.APPLICATION_ID)) return;
if (eventPackageName.equals(getCurrentKeyboardPackageName())) return;
int eventType = event.getEventType();
if (eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED || eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
AccessibilityNodeInfo mNodeInfo = event.getSource();
StringBuilder stringBuilder = new StringBuilder("");
getAllTextViews(mNodeInfo, stringBuilder);
String value = stringBuilder.toString().replace('\n', ' ').replaceAll(" +", " ");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
My getAllTextViews() method:
private void getAllTextViews(AccessibilityNodeInfo nodeInfo, StringBuilder stringBuilder) {
if (nodeInfo == null) return;
if (!TextUtils.isEmpty(nodeInfo.getText())) {
stringBuilder.append(" " + nodeInfo.getText());
}
for (int i = 0; i < nodeInfo.getChildCount(); i++) {
getAllTextViews(nodeInfo.getChild(i), stringBuilder);
}
}
Any help will be appreciated. Thank a lot!
What you need is to use recycle() method of AccessibilityNodeInfo after info is used.
Related
I try to using FingerPrint API to build a demo,like this:
if (fingerprintManager.hasEnrolledFingerprints()) {
// start fingerprint auth here.
try {
// CryptoObjectHelper cryptoObjectHelper = new CryptoObjectHelper();
if (cancellationSignal == null) {
cancellationSignal = new CancellationSignal();
}
if (cancellationSignal.isCanceled()) {
cancellationSignal = new CancellationSignal();
}
myAuthCallback = new MyAuthCallback(context, handler);
fingerprintManager.authenticate(null, cancellationSignal, 0, myAuthCallback, null);
} catch (Exception e) {
}
}
and it works in an Activity Component,I can distinguish my fingerprints.
But when I try to using these codes working with a Service or a BroadcastReciver Component, I cannot receive any callback,is it right that FingerPrint API can use in Activity Component only ?why is that?
I have found out the answer from the source code,
/frameworks/base/services/core/java/com/android/server/fingerprint/Fingerprint/FingerprintService.java
#Override // Binder call
public void authenticate(final IBinder token, final long opId, final int groupId,
final IFingerprintServiceReceiver receiver, final int flags,
final String opPackageName) {
if (!canUseFingerprint(opPackageName, true /* foregroundOnly */)) {
if (DEBUG) Slog.v(TAG, "authenticate(): reject " + opPackageName);
return;
}
……
private boolean canUseFingerprint(String opPackageName, boolean foregroundOnly) {
checkPermission(USE_FINGERPRINT);
final int uid = Binder.getCallingUid();
final int pid = Binder.getCallingPid();
if (opPackageName.equals(mKeyguardPackage)) {
return true; // Keyguard is always allowed
}
if (!isCurrentUserOrProfile(UserHandle.getCallingUserId())) {
Slog.w(TAG,"Rejecting " + opPackageName + " ; not a current user or profile");
return false;
}
if (mAppOps.noteOp(AppOpsManager.OP_USE_FINGERPRINT, uid, opPackageName)
!= AppOpsManager.MODE_ALLOWED) {
Slog.w(TAG, "Rejecting " + opPackageName + " ; permission denied");
return false;
}
if (foregroundOnly && !isForegroundActivity(uid, pid)) {
Slog.w(TAG, "Rejecting " + opPackageName + " ; not in foreground");
return false;
}
return true;
}
private boolean isForegroundActivity(int uid, int pid) {
try {
List<RunningAppProcessInfo> procs =
ActivityManagerNative.getDefault().getRunningAppProcesses();
int N = procs.size();
for (int i = 0; i < N; i++) {
RunningAppProcessInfo proc = procs.get(i);
if (proc.pid == pid && proc.uid == uid
&& proc.importance == IMPORTANCE_FOREGROUND) {
return true;
}
}
} catch (RemoteException e) {
Slog.w(TAG, "am.getRunningAppProcesses() failed");
}
return false;
}
It is asked for a foreground activity to authenticate!!
Downloading to internal storage works.
However, when I try to download to the external sdcard, then status doesn't update until after 2~3 minutes. (Meaning I get 0 bytes downloaded from cursor.getLong(cursor
.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));).
It eventually downloads after 2~3 minutes.
The notification status also says 0%
private void addToDownloadManager(String sourcePath, String destFolder, String deskFileName, DownloadManager downloadManager) {
try {
if(sourcePath == null || sourcePath.equals(""))
return;
try {
File folder = new File(destFolder);
if (!folder.exists()) {
folder.mkdirs();
}
}catch (Exception e) {
}
Uri Download_Uri = Uri.parse(sourcePath);
DownloadManager.Request request = new DownloadManager.Request(Download_Uri);
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
request.setAllowedOverRoaming(false);
request.setTitle("title");
request.setDescription("description");
File destination = new File(destFolder, deskFileName);
request.setDestinationUri(Uri.fromFile(destination));
downloadReference = downloadManager.enqueue(request);
} catch (Exception e) {
}
}
private Timer mDownloadStatusTimer;
public void downloadStatusTimerSchedule() {
if (mDownloadStatusTimer != null)
downloadStatusTimerCancel();
try {
mDownloadStatusTimer = new Timer("DownloadStatusTimer");
DownloadStatusTimer timer = new DownloadStatusTimer();
mDownloadStatusTimer.schedule(timer, 500, 500); // 0.5 second
} catch (Exception e) {
}
}
public void downloadStatusTimerCancel() {
if (mDownloadStatusTimer != null) {
mDownloadStatusTimer.cancel();
mDownloadStatusTimer.purge();
mDownloadStatusTimer = null;
}
}
private long bytes_downloaded = 0;
private long bytes_total = 0;
public class DownloadStatusTimer extends TimerTask {
#Override
public void run() {
if (mDownloadManager != null) {
DownloadManager.Query myDownloadQuery = new DownloadManager.Query();
Cursor cursor = mDownloadManager.query(myDownloadQuery);
bytes_downloaded = 0;
bytes_total = 0;
try {
if (cursor != null && cursor.moveToFirst()) {
try {
// Get downloaded size/total size
if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL ||
cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_FAILED) {
// do nothing
} else {
bytes_downloaded += cursor.getLong(cursor
.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
bytes_total += cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
}
} catch (Exception e) {
}
while (cursor != null && cursor.moveToNext()) {
try {
// Get downloaded size/total size
if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL ||
cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_FAILED) {
// do nothing
} else {
bytes_downloaded += cursor.getLong(cursor
.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
bytes_total += cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
}
} catch (Exception e) {
}
}
} else {
}
} catch (Exception e) {
} finally {
if (cursor != null) {
cursor.close();
}
}
Log.e("test", "Download size: " + bytes_downloaded + " / " + bytes_total);
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
try {
tv_download_status.setText("Download size: " + bytes_downloaded + " / " + bytes_total);
} catch (Exception e) {
}
}
});
}
}
}
I tested Note 4 and Galaxy S5 and they seems to be fine.
Could it be Android 6.0 thing? or S7?
Is it a bug? Or is there anything I am doing wrong here?
If you want to test it yourself, here's the project with source code:
https://drive.google.com/open?id=0BygTefPD845LTkp5QU1mOHRkMDQ
Here's APK to test:
https://drive.google.com/open?id=0By...Ec1ZHk5ZWRkWWc
[Edit]
My destination location is: /storage/806E-1A11/Android/data/com.joshua.externalsddownloadtest/files/download/video.mp4
Source is: http://downloads.4ksamples.com/downloads/[2160p]%204K-HD.Club-2013-Taipei%20101%20Fireworks%20Trailer%20(4ksamples.com).mp4
(I got the URL from the Mp4 Sample website)
File[] files = ContextCompat.getExternalFilesDirs(MainActivity.this, null);
destFolder = null;
for(int i=0; i< files.length; i++) {
if (!files[i].getAbsolutePath().equals(MainActivity.this.getExternalFilesDir(null).getPath())) {
destFolder = files[i].getAbsolutePath();
break;
}
}
boolean bDownloadToExternal = false;
if(destFolder == null) {
tv_download_destination.setText("No external storage found");
} else {
destFolder += "/download/";
tv_download_destination.setText("Destination location: " + destFolder + fileName);
bDownloadToExternal = true;
}
I think its about new permission system at android 6.
You should ask permissions in runtime like:
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != getPackageManager().PERMISSION_GRANTED){
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, YOUR_CONST_REQUEST_CODE);
}
}
And implement listener
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case YOUR_CONST_REQUEST_CODE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// invoke your download method
} else {
// if permissions was not granted
}
}
}
}
Other way you can set targetSdkVersion less then 23 in gradle file.
More about new permission system you can read here Android.com
Hi just want to cast an audio mp3 file by given url from my phone. in my Application i started the casting method when connection is established that means after calling of setSelection method and initialized the GoogleApiClient instance. but casting is not happen, whether am i doing correct way or not if not, then when do i start the casting. Please guide me to start the casting and their life cycles.
Thanks in Advance.
My Code Part is
private void setSelectedDevice(CastDevice device) {
Log.d(Tag, "setSelectedDevice: " + device);
mSelectedDevice = device;
if (mSelectedDevice != null) {
try {
disconnectApiClient();
connectApiClient();
} catch (IllegalStateException e) {
Log.w(Tag, "Exception while connecting API client", e);
disconnectApiClient();
}
} else {
if (mApiClient != null) {
if (mApiClient.isConnected()) {
if (mRemoteMediaPlayer != null && isPlaying) {
mRemoteMediaPlayer.pause(mApiClient);
}
}
disconnectApiClient();
}
mMediaRouter.selectRoute(mMediaRouter.getDefaultRoute());
}
}
private void connectApiClient() {
Cast.CastOptions apiOptions = Cast.CastOptions.builder(mSelectedDevice,
mCastListener).build();
mApiClient = new GoogleApiClient.Builder(this)
.addApi(Cast.API, apiOptions)
.addConnectionCallbacks(mConnectionCallbacks)
.addOnConnectionFailedListener(mConnectionFailedListener)
.build();
// Start the casting when connected the route device // here i am start the casting....
if(songURL != null){
Log.d(Tag, "Current casting url:" + songURL);
isPlaying = false;
firstTimeCasting = true;
SynchwithChromeCast(songURL); // here load the song url with remoteplayer
//Play(songURL);
}
}
private void SynchwithChromeCast(String file){
if(firstTimeCasting){
firstTimeCasting = false;
try {
Log.e("Play Testing", "mRemoteMediaPlayer is play");
if(firstTimeCasting){
firstTimeCasting = false;
//mRemoteMediaPlayer = new RemoteMediaPlayer();
isPlaying = true;
MediaMetadata mediaMetadata = new MediaMetadata(
MediaMetadata.MEDIA_TYPE_MUSIC_TRACK);
mediaMetadata.putString(MediaMetadata.KEY_ALBUM_ARTIST,
"" +singers.getText().toString());
mediaMetadata.putString(mediaMetadata.KEY_ALBUM_TITLE,
"" +songTitle.getText().toString());
MediaInfo mediaInfo = new MediaInfo.Builder(file)
.setContentType("audio/mp3")
.setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
.setMetadata(mediaMetadata).build();
mRemoteMediaPlayer
.load(mApiClient, mediaInfo, true)
.setResultCallback(
new ResultCallback<RemoteMediaPlayer.MediaChannelResult>() {
#Override
public void onResult(
MediaChannelResult result) {
if (result.getStatus().isSuccess()) {
Log.d(Tag, "Media loaded Successfully" + result.getStatus());
}
else{
Log.d(Tag, "Media loaded Not Successfully" + result.getStatus());
}
}
});
}
} catch (IllegalStateException e) {
Log.e(Tag, e.getMessage());
} catch (Exception e) {
// TODO: handle exception
Log.e(Tag, e.getMessage());
}
}
}
// activate play button
play.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
// disable the button
if (PlusUtilities.isInternetConnected()) {
play.setEnabled(false);
// if mediaplayer is in pause state
if (mp != null & !mp.isPlaying()) {
mp.seekTo(mp.getCurrentPosition());
playSong(false);
updateProgressBar();
// Interact with Chrome-cast while play/pause ////////
//reset
firstTimeCasting = false;
isPlaying = true;
Play(songURL); // Play or Pause the chromecast receiver
}
else if (mp != null) {
playSong(true);
//if(songURL != null)
isPlaying = false;
Play(songURL);
}
});
private void Play(String file) {
if (mp != null && isPlaying) {
if (mApiClient != null) {
Log.e("Play **********", mApiClient.isConnected() + " ++++++++Status");
if (mApiClient.isConnected()) {
if (mRemoteMediaPlayer != null) {
mRemoteMediaPlayer.pause(mApiClient);
}
}
}
} else if (mp != null && !isPlaying && !firstTimeCasting) {
if (mApiClient != null) {
if (mApiClient.isConnected()) {
if (mRemoteMediaPlayer != null) {
mRemoteMediaPlayer.play(mApiClient);
}
}
}
}
}
You can look at a number of samples that we have on GitHub to see how the flow should be; it is an asynchronous set of calls, so
After calling connect, you wait for onConnected to be called, that signals a connection
Then you load the "application" using the app id that you were assigned on Developer Console or the default app id
When application is launched successfully, you then load the media and then you can play or do as you wish.
Read our documentation.
I am using this ndeftools library to communicate with the NFC hardware. It works fine except for one issue where right after the app is installed, the NFC doesn't seem to want to return anything. It makes the NFC sound like it is scanning the NFC tag, but nothing else happens. If I exit my app and scan the tag, the native NFC app is activated like usual. Once the device is restarted, NFC function is restored to my app from then on. I was wondering if anyone has ran into this issue. Any help would be appreciated.
EDIT: I'm including the code that I use to interface with the NFC library. For reading tags, I just use enableForegroundMode() and it works for the most part except for this one scenario right after install. Is there more I should be doing?
public class NfcHelper {
private final String TAG = NfcHelper.class.getSimpleName();
protected NfcAdapter m_NFCAdapter;
protected PendingIntent m_NFCPendingIntent;
private Context m_Context = null;
public NfcHelper(Context p_Context) {
m_Context = p_Context;
m_NFCAdapter = NfcAdapter.getDefaultAdapter(m_Context);
m_NFCPendingIntent = PendingIntent.getActivity(m_Context, 0, new Intent(m_Context, m_Context.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
}
public void disableForegroundMode() {
Log.i(TAG, "disableForegroundMode");
m_NFCAdapter.disableForegroundDispatch((Activity) m_Context);
}
public void enableForegroundMode() {
Log.i(TAG, "enableForegroundMode");
// foreground mode gives the current active application priority for reading scanned tags
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED); // filter for tags
IntentFilter[] writeTagFilters = new IntentFilter[] {tagDetected};
m_NFCAdapter.enableForegroundDispatch((Activity) m_Context, m_NFCPendingIntent, writeTagFilters, null);
}
public NfcAdapter getNFCAdapter() {
return m_NFCAdapter;
}
public SimpleEntry<String, String> getNFCData(Intent p_intent) {
Log.i(TAG, "getNFCData");
byte[] arrTagSerial = null;
String sTagSerial = "";
String sTagContent = "";
try {
// check for NFC related actions
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(p_intent.getAction())) {
arrTagSerial = p_intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
sTagSerial = new BigInteger(arrTagSerial).toString(16);
Parcelable[] messages = p_intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages != null) {
Log.d(TAG, "Found " + messages.length + " NDEF messages");
//vibrate();
// parse to records
for (int i = 0; i < messages.length; i++) {
try {
List<Record> records = new Message((NdefMessage)messages[i]);
Log.d(TAG, "Found " + records.size() + " records in message " + i);
for(int k = 0; k < records.size(); k++) {
Log.d(TAG, " Record #" + k + " is of class " + records.get(k).getClass().getSimpleName());
Record record = records.get(k);
if (record instanceof TextRecord) {
TextRecord txtrecord = (TextRecord) records.get(k);
sTagContent = txtrecord.getText();
}
else if(record instanceof AndroidApplicationRecord) {
AndroidApplicationRecord aar = (AndroidApplicationRecord)record;
Log.d(TAG, "Package is " + aar.getPackageName());
}
}
}
catch (Exception e) {
Log.e(TAG, "Problem parsing message", e);
}
}
}
} else {
// ignore
}
}
catch (Exception ex) {
ex.printStackTrace();
}
return new SimpleEntry<String, String>(sTagSerial, sTagContent);
}
public boolean writeText(String text, Intent intent) {
Message message = new Message();
org.ndeftools.wellknown.TextRecord textRecord = new org.ndeftools.wellknown.TextRecord();
try {
textRecord.setText(text);
textRecord.setEncoding(Charset.forName("UTF-8"));
textRecord.setLocale(Locale.ENGLISH);
message.add(textRecord);
return writeMessage(message, intent);
}
catch (Exception ex) {
ex.printStackTrace();
return false;
}
}
public boolean writeMessage(Message message, Intent intent) {
return writeMessage(message.getNdefMessage(), intent);
}
public boolean writeMessage(NdefMessage rawMessage, Intent intent) {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
NdefFormatable format = NdefFormatable.get(tag);
if (format != null) {
Log.d(TAG, "Write unformatted tag");
try {
format.connect();
format.format(rawMessage);
//writeNdefSuccess();
return true;
}
catch (Exception e) {
//writeNdefFailed(e);
}
finally {
try {
format.close();
}
catch (IOException e) {
// ignore
}
}
Log.d(TAG, "Cannot write unformatted tag");
}
else {
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
try {
Log.d(TAG, "Write formatted tag");
ndef.connect();
if (!ndef.isWritable()) {
Log.d(TAG, "Tag is not writeable");
//writeNdefNotWritable();
return false;
}
if (ndef.getMaxSize() < rawMessage.toByteArray().length) {
Log.d(TAG,
"Tag size is too small, have "
+ ndef.getMaxSize() + ", need "
+ rawMessage.toByteArray().length);
//writeNdefTooSmall(rawMessage.toByteArray().length, ndef.getMaxSize());
return false;
}
ndef.writeNdefMessage(rawMessage);
//writeNdefSuccess();
return true;
}
catch (Exception e) {
//writeNdefFailed(e);
}
finally {
try {
ndef.close();
}
catch (IOException e) {
// ignore
}
}
}
else {
//writeNdefCannotWriteTech();
}
Log.d(TAG, "Cannot write formatted tag");
}
return false;
}
public int getMaxNdefSize(Intent intent) {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
NdefFormatable format = NdefFormatable.get(tag);
if (format != null) {
Log.d(TAG, "Format tag with empty message");
try {
if (!format.isConnected()) {
format.connect();
}
format.format(new NdefMessage(new NdefRecord[0]));
}
catch (Exception e) {
Log.d(TAG, "Problem checking tag size", e);
return -1;
}
}
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
try {
if (!ndef.isConnected()) {
ndef.connect();
}
if (!ndef.isWritable()) {
Log.d(TAG, "Capacity of non-writeable tag is zero");
//writeNdefNotWritable();
return 0;
}
int maxSize = ndef.getMaxSize();
ndef.close();
return maxSize;
}
catch (Exception e) {
Log.d(TAG, "Problem checking tag size", e);
}
}
else {
//writeNdefCannotWriteTech();
}
Log.d(TAG, "Cannot get size of tag");
return -1;
}
}
EDIT2: Here is the code of my Activity that uses the NfcHelper:
private NfcHelper mNFC = new NfcHelper(this);
#Override
public void onNewIntent(Intent intent) {
SimpleEntry<String, String> NFCData = null;
// If intent from NFC tag scan
if (intent.getAction() != null &&
intent.getAction().equals(NfcAdapter.ACTION_TAG_DISCOVERED)) {
NFCData = mNFC.getNFCData(intent);
// Do stuff with NFC data
}
}
#Override
protected void onResume() {
super.onResume();
mNFC.enableForegroundMode();
}
#Override
protected void onPause() {
super.onResume();
mNFC.disableForegroundMode();
}
How to write all writeCharacteristics in a loop in ble in android.code is as follows
in this method i pass 3 writecharacteristic() and only one is write and others are ignored.
if (beartoggle.isChecked()) {
if (mDeviceLight.equalsIgnoreCase("on") && mDeviceAlarm.equalsIgnoreCase("on")) {
byte[] val = {1};
if (check_port_1 == 1) {
mBluetoothLeService.writeCharacteristic(val, 1);
}
if (check_port_2 == 1) {
mBluetoothLeService.writeCharacteristic(val, 2);
}
if (find_me == 1) {
mBluetoothLeService.writeCharacteristic(val, 3);
}
}
}
and someone is saying use public void onReliableWriteCompleted() and check if port1 is written then go to port2 and then findme. This method will help me, if yes then how ? Please send me clear details and following is my writeCharacteristic()
public boolean writeCharacteristic(byte value[], int type) {
//check mBluetoothGatt is available
if (mBluetoothGatt == null) {
Log.e(TAG, "lost connection");
return false;
}
BluetoothGattService Service = mBluetoothGatt.getService(UUID_SIMPLESERVICE);
if (Service == null) {
Log.e(TAG, "service not found!");
return false;
}
BluetoothGattCharacteristic charac1 = null;
BluetoothGattCharacteristic charac2 = null;
BluetoothGattCharacteristic charac3 = null;
boolean status1 = false, status2 = false, status3 = false;
Log.v("___TYPE___", "________1______________" + (type == 1));
Log.v("___TYPE___", "________2______________" + (type == 2));
Log.v("___TYPE___", "________3______________" + (type == 3));
onReliableWriteCompleted(status1);
onReliableWriteCompleted(status2);
onReliableWriteCompleted(status3);
if (type == 1) {
charac1 = Service.getCharacteristic(UUID_PORT1);
charac1.setValue(value);
status1 = mBluetoothGatt.writeCharacteristic(charac1);
Log.v("________BLESERVICE____", "___WRITE CHARATERISTICS STATUS:_________" + status1);
onReliableWriteCompleted(status1);
} else if (type == 2) {
charac2 = Service.getCharacteristic(UUID_PORT2);
charac2.setValue(value);
status2 = mBluetoothGatt.writeCharacteristic(charac2);
onReliableWriteCompleted(status2);
Log.v("________BLESERVICE_______", "___WRITE CHARACTERISTICS STATUS_______" + status2);
} else if (type == 3) {
charac3 = Service.getCharacteristic(UUID_FINDME);
charac3.setValue(value);
status3 = mBluetoothGatt.writeCharacteristic(charac3);
onReliableWriteCompleted(status3);
Log.v("__________BLESERVICE_________", "___WRITE CHARACTERISTICS STATUS_____" + status3);
}
if (charac1 == null && charac2 == null && charac3 == null) {
Log.e(TAG, "char not found!");
return false;
}
Log.v("___TYPE___", "______________________" + type);
return status1 && status2 && status3;
}
call BluetoothLeService.getSupportedGattServices(), you will get a list of services. Iterate through it and call BluetoothGattService.getCharacteristics(). You will again get a list, you can iterate through it.
For more info, you can refer this