Showing posts with label step-by-step series. Show all posts
Showing posts with label step-by-step series. Show all posts

Bluetooth LE Gatt Example, step-by-step

Last post demonstrate the Android Bluetooth Le Gatt example code with Arduino/Genuino 101. This post start to (TRY to) implement my own Bluetooth LE Gatt Example, step-by-step. The aim of the examples (in coming series) are scan BLE device, find and link with specified device Genuino 101 (programmed with "LEDCB", refer previous post), and read and write characteristic of the device to turn ON/OFF the Genuino 101 on-board LED.

The main reference material are:
- Android Developers Guide > Bluetooth Low Energy
- The Android example code - BluetoothLeGatt. (The example in last post)

In this first step, create a new project in Android Studio, named AndroidBleGatt.

In my example (in coming post) I will scan LE device using BluetoothLeScanner (Added in API level 21) instead of calling deprecated startLeScan() and stopLeScan() methods as in the BluetoothLeGatt example, so specify the Min Sdk Version of API 21.

Edit AndroidManifest.xml to add uses-feature of "android.hardware.bluetooth_le", uses-permission of "android.permission.BLUETOOTH", "android.permission.BLUETOOTH_ADMIN" and "android.permission.ACCESS_COARSE_LOCATION".

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.blogspot.android_er.androidblegatt">

<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>


<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>

Edit MainActivity.java
package com.blogspot.android_er.androidblegatt;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

private BluetoothAdapter mBluetoothAdapter;
private BluetoothLeScanner mBluetoothLeScanner;

private boolean mScanning;

private static final int RQS_ENABLE_BLUETOOTH = 1;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// Check if BLE is supported on the device.
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this,
"BLUETOOTH_LE not supported in this device!",
Toast.LENGTH_SHORT).show();
finish();
}

getBluetoothAdapterAndLeScanner();

// Checks if Bluetooth is supported on the device.
if (mBluetoothAdapter == null) {
Toast.makeText(this,
"bluetoothManager.getAdapter()==null",
Toast.LENGTH_SHORT).show();
finish();
return;
}

}

@Override
protected void onResume() {
super.onResume();

if (!mBluetoothAdapter.isEnabled()) {
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, RQS_ENABLE_BLUETOOTH);
}
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if (requestCode == RQS_ENABLE_BLUETOOTH && resultCode == Activity.RESULT_CANCELED) {
finish();
return;
}

getBluetoothAdapterAndLeScanner();

// Checks if Bluetooth is supported on the device.
if (mBluetoothAdapter == null) {
Toast.makeText(this,
"bluetoothManager.getAdapter()==null",
Toast.LENGTH_SHORT).show();
finish();
return;
}

super.onActivityResult(requestCode, resultCode, data);
}

private void getBluetoothAdapterAndLeScanner(){
// Get BluetoothAdapter and BluetoothLeScanner.
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();

mScanning = false;
}
}



Up to here, the app simple check Bluetooth LE available and enable it. In next post, I will show how to scan available Bluetooth LE devices in range.

Next:
- Bluetooth LE Gatt Example, scan BLE devices
- Scan specified BLE devices with ScanFilter
- Connect to Bluetooth LE device and display GATT Services



Load Here map image, using REST API

This example show how to load Here map image, using REST API (not Native SDK). HERE, a Nokia company, is a global leader in the mapping and location intelligence business.



The Here Map Image API Developer's Quick Start Guide provide information to help you start using the Map Image API.

app_id and app_code are authentication credentials. You can use the demo credentials in the examples for testing, but must substitute them with your own unique values in your website or application. See Acquiring Credentials for more information.

MainActivity.java
package com.example.androidhererestmapimage;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import android.support.v7.app.ActionBarActivity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ImageView;

public class MainActivity extends ActionBarActivity {

public class LoadHereMapTask extends AsyncTask<URL, Void, Bitmap> {

ImageView imageView;

LoadHereMapTask(ImageView v){
imageView = v;
}

@Override
protected Bitmap doInBackground(URL... params) {
Bitmap bm = null;
URL urlMapImage = params[0];
try {
bm = BitmapFactory.decodeStream(urlMapImage.openConnection().getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bm;
}

@Override
protected void onPostExecute(Bitmap result) {
imageView.setImageBitmap(result);
}

}

ImageView mapImage;
LoadHereMapTask loadHereMapTask;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mapImage = (ImageView)findViewById(R.id.mapimage);

loadHereMapTask = new LoadHereMapTask(mapImage);

URL urlTarget;
try {
urlTarget = new URL(genHereMapImageRequest());
loadHereMapTask.execute(urlTarget);
} catch (MalformedURLException e) {
e.printStackTrace();
}

}

private String genHereMapImageRequest(){

String BaseURL = "http://image.maps.cit.api.here.com";
String Path = "/mia/1.6/";
String Resource = "mapview";
String ApplicationId = "DemoAppId01082013GAL"; //for demo
String ApplicationCode = "AJKnXv84fjrb0KIHawS0Tg"; //for demo
String location = "52.378,13.520"; //Berlin

String rqs = BaseURL + Path + Resource
+ "?app_id=" + ApplicationId
+ "&app_code=" + ApplicationCode
+ "&c=" + location;

return rqs;
}

}

/res/layout/activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.example.androidhererestmapimage.MainActivity" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<ImageView
android:id="@+id/mapimage"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</LinearLayout>

uses-permission of "android.permission.INTERNET" is needed in AndroidManifest.xml.

download filesDownload the files.

More examples:
- Here REST API example, set zoom level
- Using Here Map Tile REST API on Android
- Base Map, Aerial and Traffic Tile
- Using Here Geocoder API on Android
- Search and display Map Tile using Here REST API

Something about processing images in Android

I will do some trial experience about image in Android programming. The list here will be updated once posted.

Related demo video:

The exercises have not take care the bitmap size, and any resizing. So don't test with big picture, otherwise OutOfMemoryError or "Bitmap too large to be uploaded into a texture" will happen.

YouTube Android Player API step-by-step

The YouTube Android Player API enables you to incorporate video playback functionality into your Android applications. The API defines methods for loading and playing YouTube videos (and playlists) and for customizing and controlling the video playback experience.

Using the API, you can load or cue videos into a player view embedded in your application's UI. You can then control playback programmatically. For example, you can play, pause, or seek to a specific point in the currently loaded video.

You can also register event listeners to get callbacks for certain events, such as the player loading a video or the player state changing. Finally, the API has helper functionality to support orientation changes as well as transitions to fullscreen playback.






Develop Android App with YouTube Android Player API step-by-step:

Related: