Android version: Android 5.1.x
Kernel Version: 3.4.67
Base : CyanogrnMod 12.1
CM12 Theme Engine
Status Bar
-Clock & Date Options
-Battery Options
-Battery Bar Options
-SuperUser Indicator
-Bluetooth Indicator
-Brightness Control
-Mobile & Wifi Icon Options
-Notification & System Icon Options
-Network Traffic Monitor
-Breathing Notifications
-Bliss Logo Option
-Notification Count
Navigation & Button Options
-Set Navigation Ring Targets
-Backlight Brightness & Timeout
-Overflow Button Settings
-Navigation Bar Toggle
-Set Navigation Buttons, Layout & Dimension
-Double Tap to Sleep
-Power Button End Call Option
-Home Button Options
-Back Button Wake Up Option
-Menu Button Options
-Search Button Options
-Left-Handed Mode
Recents Options
-Memory Bar
-Clear All Button Tweaks
-Clear All tasks
-Clear All Recents Location
-Option to show Google search bar in recents Menu
-OmniSwitch (Option to replace recents menu with Omniswitch)
Notification Drawer
-Status Bar Header (Weather)
-Tile Options
-Flashlight Option
-Custom Color Tile Options (Set Background, Icons & Text)
-Quick Setting Options
-Quick & Smart Pulldown
-Brightness Slider Toggle
-Vibrate, Detailed Wifi View & Advanced Location Options
-SlimActions Tile
-Auto Close Panel
-Force Expanded Notifications
Heads Up Notifications
Lockscreen Options
-Long Press Lock Icon to Sleep
-Shortcuts
-Bottom Corner Targets
-Weather Options
-Customize Text & Icon Colors
-Clock Widget Settings
-Music Visualizer Options
-Power Button Lock Options
-Lock Method Options
Power Menu Options
-Power Off
-Reboot
-One Click Reboot
-Screenshot (with delay option)
-Screen Record
-Profile Switcher
-Airplane Mode
-User Switcher
-Settings Shortcut
-Device Lockdown
-Bug Reporting
-Sound Panel
Gesture Anywhere
-Location Options
-Trigger Regions
Animations
-IME Animations
-Toast Animations
-Listview Animations
-System Animations
-Scrolling Cache
-Scrolling Modifiers
App Circle Bar
-Included Apps
-Trigger width, position and height
Sound Options
-Link Ringtone & Notification Toggle
-Media, Alarm, Ring & Notification Sound Options
-Volume Steps
-Volume Panel Timeout
-Interruptions
-Launch Music Apps
-Dial Pad Tones
-Screen Locking Sound
-Touch Sounds
-Charging Sounds
-Camera Shutter & Screenshot Sounds
-Safe Headset Volume
-Less Frequent Notifications
-Media Control
-Vibration Options
Display & Light Options
-Smart Cover
-Adaptive Brightness
-LiveDisplay
-Rotation
-Double Tap to Sleep
-Sleep Time
-Wake on Plug
-Cast Screen
-Expanded Desktop
-Daydream
-Font Size
-DPI
-Battery Light
-Notification Light with Per App Settings
Notification Manager
-Device Lock Options
-Block App Notifications
-Disable Persistent Info
-Priority App Notifications
Kernel Options
-Governors
preservative
yankactive
ragingmolasses
xperience
tripndroid
darkness
barry_allen
alucard
zzmoove
wheatley
nightmare
intelliactive
hyper
hellsactive
elementalx
dancedance
conservative
blu_active
wave
performance
lionheart
bioshock
MSM LIMITER
uc/oc 35MHz to 2899MHz
power-efficient Workqueues
-Hotplugs
Intelliplug
Bricked hotplug
Alucard hotplug
Mako hotplug
-Thermal
Intellithermal
Adjustable voltages
-I/O schedulers
-deadline
-row
-sioplus
-sio
-cfq
-bfq
-fiops
-zen
-tripndroid
-vr
GPU
Simple Ondemand
uc/ov 110MHz to 700MHz
-Kcal control
-Faux sound
-Wake Gestures
TCP congestion control
htcp
reno
bic
cdg
cubic
westwood
highspeed
hybla
vegas
veno
scalable
lp
yeah
illinois
Power Suspend mode
kernel mode
user mode
LCD hooks
Highest Level Hook
-UKSM
-Low Memory Killer
AudioFX Equalizer
Bugs:
USSD
Hotspot
DOWNLOAD
BlissPop-v4.0_H870 v1.03 by Harry_ET.zip
gapps-L-4-21-15.zip
ROM OS Version: 5.1.x Lollipop
ROM Kernel: Linux 3.4.x
Version Information
Status: Nigtly
Created 2015-10-27
Last Updated 2015-10-27
Credits:
Tran Tien XDA Dev
SuperSU
BlissPOP Team
Me for Porting
Custom InfoWindow for Google Maps Android API v2
To create Custom InfoWindow for Google Maps Android API v2:
- Make your Activity implements GoogleMap.InfoWindowAdapter.
- Override getInfoWindow(Marker marker) and getInfoContents(Marker marker).
The API will first call getInfoWindow(Marker) and if null is returned, it will then call getInfoContents(Marker). If this also returns null, then the default info window will be used.
The first of these (getInfoWindow()) allows you to provide a view that will be used for the entire info window. The second of these (getInfoContents()) allows you to just customize the contents of the window but still keep the default info window frame and background.
- setInfoWindowAdapter(this).
Modify MapsActivity.java from last example "Make GoogleMap's marker draggabe and detect moving marker".
package com.blogspot.android_er.androidstudiomapapp;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.InputType;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback,
GoogleMap.OnMapClickListener, GoogleMap.OnMapLongClickListener,
GoogleMap.OnMarkerDragListener, GoogleMap.InfoWindowAdapter {
private GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setOnMapClickListener(this);
mMap.setOnMapLongClickListener(this);
mMap.setOnMarkerDragListener(this);
mMap.setInfoWindowAdapter(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_addmarkers:
addMarker();
return true;
case R.id.maptypeHYBRID:
if(mMap != null){
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
return true;
}
case R.id.maptypeNONE:
if(mMap != null){
mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
return true;
}
case R.id.maptypeNORMAL:
if(mMap != null){
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
return true;
}
case R.id.maptypeSATELLITE:
if(mMap != null){
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
return true;
}
case R.id.maptypeTERRAIN:
if(mMap != null){
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
return true;
}
case R.id.menu_legalnotices:
String LicenseInfo = GoogleApiAvailability
.getInstance()
.getOpenSourceSoftwareLicenseInfo(MapsActivity.this);
AlertDialog.Builder LicenseDialog =
new AlertDialog.Builder(MapsActivity.this);
LicenseDialog.setTitle("Legal Notices");
LicenseDialog.setMessage(LicenseInfo);
LicenseDialog.show();
return true;
case R.id.menu_about:
AlertDialog.Builder aboutDialogBuilder =
new AlertDialog.Builder(MapsActivity.this);
aboutDialogBuilder.setTitle("About Me")
.setMessage("http://android-er.blogspot.com");
aboutDialogBuilder.setPositiveButton("visit",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String url = "http://android-er.blogspot.com";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
});
aboutDialogBuilder.setNegativeButton("Dismiss",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog aboutDialog = aboutDialogBuilder.create();
aboutDialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}
private void addMarker(){
if(mMap != null){
//create custom LinearLayout programmatically
LinearLayout layout = new LinearLayout(MapsActivity.this);
layout.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
layout.setOrientation(LinearLayout.VERTICAL);
final EditText titleField = new EditText(MapsActivity.this);
titleField.setHint("Title");
final EditText latField = new EditText(MapsActivity.this);
latField.setHint("Latitude");
latField.setInputType(InputType.TYPE_CLASS_NUMBER
| InputType.TYPE_NUMBER_FLAG_DECIMAL
| InputType.TYPE_NUMBER_FLAG_SIGNED);
final EditText lonField = new EditText(MapsActivity.this);
lonField.setHint("Longitude");
lonField.setInputType(InputType.TYPE_CLASS_NUMBER
| InputType.TYPE_NUMBER_FLAG_DECIMAL
| InputType.TYPE_NUMBER_FLAG_SIGNED);
layout.addView(titleField);
layout.addView(latField);
layout.addView(lonField);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Add Marker");
builder.setView(layout);
AlertDialog alertDialog = builder.create();
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
boolean parsable = true;
Double lat = null, lon = null;
String strLat = latField.getText().toString();
String strLon = lonField.getText().toString();
String strTitle = titleField.getText().toString();
try{
lat = Double.parseDouble(strLat);
}catch (NumberFormatException ex){
parsable = false;
Toast.makeText(MapsActivity.this,
"Latitude does not contain a parsable double",
Toast.LENGTH_LONG).show();
}
try{
lon = Double.parseDouble(strLon);
}catch (NumberFormatException ex){
parsable = false;
Toast.makeText(MapsActivity.this,
"Longitude does not contain a parsable double",
Toast.LENGTH_LONG).show();
}
if(parsable){
LatLng targetLatLng = new LatLng(lat, lon);
MarkerOptions markerOptions =
new MarkerOptions().position(targetLatLng).title(strTitle);
markerOptions.draggable(true);
mMap.addMarker(markerOptions);
mMap.moveCamera(CameraUpdateFactory.newLatLng(targetLatLng));
}
}
});
builder.setNegativeButton("Cancel", null);
builder.show();
}else{
Toast.makeText(MapsActivity.this, "Map not ready", Toast.LENGTH_LONG).show();
}
}
@Override
public void onMapClick(LatLng latLng) {
Toast.makeText(MapsActivity.this,
"onMapClick:\n" + latLng.latitude + " : " + latLng.longitude,
Toast.LENGTH_LONG).show();
}
@Override
public void onMapLongClick(LatLng latLng) {
Toast.makeText(MapsActivity.this,
"onMapLongClick:\n" + latLng.latitude + " : " + latLng.longitude,
Toast.LENGTH_LONG).show();
//Add marker on LongClick position
MarkerOptions markerOptions =
new MarkerOptions().position(latLng).title(latLng.toString());
markerOptions.draggable(true);
mMap.addMarker(markerOptions);
}
@Override
public void onMarkerDragStart(Marker marker) {
marker.setTitle(marker.getPosition().toString());
marker.showInfoWindow();
marker.setAlpha(0.5f);
}
@Override
public void onMarkerDrag(Marker marker) {
marker.setTitle(marker.getPosition().toString());
marker.showInfoWindow();
marker.setAlpha(0.5f);
}
@Override
public void onMarkerDragEnd(Marker marker) {
marker.setTitle(marker.getPosition().toString());
marker.showInfoWindow();
marker.setAlpha(1.0f);
}
@Override
public View getInfoWindow(Marker marker) {
return null;
//return prepareInfoView(marker);
}
@Override
public View getInfoContents(Marker marker) {
//return null;
return prepareInfoView(marker);
}
private View prepareInfoView(Marker marker){
//prepare InfoView programmatically
LinearLayout infoView = new LinearLayout(MapsActivity.this);
LinearLayout.LayoutParams infoViewParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
infoView.setOrientation(LinearLayout.HORIZONTAL);
infoView.setLayoutParams(infoViewParams);
ImageView infoImageView = new ImageView(MapsActivity.this);
//Drawable drawable = getResources().getDrawable(R.mipmap.ic_launcher);
Drawable drawable = getResources().getDrawable(android.R.drawable.ic_dialog_map);
infoImageView.setImageDrawable(drawable);
infoView.addView(infoImageView);
LinearLayout subInfoView = new LinearLayout(MapsActivity.this);
LinearLayout.LayoutParams subInfoViewParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
subInfoView.setOrientation(LinearLayout.VERTICAL);
subInfoView.setLayoutParams(subInfoViewParams);
TextView subInfoLat = new TextView(MapsActivity.this);
subInfoLat.setText("Lat: " + marker.getPosition().latitude);
TextView subInfoLnt = new TextView(MapsActivity.this);
subInfoLnt.setText("Lnt: " + marker.getPosition().longitude);
subInfoView.addView(subInfoLat);
subInfoView.addView(subInfoLnt);
infoView.addView(subInfoView);
return infoView;
}
}
Reference: https://developers.google.com/maps/documentation/android-api/infowindows
Next:
- Detect user click on InfoWindow, by implementing GoogleMap.OnInfoWindowClickListener()
~ Step-by-step of Android Google Maps Activity using Google Maps Android API v2, on Android Studio
Connect Windows 10 to HC-06 Bluetooth
This post show how to connect Windows 10 to HC-06 Bluetooth Module.
Actually it's a loopback connection:
PuTTY Serial connect to Bluetooth Outgoing port -> (Bluetooth) -> HC-06 -> FT232RL -> (USB) -> Arduino IDE Serial Monitot.
This video show how to pair HC-06 on Windows 10, and try the loopback test.
Related:
- Raspberry Pi Bluetooth Serial Terminal, using HC-06 Bluetooth Module, connect from Windows 10 with Bluetooth, using PuTTY.
Actually it's a loopback connection:
PuTTY Serial connect to Bluetooth Outgoing port -> (Bluetooth) -> HC-06 -> FT232RL -> (USB) -> Arduino IDE Serial Monitot.
This video show how to pair HC-06 on Windows 10, and try the loopback test.
Related:
- Raspberry Pi Bluetooth Serial Terminal, using HC-06 Bluetooth Module, connect from Windows 10 with Bluetooth, using PuTTY.
Android Bluetooth connect PC (running Windows10) via HC-06 BT Module and FTDI US-to-Serial adapter
Last post show a "Android communicate with Arduino + HC-06 Bluetooth Module". Alternatively, the HC-06 can connect to PC via a FTDI USB-to-Serial adapter, such that Android can talk to PC by Bluetooth.
This video show how to:
Android side, refer to last post "Android communicate with Arduino + HC-06 Bluetooth Module", with source code and APK.
In my setup, both FT232RL (FTDI USB-to-Serial adapter) and HC-06 (Bluetooth Module) operate on 3.3V.
Connection:
HC-06 VCC - FT232RL VCC *make sure both devices work on the same voltage.
HC-06 GND - FT232RL GND
HC-06 TXD - FT232RL RXD
HC-06 RXD - FT232RL TXD
PC running Windows 10, connect to FT232RL by USB.
Serial Monitor of Arduino IDE is used as a terminal to talk with Android.
Android communicate with Arduino + HC-06 Bluetooth Module, part II
It's my old post "Android example to communicate with Bluetooth device, HC-06 Bluetooth Module", to make a Android phone communicate with Arduino + HC-06 Bluetooth Module. In the example, the first byte always lost.
After more test, I found that the first byte not lost. Because the byte stream sent from Arduino not in sync with Android side, and the bytes may be separated in different slot received in Android ThreadConnected, and the old slot covered by the new slot.
To show it, I modify it not to clear the TextView.
MainActivity.java
layout/activity_main.xml
Have to modify AndroidManifest.xml to uses-permission of "android.permission.BLUETOOTH". Refer the exmple "Android example to communicate with Bluetooth device, HC-06 Bluetooth Module".
Download the files (Android Studio Format) .
Download and try APK.
For the Arduino side, refer to : Arduino-er - Connect Arduino Due with HC-06 (Bluetooth Module).
This Android App can be used to talk with PC, with FTDI USB-to-Serial adapter connected to HC-06. Refer to the next post "Android Bluetooth connect PC (running Windows10) via HC-06 BT Module and FTDI US-to-Serial adapter".
more:
- Android Bluetooth Terminal to login Raspberry Pi + HC-06
After more test, I found that the first byte not lost. Because the byte stream sent from Arduino not in sync with Android side, and the bytes may be separated in different slot received in Android ThreadConnected, and the old slot covered by the new slot.
To show it, I modify it not to clear the TextView.
MainActivity.java
/*
Android Example to connect to and communicate with Bluetooth
In this exercise, the target is a Arduino Due + HC-06 (Bluetooth Module)
Ref:
- Make BlueTooth connection between Android devices
http://android-er.blogspot.com/2014/12/make-bluetooth-connection-between.html
- Bluetooth communication between Android devices
http://android-er.blogspot.com/2014/12/bluetooth-communication-between-android.html
*/
package com.example.androidbtcontrol;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
public class MainActivity extends ActionBarActivity {
private static final int REQUEST_ENABLE_BT = 1;
BluetoothAdapter bluetoothAdapter;
ArrayList<BluetoothDevice> pairedDeviceArrayList;
TextView textInfo, textStatus, textByteCnt;
ListView listViewPairedDevice;
LinearLayout inputPane;
EditText inputField;
Button btnSend, btnClear;
ArrayAdapter<BluetoothDevice> pairedDeviceAdapter;
private UUID myUUID;
private final String UUID_STRING_WELL_KNOWN_SPP =
"00001101-0000-1000-8000-00805F9B34FB";
ThreadConnectBTdevice myThreadConnectBTdevice;
ThreadConnected myThreadConnected;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textInfo = (TextView)findViewById(R.id.info);
textStatus = (TextView)findViewById(R.id.status);
textByteCnt = (TextView)findViewById(R.id.textbyteCnt);
listViewPairedDevice = (ListView)findViewById(R.id.pairedlist);
inputPane = (LinearLayout)findViewById(R.id.inputpane);
inputField = (EditText)findViewById(R.id.input);
btnSend = (Button)findViewById(R.id.send);
btnSend.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
if(myThreadConnected!=null){
byte[] bytesToSend = inputField.getText().toString().getBytes();
myThreadConnected.write(bytesToSend);
byte[] NewLine = "\n".getBytes();
myThreadConnected.write(NewLine);
}
}});
btnClear = (Button)findViewById(R.id.clear);
btnClear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
textStatus.setText("");
textByteCnt.setText("");
}
});
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)){
Toast.makeText(this,
"FEATURE_BLUETOOTH NOT support",
Toast.LENGTH_LONG).show();
finish();
return;
}
//using the well-known SPP UUID
myUUID = UUID.fromString(UUID_STRING_WELL_KNOWN_SPP);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Toast.makeText(this,
"Bluetooth is not supported on this hardware platform",
Toast.LENGTH_LONG).show();
finish();
return;
}
String stInfo = bluetoothAdapter.getName() + "\n" +
bluetoothAdapter.getAddress();
textInfo.setText(stInfo);
}
@Override
protected void onStart() {
super.onStart();
//Turn ON BlueTooth if it is OFF
if (!bluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}
setup();
}
private void setup() {
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
pairedDeviceArrayList = new ArrayList<BluetoothDevice>();
for (BluetoothDevice device : pairedDevices) {
pairedDeviceArrayList.add(device);
}
pairedDeviceAdapter = new ArrayAdapter<BluetoothDevice>(this,
android.R.layout.simple_list_item_1, pairedDeviceArrayList);
listViewPairedDevice.setAdapter(pairedDeviceAdapter);
listViewPairedDevice.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
BluetoothDevice device =
(BluetoothDevice) parent.getItemAtPosition(position);
Toast.makeText(MainActivity.this,
"Name: " + device.getName() + "\n"
+ "Address: " + device.getAddress() + "\n"
+ "BondState: " + device.getBondState() + "\n"
+ "BluetoothClass: " + device.getBluetoothClass() + "\n"
+ "Class: " + device.getClass(),
Toast.LENGTH_LONG).show();
textStatus.setText("start ThreadConnectBTdevice");
myThreadConnectBTdevice = new ThreadConnectBTdevice(device);
myThreadConnectBTdevice.start();
}
});
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if(myThreadConnectBTdevice!=null){
myThreadConnectBTdevice.cancel();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode==REQUEST_ENABLE_BT){
if(resultCode == Activity.RESULT_OK){
setup();
}else{
Toast.makeText(this,
"BlueTooth NOT enabled",
Toast.LENGTH_SHORT).show();
finish();
}
}
}
//Called in ThreadConnectBTdevice once connect successed
//to start ThreadConnected
private void startThreadConnected(BluetoothSocket socket){
myThreadConnected = new ThreadConnected(socket);
myThreadConnected.start();
}
/*
ThreadConnectBTdevice:
Background Thread to handle BlueTooth connecting
*/
private class ThreadConnectBTdevice extends Thread {
private BluetoothSocket bluetoothSocket = null;
private final BluetoothDevice bluetoothDevice;
private ThreadConnectBTdevice(BluetoothDevice device) {
bluetoothDevice = device;
try {
bluetoothSocket = device.createRfcommSocketToServiceRecord(myUUID);
textStatus.setText("bluetoothSocket: \n" + bluetoothSocket);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
boolean success = false;
try {
bluetoothSocket.connect();
success = true;
} catch (IOException e) {
e.printStackTrace();
final String eMessage = e.getMessage();
runOnUiThread(new Runnable() {
@Override
public void run() {
textStatus.setText("something wrong bluetoothSocket.connect(): \n" + eMessage);
}
});
try {
bluetoothSocket.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
if(success){
//connect successful
final String msgconnected = "connect successful:\n"
+ "BluetoothSocket: " + bluetoothSocket + "\n"
+ "BluetoothDevice: " + bluetoothDevice;
runOnUiThread(new Runnable() {
@Override
public void run() {
textStatus.setText("");
textByteCnt.setText("");
Toast.makeText(MainActivity.this, msgconnected, Toast.LENGTH_LONG).show();
listViewPairedDevice.setVisibility(View.GONE);
inputPane.setVisibility(View.VISIBLE);
}
});
startThreadConnected(bluetoothSocket);
}else{
//fail
}
}
public void cancel() {
Toast.makeText(getApplicationContext(),
"close bluetoothSocket",
Toast.LENGTH_LONG).show();
try {
bluetoothSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/*
ThreadConnected:
Background Thread to handle Bluetooth data communication
after connected
*/
private class ThreadConnected extends Thread {
private final BluetoothSocket connectedBluetoothSocket;
private final InputStream connectedInputStream;
private final OutputStream connectedOutputStream;
public ThreadConnected(BluetoothSocket socket) {
connectedBluetoothSocket = socket;
InputStream in = null;
OutputStream out = null;
try {
in = socket.getInputStream();
out = socket.getOutputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
connectedInputStream = in;
connectedOutputStream = out;
}
@Override
public void run() {
byte[] buffer = new byte[1024];
int bytes;
String strRx = "";
while (true) {
try {
bytes = connectedInputStream.read(buffer);
final String strReceived = new String(buffer, 0, bytes);
final String strByteCnt = String.valueOf(bytes) + " bytes received.\n";
runOnUiThread(new Runnable(){
@Override
public void run() {
textStatus.append(strReceived);
textByteCnt.append(strByteCnt);
}});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
final String msgConnectionLost = "Connection lost:\n"
+ e.getMessage();
runOnUiThread(new Runnable(){
@Override
public void run() {
textStatus.setText(msgConnectionLost);
}});
}
}
}
public void write(byte[] buffer) {
try {
connectedOutputStream.write(buffer);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void cancel() {
try {
connectedBluetoothSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:orientation="horizontal"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<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" />
<TextView
android:id="@+id/textbyteCnt"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"/>
<TextView
android:id="@+id/status"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/info"
android:textStyle="bold|italic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ListView
android:id="@+id/pairedlist"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<LinearLayout
android:id="@+id/inputpane"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone">
<EditText
android:id="@+id/input"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/send"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Sent"/>
<Button
android:id="@+id/clear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Clear"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
Have to modify AndroidManifest.xml to uses-permission of "android.permission.BLUETOOTH". Refer the exmple "Android example to communicate with Bluetooth device, HC-06 Bluetooth Module".
Download the files (Android Studio Format) .
Download and try APK.
For the Arduino side, refer to : Arduino-er - Connect Arduino Due with HC-06 (Bluetooth Module).
This Android App can be used to talk with PC, with FTDI USB-to-Serial adapter connected to HC-06. Refer to the next post "Android Bluetooth connect PC (running Windows10) via HC-06 BT Module and FTDI US-to-Serial adapter".
more:
- Android Bluetooth Terminal to login Raspberry Pi + HC-06
Make GoogleMap's marker draggabe and detect moving marker
To make GoogleMap's marker draggabe and detect moving marker:
- Modify MapsActivity to implement GoogleMap.OnMarkerDragListener
- Override onMarkerDragStart(Marker marker), onMarkerDrag(Marker marker) and onMarkerDragEnd(Marker marker), to handle the MarkerDrag events.
- Assign OnMarkerDragListener by calling mMap.setOnMarkerDragListener(this).
- Set markers draggable by calling markerOptions.draggable(true).
Modify MapsActivity.java from last post "Detect touch on GoogleMap, onMapClick() and onMapLongClick()".
MapsActivity.java
package com.blogspot.android_er.androidstudiomapapp;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.InputType;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback,
GoogleMap.OnMapClickListener, GoogleMap.OnMapLongClickListener,
GoogleMap.OnMarkerDragListener {
private GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setOnMapClickListener(this);
mMap.setOnMapLongClickListener(this);
mMap.setOnMarkerDragListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_addmarkers:
addMarker();
return true;
case R.id.maptypeHYBRID:
if(mMap != null){
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
return true;
}
case R.id.maptypeNONE:
if(mMap != null){
mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
return true;
}
case R.id.maptypeNORMAL:
if(mMap != null){
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
return true;
}
case R.id.maptypeSATELLITE:
if(mMap != null){
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
return true;
}
case R.id.maptypeTERRAIN:
if(mMap != null){
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
return true;
}
case R.id.menu_legalnotices:
String LicenseInfo = GoogleApiAvailability
.getInstance()
.getOpenSourceSoftwareLicenseInfo(MapsActivity.this);
AlertDialog.Builder LicenseDialog =
new AlertDialog.Builder(MapsActivity.this);
LicenseDialog.setTitle("Legal Notices");
LicenseDialog.setMessage(LicenseInfo);
LicenseDialog.show();
return true;
case R.id.menu_about:
AlertDialog.Builder aboutDialogBuilder =
new AlertDialog.Builder(MapsActivity.this);
aboutDialogBuilder.setTitle("About Me")
.setMessage("http://android-er.blogspot.com");
aboutDialogBuilder.setPositiveButton("visit",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String url = "http://android-er.blogspot.com";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
});
aboutDialogBuilder.setNegativeButton("Dismiss",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog aboutDialog = aboutDialogBuilder.create();
aboutDialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}
private void addMarker(){
if(mMap != null){
//create custom LinearLayout programmatically
LinearLayout layout = new LinearLayout(MapsActivity.this);
layout.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
layout.setOrientation(LinearLayout.VERTICAL);
final EditText titleField = new EditText(MapsActivity.this);
titleField.setHint("Title");
final EditText latField = new EditText(MapsActivity.this);
latField.setHint("Latitude");
latField.setInputType(InputType.TYPE_CLASS_NUMBER
| InputType.TYPE_NUMBER_FLAG_DECIMAL
| InputType.TYPE_NUMBER_FLAG_SIGNED);
final EditText lonField = new EditText(MapsActivity.this);
lonField.setHint("Longitude");
lonField.setInputType(InputType.TYPE_CLASS_NUMBER
| InputType.TYPE_NUMBER_FLAG_DECIMAL
| InputType.TYPE_NUMBER_FLAG_SIGNED);
layout.addView(titleField);
layout.addView(latField);
layout.addView(lonField);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Add Marker");
builder.setView(layout);
AlertDialog alertDialog = builder.create();
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
boolean parsable = true;
Double lat = null, lon = null;
String strLat = latField.getText().toString();
String strLon = lonField.getText().toString();
String strTitle = titleField.getText().toString();
try{
lat = Double.parseDouble(strLat);
}catch (NumberFormatException ex){
parsable = false;
Toast.makeText(MapsActivity.this,
"Latitude does not contain a parsable double",
Toast.LENGTH_LONG).show();
}
try{
lon = Double.parseDouble(strLon);
}catch (NumberFormatException ex){
parsable = false;
Toast.makeText(MapsActivity.this,
"Longitude does not contain a parsable double",
Toast.LENGTH_LONG).show();
}
if(parsable){
LatLng targetLatLng = new LatLng(lat, lon);
MarkerOptions markerOptions =
new MarkerOptions().position(targetLatLng).title(strTitle);
markerOptions.draggable(true);
mMap.addMarker(markerOptions);
mMap.moveCamera(CameraUpdateFactory.newLatLng(targetLatLng));
}
}
});
builder.setNegativeButton("Cancel", null);
builder.show();
}else{
Toast.makeText(MapsActivity.this, "Map not ready", Toast.LENGTH_LONG).show();
}
}
@Override
public void onMapClick(LatLng latLng) {
Toast.makeText(MapsActivity.this,
"onMapClick:\n" + latLng.latitude + " : " + latLng.longitude,
Toast.LENGTH_LONG).show();
}
@Override
public void onMapLongClick(LatLng latLng) {
Toast.makeText(MapsActivity.this,
"onMapLongClick:\n" + latLng.latitude + " : " + latLng.longitude,
Toast.LENGTH_LONG).show();
//Add marker on LongClick position
MarkerOptions markerOptions =
new MarkerOptions().position(latLng).title(latLng.toString());
markerOptions.draggable(true);
mMap.addMarker(markerOptions);
}
@Override
public void onMarkerDragStart(Marker marker) {
marker.setTitle(marker.getPosition().toString());
marker.showInfoWindow();
marker.setAlpha(0.5f);
}
@Override
public void onMarkerDrag(Marker marker) {
marker.setTitle(marker.getPosition().toString());
marker.showInfoWindow();
marker.setAlpha(0.5f);
}
@Override
public void onMarkerDragEnd(Marker marker) {
marker.setTitle(marker.getPosition().toString());
marker.showInfoWindow();
marker.setAlpha(1.0f);
}
}
reference: https://developers.google.com/maps/documentation/android-api/marker
Next: - Custom InfoWindow for Google Maps Android API v2
~ Step-by-step of Android Google Maps Activity using Google Maps Android API v2, on Android Studio
Detect touch on GoogleMap, onMapClick() and onMapLongClick()
To detect touch on GoogleMap, modify MapsActivity.java from last example "Google Maps Android API v2 - initialize map in xml".
Edit MapsActivity to implements GoogleMap.OnMapClickListener, GoogleMap.OnMapLongClickListener.
Implement your listeners, onMapClick() and onMapLongClick().
Assign the listeners to your GoogleMap by calling:
mMap.setOnMapClickListener(this);
mMap.setOnMapLongClickListener(this);
package com.blogspot.android_er.androidstudiomapapp;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.InputType;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback,
GoogleMap.OnMapClickListener, GoogleMap.OnMapLongClickListener {
private GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setOnMapClickListener(this);
mMap.setOnMapLongClickListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_addmarkers:
addMarker();
return true;
case R.id.maptypeHYBRID:
if(mMap != null){
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
return true;
}
case R.id.maptypeNONE:
if(mMap != null){
mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
return true;
}
case R.id.maptypeNORMAL:
if(mMap != null){
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
return true;
}
case R.id.maptypeSATELLITE:
if(mMap != null){
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
return true;
}
case R.id.maptypeTERRAIN:
if(mMap != null){
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
return true;
}
case R.id.menu_legalnotices:
String LicenseInfo = GoogleApiAvailability
.getInstance()
.getOpenSourceSoftwareLicenseInfo(MapsActivity.this);
AlertDialog.Builder LicenseDialog =
new AlertDialog.Builder(MapsActivity.this);
LicenseDialog.setTitle("Legal Notices");
LicenseDialog.setMessage(LicenseInfo);
LicenseDialog.show();
return true;
case R.id.menu_about:
AlertDialog.Builder aboutDialogBuilder =
new AlertDialog.Builder(MapsActivity.this);
aboutDialogBuilder.setTitle("About Me")
.setMessage("http://android-er.blogspot.com");
aboutDialogBuilder.setPositiveButton("visit",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String url = "http://android-er.blogspot.com";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
});
aboutDialogBuilder.setNegativeButton("Dismiss",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog aboutDialog = aboutDialogBuilder.create();
aboutDialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}
private void addMarker(){
if(mMap != null){
//create custom LinearLayout programmatically
LinearLayout layout = new LinearLayout(MapsActivity.this);
layout.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
layout.setOrientation(LinearLayout.VERTICAL);
final EditText titleField = new EditText(MapsActivity.this);
titleField.setHint("Title");
final EditText latField = new EditText(MapsActivity.this);
latField.setHint("Latitude");
latField.setInputType(InputType.TYPE_CLASS_NUMBER
| InputType.TYPE_NUMBER_FLAG_DECIMAL
| InputType.TYPE_NUMBER_FLAG_SIGNED);
final EditText lonField = new EditText(MapsActivity.this);
lonField.setHint("Longitude");
lonField.setInputType(InputType.TYPE_CLASS_NUMBER
| InputType.TYPE_NUMBER_FLAG_DECIMAL
| InputType.TYPE_NUMBER_FLAG_SIGNED);
layout.addView(titleField);
layout.addView(latField);
layout.addView(lonField);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Add Marker");
builder.setView(layout);
AlertDialog alertDialog = builder.create();
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
boolean parsable = true;
Double lat = null, lon = null;
String strLat = latField.getText().toString();
String strLon = lonField.getText().toString();
String strTitle = titleField.getText().toString();
try{
lat = Double.parseDouble(strLat);
}catch (NumberFormatException ex){
parsable = false;
Toast.makeText(MapsActivity.this,
"Latitude does not contain a parsable double",
Toast.LENGTH_LONG).show();
}
try{
lon = Double.parseDouble(strLon);
}catch (NumberFormatException ex){
parsable = false;
Toast.makeText(MapsActivity.this,
"Longitude does not contain a parsable double",
Toast.LENGTH_LONG).show();
}
if(parsable){
LatLng targetLatLng = new LatLng(lat, lon);
MarkerOptions markerOptions =
new MarkerOptions().position(targetLatLng).title(strTitle);
mMap.addMarker(markerOptions);
mMap.moveCamera(CameraUpdateFactory.newLatLng(targetLatLng));
}
}
});
builder.setNegativeButton("Cancel", null);
builder.show();
}else{
Toast.makeText(MapsActivity.this, "Map not ready", Toast.LENGTH_LONG).show();
}
}
@Override
public void onMapClick(LatLng latLng) {
Toast.makeText(MapsActivity.this,
"onMapClick:\n" + latLng.latitude + " : " + latLng.longitude,
Toast.LENGTH_LONG).show();
}
@Override
public void onMapLongClick(LatLng latLng) {
Toast.makeText(MapsActivity.this,
"onMapLongClick:\n" + latLng.latitude + " : " + latLng.longitude,
Toast.LENGTH_LONG).show();
//Add marker on LongClick position
MarkerOptions markerOptions =
new MarkerOptions().position(latLng).title(latLng.toString());
mMap.addMarker(markerOptions);
}
}
Next: Make GoogleMap's marker draggabe and detect moving marker
~ Step-by-step of Android Google Maps Activity using Google Maps Android API v2, on Android Studio
Convert ImageView to black and white, and set brightness, using ColorFilter
MainActivity.java
package com.blogspot.android_er.androidcolorfilter;
import android.graphics.ColorFilter;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
ImageView imageView;
SeekBar brightnessBar;
TextView brightnessInfo;
PorterDuff.Mode[] optMode = PorterDuff.Mode.values();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView)findViewById(R.id.iv);
brightnessBar = (SeekBar)findViewById(R.id.bar_brightness);
brightnessInfo = (TextView)findViewById(R.id.brightness_info);
brightnessBar.setOnSeekBarChangeListener(brightnessBarChangeListener);
setBlackAndWhite(imageView);
}
SeekBar.OnSeekBarChangeListener brightnessBarChangeListener
= new SeekBar.OnSeekBarChangeListener(){
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
setBlackAndWhite(imageView);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
};
private void setBlackAndWhite(ImageView iv){
float brightness = (float)(brightnessBar.getProgress() - 255);
float[] colorMatrix = {
0.33f, 0.33f, 0.33f, 0, brightness, //red
0.33f, 0.33f, 0.33f, 0, brightness, //green
0.33f, 0.33f, 0.33f, 0, brightness, //blue
0, 0, 0, 1, 0 //alpha
};
ColorFilter colorFilter = new ColorMatrixColorFilter(colorMatrix);
iv.setColorFilter(colorFilter);
brightnessInfo.setText(String.valueOf(brightness));
}
}
layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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:padding="16dp"
android:orientation="vertical"
tools:context=".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/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Brightness"/>
<SeekBar
android:id="@+id/bar_brightness"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="512"
android:progress="255"/>
<TextView
android:id="@+id/brightness_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Brightness"/>
</LinearLayout>
Related:
- Android example code using ColorFilter
Android example code using ColorFilter
MainActivity.java
package com.blogspot.android_er.androidcolorfilter;
import android.graphics.ColorFilter;
import android.graphics.ColorMatrixColorFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import android.widget.SeekBar;
public class MainActivity extends AppCompatActivity {
ImageView imageView;
SeekBar redBar, greenBar, blueBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView)findViewById(R.id.iv);
redBar = (SeekBar)findViewById(R.id.redbar);
greenBar = (SeekBar)findViewById(R.id.greenbar);
blueBar = (SeekBar)findViewById(R.id.bluebar);
redBar.setOnSeekBarChangeListener(colorBarChangeListener);
greenBar.setOnSeekBarChangeListener(colorBarChangeListener);
blueBar.setOnSeekBarChangeListener(colorBarChangeListener);
setColorFilter(imageView);
}
SeekBar.OnSeekBarChangeListener colorBarChangeListener
= new SeekBar.OnSeekBarChangeListener(){
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
setColorFilter(imageView);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
};
private void setColorFilter(ImageView iv){
/*
* 5x4 matrix for transforming the color+alpha components of a Bitmap.
* The matrix is stored in a single array, and its treated as follows:
* [ a, b, c, d, e,
* f, g, h, i, j,
* k, l, m, n, o,
* p, q, r, s, t ]
*
* When applied to a color [r, g, b, a], the resulting color is computed
* as (after clamping)
* R' = a*R + b*G + c*B + d*A + e;
* G' = f*R + g*G + h*B + i*A + j;
* B' = k*R + l*G + m*B + n*A + o;
* A' = p*R + q*G + r*B + s*A + t;
*/
float redValue = ((float)redBar.getProgress())/255;
float greenValue = ((float)greenBar.getProgress())/255;
float blueValue = ((float)blueBar.getProgress())/255;
float[] colorMatrix = {
redValue, 0, 0, 0, 0, //red
0, greenValue, 0, 0, 0, //green
0, 0, blueValue, 0, 0, //blue
0, 0, 0, 1, 0 //alpha
};
ColorFilter colorFilter = new ColorMatrixColorFilter(colorMatrix);
iv.setColorFilter(colorFilter);
}
}
layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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:padding="16dp"
android:orientation="vertical"
tools:context=".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/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"/>
<SeekBar
android:id="@+id/redbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255"
android:progress="255"/>
<SeekBar
android:id="@+id/greenbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255"
android:progress="255"/>
<SeekBar
android:id="@+id/bluebar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255"
android:progress="255"/>
</LinearLayout>
Related:
- Convert ImageView to black and white, and set brightness, using ColorFilter
الاشتراك في:
الرسائل (Atom)