2014-06-13

Install Android NDK on Windows

1. Download Android NDK

  • Download latest version of NDK from http://developer.android.com/tools/sdk/ndk/index.html 
  • Decompress it and put NDK folder anywhere you want. For my example: D:\SDK\android-ndk-r9d
2. Install CDT for Eclipse
  • Open Eclipse, Help-->Install New Software
  • Press "Add"
  • Name: CDT(whatever you want), Location: http://download.eclipse.org/tools/cdt/releases/kepler
  • Check "CDT Main features"
  • Press Next to install.
3. Install NDK Plugin for Eclipse
  • Open Eclipse, Help-->Install New Software
  • Search for https://dl-ssl.google.com/android/eclipse/ in "Work with", if you can't find one, just press "Add" to add it.
  • Check "NDK plugins"
  • Press Next to install.
4. Setup NDK
  • Restart Eclipse, if you just complete all steps above.
  • Window-->Preferences-->Android-->NDK
  • Enter the NDK decompressed path, for my example: D:\SDK\android-ndk-r9d
5. Install Cygwin
  • Download latest version of Cygwin from http://www.cygwin.com
  • Execute setup.exe you downloaded.
  • Next-->Select "Install from Internet"
  • Select your Root Directory, in my example: C:\cygwin64\
  • Next-->Local Package Directory
  • Next-->Next-->select a download server
  • Next-->Start to download and install
  • When Select Packages, please change "Devel" to "Install"
  • Next-->Finish
  • How to verify your cygwin:
A. Go to your cygwin installed path (Root Directory), for my example: C:\cygwin64\
B. Execute C:\cygwin64\cygwin.bat
make -v
You should see your GNU Make version.
gcc -v
You should see your gcc version.


Finished, you can build your JNI now!!!!!

2014-01-22

Force Android MTP database refresh if file in storage changed

Method 1.
Old method, not recommended.
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
    Uri.parse("file://" + Environment.getExternalStorageDirectory())));
Force whole SDCard rescan.
Side-effect: Some devices will force close or cause System UI exception.

Method 2.
Send intent to scan specific file
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
You need a for loop or recursive call if your target is a directory.

Method 3.
Similar with method 2, but do your Media scan by yourself.
public class MediaScanner implements MediaScannerConnectionClient {
private MediaScannerConnection mScanner;
private File mFile;
public MediaScanner(Context context, File file) {
   mFile = file;
   mScanner = new MediaScannerConnection(context, this);
   mScanner.connect();
}
@Override
public void onMediaScannerConnected() {
   mScanner.scanFile(mFile.getAbsolutePath(), null);
}
@Override
public void onScanCompleted(String path, Uri uri) {
   mScanner.disconnect();
}
}
public class YourClass {
    ...
    new MediaScanner(context, file);
    ...
}
Same as method 2, you need a for loop or recursive call if your target is a directory.
Suggest to use Thread or ExecutorService for a better performance.

2013-11-29

VobSub.dll is missing or can't be found error on Win7 64-bit

Execute VobSub with error "vobsub.dll is missing or can't be found" on Win7 64-bit.
This is due to 32-bit dll with be put into System32 folder, but 64-bit will be in SysWOW64. Solution is to modify the shortcut of vobsub.
For example, VobSub cutter:
C:\Windows\System32\rundll32.exe vobsub.dll,Cutter
Change to
C:\Windows\SysWOW64\rundll32.exe vobsub.dll,Cutter
The solution also can be applied to VobSub cutter, VobSub joiner, VobSub configure and DirectVobSub configure.

2013-11-19

Android API to unlock device and turn the screen on.

When you doing a notification or some like incoming call application. You usually need to unlock device and turn the screen on to let user seeing your notification. What you need is to disable keyguard and make a wake lock.

Disable keyguard (Unlock device)
KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
KeyguardLock kl = km.newKeyguardLock("MyKeyguardLock");
kl.disableKeyguard();
Also remember to add permission to your AndroidManifest.xml
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> 

Acquire wake lock
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "MyWakeLock");
mWakeLock.acquire();
Don't forget to release wake lock when your notification disabled.
mWakeLock.release();
The permission you need for wake lock:
<uses-permission android:name="android.permission.WAKE_LOCK" />

2013-09-14

Remote root access permission for MySQL server on Ubuntu

After install mysql server on Ubuntu.

Enter mysql console by root
mysql -u root
Set password for root
SET PASSWORD FOR 'ROOT'@'LOCALHOST'
= PASSWORD('my_root_password');
Grant remote permission for root
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'
IDENTIFIED BY 'my_root_password' WITH GRANT OPTION;
Flush setting
FLUSH PRIVILEGES;
Exit mysql console
exit
Edit mysql config file
vi /etc/mysql/my.conf
Search for keyword bind-address, make sure your mysql service can be access by your local PC.
bind-address = 0.0.0.0 

2013-07-26

How to cast a List of Objects to another type in Java

For example, if you have:
class Father{}
class Son extends Father{}
Now you're going to do like:
void doSomething(List<Father> list){}
doSomething(new ArrayList<Son>());
This won't work because you can't cast a generic type of one parameter to another. Java will give to you compile error.
Solution is to use wildcard type:
void doSomething(List<?> list){
  List<Parent> parents = (List<Parent>)list;

2013-07-23

Android API to get Activity name of current top Application

ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List< ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(1);
Log.d(TAG, "Current activity: "+taskInfo.get(0).topActivity.getClassName());
ComponentName componentInfo = taskInfo.get(0).topActivity;
Log.d(TAG, "Current top application: "+componentInfo.getPackageName());