Can I hang up a call programmatically in android?
First, you need to declare this permission in AndroidManifest.xml
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Then you setup a BroadcastReceiver
service for android.intent.action.PHONE_STATE
(incoming calls) and android.intent.action.NEW_OUTGOING_CALL
(outgoing calls) by adding the following to AndroidManifest.xml
AndroidManifest.xml
<receiver android:name=".PhoneStateReceiver">
<intent-filter android:priority="0">
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
PhoneStateReceiver.JAVA
import java.lang.reflect.Method;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.util.Log;
public class PhoneStateReceiver extends BroadcastReceiver {
public static String TAG="PhoneStateReceiver";
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.PHONE_STATE")) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
Log.d(TAG,"PhoneStateReceiver**Call State=" + state);
if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
Log.d(TAG,"PhoneStateReceiver**Idle");
} else if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
// Incoming call
String incomingNumber =
intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
Log.d(TAG,"PhoneStateReceiver**Incoming call " + incomingNumber);
if (!killCall(context)) { // Using the method defined earlier
Log.d(TAG,"PhoneStateReceiver **Unable to kill incoming call");
}
} else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
Log.d(TAG,"PhoneStateReceiver **Offhook");
}
} else if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {
// Outgoing call
String outgoingNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Log.d(TAG,"PhoneStateReceiver **Outgoing call " + outgoingNumber);
setResultData(null); // Kills the outgoing call
} else {
Log.d(TAG,"PhoneStateReceiver **unexpected intent.action=" + intent.getAction());
}
}
public boolean killCall(Context context) {
try {
// Get the boring old TelephonyManager
TelephonyManager telephonyManager =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
// Get the getITelephony() method
Class classTelephony = Class.forName(telephonyManager.getClass().getName());
Method methodGetITelephony = classTelephony.getDeclaredMethod("getITelephony");
// Ignore that the method is supposed to be private
methodGetITelephony.setAccessible(true);
// Invoke getITelephony() to get the ITelephony interface
Object telephonyInterface = methodGetITelephony.invoke(telephonyManager);
// Get the endCall method from ITelephony
Class telephonyInterfaceClass =
Class.forName(telephonyInterface.getClass().getName());
Method methodEndCall = telephonyInterfaceClass.getDeclaredMethod("endCall");
// Invoke endCall()
methodEndCall.invoke(telephonyInterface);
} catch (Exception ex) { // Many things can go wrong with reflection calls
Log.d(TAG,"PhoneStateReceiver **" + ex.toString());
return false;
}
return true;
}
}
MainActivity.JAVA
import android.Manifest;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
public static final int MY_PERMISSIONS_REQUEST_READ_PHONE_STATE = 101;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_PHONE_STATE)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_PHONE_STATE},
MY_PERMISSIONS_REQUEST_READ_PHONE_STATE);
// MY_PERMISSIONS_REQUEST_READ_PHONE_STATE is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_PHONE_STATE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay!
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
}
Detecting outgoing call and call hangup event in android
You should create a BroadcastReceiver:
public class CallReciever extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
TelephonyManager.EXTRA_STATE_RINGING)) {
// Phone number
String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
// Ringing state
// This code will execute when the phone has an incoming call
} else if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
TelephonyManager.EXTRA_STATE_IDLE)
|| intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
TelephonyManager.EXTRA_STATE_OFFHOOK)) {
// This code will execute when the call is answered or disconnected
}
}
}
You should register you application to listen to these intents in the manifest:
<receiver android:name=".CallReciever" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
How to check and hang-up/reject incoming/outgoing calls on Android in Delphi?
First, you must have own BroadcastReceiver unit - you can download it from here.
unit CSBroadcastReceiver;
interface
uses
System.Classes
,System.SysUtils
{$IFDEF ANDROID}
,Androidapi.JNI.Embarcadero
,Androidapi.JNI.GraphicsContentViewText
,Androidapi.Helpers
,Androidapi.JNIBridge
,Androidapi.JNI.JavaTypes
,Androidapi.JNI.App
{$ENDIF}
;
type
{$IFNDEF ANDROID}
JIntent = class
end;
JContext = class
end;
{$ENDIF}
TCSBroadcastReceiver= class;
TOnReceive = procedure (csContext: JContext; csIntent: JIntent) of object;
{$IFDEF ANDROID}
TCSListener = class(TJavaLocal, JFMXBroadcastReceiverListener)
private
FOwner: TCSBroadcastReceiver;
public
constructor Create(AOwner: TCSBroadcastReceiver);
procedure OnReceive(csContext: JContext; csIntent: JIntent); cdecl;
end;
{$ENDIF}
TCSBroadcastReceiver = class(TComponent)
private
{$IFDEF ANDROID}
FReceiver: JBroadcastReceiver;
FListener : TCSListener;
{$ENDIF}
FOnReceive: TOnReceive;
FItems: TStringList;
function GetItem(const csIndex: Integer): String;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure SendBroadcast(csValue: String);
procedure Add(csValue: String);
procedure Delete(csIndex: Integer);
procedure Clear;
procedure setResultData(data: JString);
function Remove(const csValue: String): Integer;
function First: String;
function Last: String;
function HasPermission(const csPermission: string): Boolean;
procedure RegisterReceive;
property Item[const csIndex: Integer]: string read GetItem; default;
property Items: TStringList read FItems write FItems;
published
property OnReceive: TOnReceive read FOnReceive write FOnReceive;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Classicsoft', [TCSBroadcastReceiver]);
end;
{ TCSBroadcastReceiver }
procedure TCSBroadcastReceiver.setResultData(data: Jstring);
begin
FReceiver.setResultData(data);
end;
procedure TCSBroadcastReceiver.Add(csValue: String);
{$IFDEF ANDROID}
var
Filter: JIntentFilter;
{$ENDIF}
begin
{$IFDEF ANDROID}
if (FListener = nil) or (FReceiver = nil) then
begin
Raise Exception.Create('First use RegisterReceive!');
Exit;
end;
{$ENDIF}
if FItems <> nil then
if FItems.IndexOf(csValue) = -1 then
begin
{$IFDEF ANDROID}
filter := TJIntentFilter.Create;
filter.addAction(StringToJString(csValue));
TAndroidHelper.Context.registerReceiver(FReceiver, filter);
{$ENDIF}
FItems.Add(csValue);
end;
end;
procedure TCSBroadcastReceiver.Clear;
begin
FItems.Clear;
end;
constructor TCSBroadcastReceiver.Create(AOwner: TComponent);
begin
inherited;
FItems := TStringList.Create;
end;
procedure TCSBroadcastReceiver.Delete(csIndex: Integer);
begin
if FItems <> nil then
begin
FItems.Delete(csIndex);
{$IFDEF ANDROID}
TAndroidHelper.Activity.UnregisterReceiver(FReceiver);
RegisterReceive;
{$ENDIF}
end;
end;
destructor TCSBroadcastReceiver.Destroy;
begin
FItems.Free;
{$IFDEF ANDROID}
if FReceiver <> nil then
TAndroidHelper.Activity.UnregisterReceiver(FReceiver);
{$ENDIF}
inherited;
end;
function TCSBroadcastReceiver.First: String;
begin
Result := FItems[0];
end;
function TCSBroadcastReceiver.GetItem(const csIndex: Integer): String;
begin
Result := FItems[csIndex];
end;
function TCSBroadcastReceiver.HasPermission(const csPermission: string): Boolean;
{$IFDEF ANDROID}
begin
Result := TAndroidHelper.Activity.checkCallingOrSelfPermission(StringToJString(csPermission)) = TJPackageManager.JavaClass.PERMISSION_GRANTED;
{$ELSE}
begin
Result := False;
{$ENDIF}
end;
function TCSBroadcastReceiver.Last: String;
begin
Result := FItems[FItems.Count];
end;
procedure TCSBroadcastReceiver.RegisterReceive;
{$IFDEF ANDROID}
var
I: Integer;
begin
if FListener = nil then
FListener := TCSListener.Create(Self);
if FReceiver = nil then
FReceiver := TJFMXBroadcastReceiver.JavaClass.init(FListener);
if FItems <> nil then
if FItems.Count > 0 then
for I := 0 to FItems.Count -1 do
Add(FItems[I]);
{$ELSE}
begin
{$ENDIF}
end;
function TCSBroadcastReceiver.Remove(const csValue: String): Integer;
begin
Result := FItems.IndexOf(csValue);
if Result > -1 then
FItems.Delete(Result);
end;
procedure TCSBroadcastReceiver.SendBroadcast(csValue: String);
{$IFDEF ANDROID}
var
Inx: JIntent;
begin
Inx := TJIntent.Create;
Inx.setAction(StringToJString(csValue));
TAndroidHelper.Context.sendBroadcast(Inx);
{$ELSE}
begin
{$ENDIF}
end;
{$IFDEF ANDROID}
constructor TCSListener.Create(AOwner: TCSBroadcastReceiver);
begin
inherited Create;
FOwner := AOwner;
end;
procedure TCSListener.OnReceive(csContext: JContext; csIntent: JIntent);
begin
if Assigned(FOwner.OnReceive) then
FOwner.onReceive(csContext, csIntent);
end;
{$ENDIF}
end.
Secondly, you must create your own definition of JMethod a JLang_Class - you can download it from here.
unit Androidapi.JNI.JavaTypes.Own;
interface
uses
Androidapi.JNI.JavaTypes,
Androidapi.JNIBridge;
type
JOwnMethod = interface;//java.lang.reflect.Method
JOwnLang_Class = interface;//java.lang.Class
JOwnMethodClass = interface(JObjectClass)
['{C995BD27-1D77-48E5-B478-EB8E9E607020}']
end;
[JavaSignature('java/lang/reflect/Method')]
JOwnMethod = interface(JObject)
['{ED1B0770-0BD6-4D4A-B801-9D18AB92C834}']
procedure setAccessible(flag: Boolean); cdecl; overload;
function equals(other: JObject): Boolean; cdecl;
function getAnnotation(annotationType: JOwnLang_Class): JAnnotation; cdecl;
function getAnnotations: TJavaObjectArray<JAnnotation>; cdecl;
function getDeclaredAnnotations: TJavaObjectArray<JAnnotation>; cdecl;
function getDeclaringClass: JOwnLang_Class; cdecl;
function getDefaultValue: JObject; cdecl;
function getExceptionTypes: TJavaObjectArray<JOwnLang_Class>; cdecl;
function getGenericExceptionTypes: TJavaObjectArray<Jreflect_Type>; cdecl;
function getGenericParameterTypes: TJavaObjectArray<Jreflect_Type>; cdecl;
function getGenericReturnType: Jreflect_Type; cdecl;
function getModifiers: Integer; cdecl;
function getName: JString; cdecl;
function getParameterAnnotations: TJavaObjectBiArray<JAnnotation>; cdecl;
function getParameterTypes: TJavaObjectArray<JOwnLang_Class>; cdecl;
function getReturnType: JOwnLang_Class; cdecl;
function getTypeParameters: TJavaObjectArray<JTypeVariable>; cdecl;
function hashCode: Integer; cdecl;
function invoke(receiver: JObject; args: TJavaObjectArray<JObject>): JObject; cdecl;
function isAnnotationPresent(annotationType: JOwnLang_Class): Boolean; cdecl;
function isBridge: Boolean; cdecl;
function isSynthetic: Boolean; cdecl;
function isVarArgs: Boolean; cdecl;
function toGenericString: JString; cdecl;
function toString: JString; cdecl;
end;
TJOwnMethod = class(TJavaGenericImport<JOwnMethodClass, JOwnMethod>) end;
JOwnLang_ClassClass = interface(JObjectClass)
['{E1A7F20A-FD87-4D67-9469-7492FD97D55D}']
{class} function forName(className: JString): JOwnLang_Class; cdecl; overload;
{class} function forName(className: JString; shouldInitialize: Boolean; classLoader: JClassLoader): JOwnLang_Class; cdecl; overload;
end;
[JavaSignature('java/lang/Class')]
JOwnLang_Class = interface(JObject)
['{B056EDE6-77D8-4CDD-9864-147C201FD87C}']
function asSubclass(c: JOwnLang_Class): JOwnLang_Class; cdecl;
function cast(obj: JObject): JObject; cdecl;
function desiredAssertionStatus: Boolean; cdecl;
function getAnnotation(annotationType: JOwnLang_Class): JAnnotation; cdecl;
function getAnnotations: TJavaObjectArray<JAnnotation>; cdecl;
function getCanonicalName: JString; cdecl;
function getClassLoader: JClassLoader; cdecl;
function getClasses: TJavaObjectArray<JOwnLang_Class>; cdecl;
function getComponentType: JOwnLang_Class; cdecl;
function getConstructors: TJavaObjectArray<JConstructor>; cdecl;
function getDeclaredAnnotations: TJavaObjectArray<JAnnotation>; cdecl;
function getDeclaredClasses: TJavaObjectArray<JOwnLang_Class>; cdecl;
function getDeclaredConstructors: TJavaObjectArray<JConstructor>; cdecl;
function getDeclaredField(name: JString): JField; cdecl;
function getDeclaredFields: TJavaObjectArray<JField>; cdecl;
function getDeclaredMethod(name: JString; parameterTypes: TJavaObjectArray<JOwnLang_Class>): JOwnMethod; cdecl;
function getDeclaredMethods: TJavaObjectArray<JOwnMethod>; cdecl;
function getDeclaringClass: JOwnLang_Class; cdecl;
function getEnclosingClass: JOwnLang_Class; cdecl;
function getEnclosingConstructor: JConstructor; cdecl;
function getEnclosingMethod: JOwnMethod; cdecl;
function getEnumConstants: TJavaObjectArray<JObject>; cdecl;
function getField(name: JString): JField; cdecl;
function getFields: TJavaObjectArray<JField>; cdecl;
function getGenericInterfaces: TJavaObjectArray<Jreflect_Type>; cdecl;
function getGenericSuperclass: Jreflect_Type; cdecl;
function getInterfaces: TJavaObjectArray<JOwnLang_Class>; cdecl;
function getMethods: TJavaObjectArray<JOwnMethod>; cdecl;
function getModifiers: Integer; cdecl;
function getName: JString; cdecl;
function getPackage: JPackage; cdecl;
//function getProtectionDomain: JProtectionDomain; cdecl;
//function getResource(resourceName: JString): JURL; cdecl;
function getResourceAsStream(resourceName: JString): JInputStream; cdecl;
function getSigners: TJavaObjectArray<JObject>; cdecl;
function getSimpleName: JString; cdecl;
function getSuperclass: JOwnLang_Class; cdecl;
function getTypeParameters: TJavaObjectArray<JTypeVariable>; cdecl;
function isAnnotation: Boolean; cdecl;
function isAnnotationPresent(annotationType: JOwnLang_Class): Boolean; cdecl;
function isAnonymousClass: Boolean; cdecl;
function isArray: Boolean; cdecl;
function isAssignableFrom(c: JOwnLang_Class): Boolean; cdecl;
function isEnum: Boolean; cdecl;
function isInstance(object_: JObject): Boolean; cdecl;
function isInterface: Boolean; cdecl;
function isLocalClass: Boolean; cdecl;
function isMemberClass: Boolean; cdecl;
function isPrimitive: Boolean; cdecl;
function isSynthetic: Boolean; cdecl;
function newInstance: JObject; cdecl;
function toString: JString; cdecl;
end;
TJOwnLang_Class = class(TJavaGenericImport<JOwnLang_ClassClass, JOwnLang_Class>) end;
implementation
end.
Thirdly, you must enable items PROCESS_OUTGOING_CALL and READ_PHONE_STATE in the Uses Permissions
Fourth, you must create the code for Form1:
unit Unit1;
interface
uses
System.SysUtils,
System.Types,
System.UITypes,
System.Classes,
System.Variants,
FMX.Types,
FMX.Controls,
FMX.Forms,
FMX.Graphics,
FMX.Dialogs,
FMX.Controls.Presentation,
FMX.ScrollBox,
FMX.Memo,
CSBroadcastReceiver,
Androidapi.JNI.JavaTypes.Own,
Androidapi.Jni,
AndroidApi.JNI.GraphicsContentViewText,
Androidapi.Jni.JavaTypes,
Androidapi.JNI.Os,
Androidapi.JNIBridge,
Androidapi.JNI.Telephony;
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
procedure CreateBroadcastReceiver;
procedure BroadcastReceiverOnReceive(csContext: JContext; csIntent: JIntent);
procedure CheckPhoneCallState(Context: JContext; Intent: JIntent);
function KillCall(Context: JContext): Boolean;
public
{ Public declarations }
end;
var
Form1: TForm1;
BroadcastReceiver: TCSBroadcastReceiver;
implementation
uses
Androidapi.Jni.App, Androidapi.Helpers, Androidapi.Log;
{$R *.fmx}
procedure TForm1.CreateBroadcastReceiver;
begin
if not Assigned(BroadcastReceiver) then
begin
BroadcastReceiver:= TCSBroadcastReceiver.Create(nil);
BroadcastReceiver.OnReceive:= BroadcastReceiverOnReceive;
BroadcastReceiver.RegisterReceive;
BroadcastReceiver.Add('android.intent.action.PHONE_STATE');
BroadcastReceiver.Add('android.intent.action.NEW_OUTGOING_CALL');
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if Assigned(BroadcastReceiver) then
BroadcastReceiver.Free;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
CreateBroadcastReceiver;
end;
procedure TForm1.BroadcastReceiverOnReceive(csContext: JContext; csIntent: JIntent);
begin
CheckPhoneCallState(csContext, csIntent);
end;
procedure TForm1.CheckPhoneCallState(Context: JContext; Intent: JIntent);
var
telephonyService: JObject;
telephonyManager: JTelephonyManager;
state: JString;
incomingCallNumber: string;
outgoingCallNumber: string;
outputResult: string;
begin
outputResult:= #13#10;
telephonyService := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.TELEPHONY_SERVICE);
telephonyManager := TJTelephonyManager.Wrap((telephonyService as ILocalObject).GetObjectID);
if JStringToString(Intent.getAction).Equals('android.intent.action.PHONE_STATE') then
begin
state:= Intent.getStringExtra(TJTelephonyManager.JavaClass.EXTRA_STATE);
if state.equals(TJTelephonyManager.JavaClass.EXTRA_STATE_IDLE) then
outputResult:= outputResult + 'Phone is IDLE ' + #13#10
else if state.equals(TJTelephonyManager.JavaClass.EXTRA_STATE_RINGING) then
begin
incomingCallNumber:= JStringToString(Intent.getStringExtra(TJTelephonyManager.JavaClass.EXTRA_INCOMING_NUMBER));
if incomingCallNumber.Equals('') then
incomingCallNumber:= 'PRIVATE NUMBER';
outputResult:= outputResult + 'Phone is RINGING' + #13#10;
outputResult:= outputResult + 'Incoming call from ' + incomingCallNumber + #13#10;
if incomingCallNumber = 'xyz' then
if KillCall(Context) then
outputResult:= outputResult + 'Call was terminated' + #13#10
else
outputResult:= outputResult + 'Call was not terminated' + #13#10;
end
else if state.equals(TJTelephonyManager.JavaClass.EXTRA_STATE_OFFHOOK) then
outputResult:= outputResult + 'Phone is OFFHOOK' + #13#10;
end
else if JStringToString(Intent.getAction).Equals('android.intent.action.NEW_OUTGOING_CALL') then
begin
outgoingCallNumber:= JStringToString(Intent.getStringExtra(TJIntent.JavaClass.EXTRA_PHONE_NUMBER));
outputResult:= outputResult + 'Outgoing call to ' + outgoingCallNumber + #13#10;
if outgoingCallNumber = 'xyz' then
begin
BroadcastReceiver.SetResultData(nil);
outputResult:= outputResult + 'Call is not allowed to ' + outgoingCallNumber + #13#10;
end;
end;
Memo1.Lines.Append(outputResult);
end;
function TForm1.KillCall(Context: JContext): Boolean;
var
telephonyService: JObject;
classTelephony: JOwnLang_Class;
methodGetITelephony: JOwnMethod;
telephonyInterface: JObject;
telephonyInterfaceClass: JOwnLang_Class;
methodEndCall: JOwnMethod;
begin
try
telephonyService:= TAndroidHelper.Context.getSystemService(TJContext.JavaClass.TELEPHONY_SERVICE);
classTelephony := TJOwnLang_Class.JavaClass.forName(telephonyService.getClass.getName);
methodGetITelephony:= classTelephony.getDeclaredMethod(StringToJString('getITelephony'), nil);
methodGetITelephony.setAccessible(True);
telephonyInterface := methodGetITelephony.invoke(telephonyService, nil);
telephonyInterfaceClass := TJOwnLang_Class.JavaClass.forName(telephonyInterface.getClass.getName);
methodEndCall:= telephonyInterfaceClass.getDeclaredMethod(StringToJString('endCall'), nil);
methodEndCall.invoke(telephonyInterface, nil);
Result:= True;
except
on E: Exception do
begin
Result := False;
end;
end;
end;
end.
Complete demo code you can download here.
Related Topics
Playing an Arbitrary Tone With Android
How to Parse the Androidmanifest.Xml File Inside an .Apk Package
How to Use Scrollview in Android
Android Get Free Size of Internal/External Memory
Why Does Layoutinflater Ignore the Layout_Width and Layout_Height Layout Parameters I'Ve Specified
How to Make the Corners of a Button Round
How to Add Calendar Events in Android
How to Programmatically Tell If a Bluetooth Device Is Connected
How to Hide Soft Keyboard on Android After Clicking Outside Edittext
Animate Change of View Background Color on Android
How to Develop a Soft Keyboard For Android