Sunday, October 6, 2013

How do I troubleshoot boot problems when stuck at the Ubuntu splash screen?

http://askubuntu.com/questions/306543/how-do-i-troubleshoot-boot-problems-when-stuck-at-the-ubuntu-splash-screen


Besides the below, if the GUI does not start automatically, run "sudo apt-get install ubuntu-desktop" and then "sudo reboot".

Some keys to remember.
Alt + left arrow turns the boot splash into terminal login prompt during the boot.
Ctrl + Alt + F1 switches back to the command prompt from GUI.



How do I troubleshoot boot problems when stuck at the Ubuntu splash screen?

I was tweaking some settings on my Ubuntu 12.04 install. Specifically I was altering the default color scheme of the terminal, following these instructions
Now whenever I boot Ubuntu, I get stuck in the purple screen that says "Ubuntu" with the moving dots. If I hit ENTER Ubuntu booting continues.
I'm not asking about solving my specific problem (which is definitely caused my be doing weird things) instead I'm asking how would I go about digging into what's going on at boot? What logs should I look at? What kind of thing should I look for? How would I troubleshoot this issue? I would like to "learn how to fish" and go figure out what is probably a stupid issue.
I tried the boot repair utility, however that does not appear to do the trick. Boot repair appears to be focussed more on GRUB, which is functioning fine.
share|improve this question



There's a few things you can try. First, if I were you, I'd like to know what's happening in the background (booting in) that causes you to have to hit Enter to get it to continue on.
Try editing your GRUB load manually, so you can see what's happening during the boot and provide the error/issue that's actually happening in more detail. In a terminal window, run:
gksudo gedit /etc/default/grub
Find this line:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
and change it to:
GRUB_CMDLINE_LINUX_DEFAULT=""
Leave anything else within the quotes as-is, but remove the quiet splash portion.
Then, do, in terminal:
sudo update-grub
Then, finally just reboot. Now.. see all the loading data, and let us know what the actual problem is.
share|improve this answer

Thursday, October 3, 2013

Restore screen size and position in gVim

http://vim.wikia.com/wiki/Restore_screen_size_and_position


Copy & paste the following codes to your _gvimrc or .gvimrc.
It works good.


Restore screen size and position

 Talk0
1,603PAGES ON
THIS WIKI
Tip 1569 Printable Monobook Previous Next
created 2008 · complexity basic · author Dfishburn · version 7.0

This tip is useful if you always want Vim to startup in the same location and size as the time you exit it. Most applications (i.e. FireFox) do this already. Another reason to use this tip is if you often have more than one Vim (GUI on Windows) running. Quite often I will have one per project, each instance editing multiple buffers. When I start Vim, I name it (based on the project or tool I launched it from).
gvim myFile1 myFile2
gvim --servername MyProject filename1 filename2 filename3
gvim --servername VS_NET filename
When I re-open Vim I like its screen position and size to be the same as they were when Vim was closed. The scripts below can be added to your .vimrc file. They offer 2 configuration options which can be set at the bottom before the autocmds:
" To enable the saving and restoring of screen positions.
let g:screen_size_restore_pos = 1

" To save and restore screen for each Vim instance.
" This is useful if you routinely run more than one Vim instance.
" For all Vim to use the same settings, change this to 0.
let g:screen_size_by_vim_instance = 1

Version 1 (Vim 7 and above)Edit

This version uses Vim's readfile() and writefile() functions to access the file used to save the size/position. That in addition to the use of the split() function makes this version unusable in Vim 6.x.
if has("gui_running")
  function! ScreenFilename()
    if has('amiga')
      return "s:.vimsize"
    elseif has('win32')
      return $HOME.'\_vimsize'
    else
      return $HOME.'/.vimsize'
    endif
  endfunction

  function! ScreenRestore()
    " Restore window size (columns and lines) and position
    " from values stored in vimsize file.
    " Must set font first so columns and lines are based on font size.
    let f = ScreenFilename()
    if has("gui_running") && g:screen_size_restore_pos && filereadable(f)
      let vim_instance = (g:screen_size_by_vim_instance==1?(v:servername):'GVIM')
      for line in readfile(f)
        let sizepos = split(line)
        if len(sizepos) == 5 && sizepos[0] == vim_instance
          silent! execute "set columns=".sizepos[1]." lines=".sizepos[2]
          silent! execute "winpos ".sizepos[3]." ".sizepos[4]
          return
        endif
      endfor
    endif
  endfunction

  function! ScreenSave()
    " Save window size and position.
    if has("gui_running") && g:screen_size_restore_pos
      let vim_instance = (g:screen_size_by_vim_instance==1?(v:servername):'GVIM')
      let data = vim_instance . ' ' . &columns . ' ' . &lines . ' ' .
            \ (getwinposx()<0?0:getwinposx()) . ' ' .
            \ (getwinposy()<0?0:getwinposy())
      let f = ScreenFilename()
      if filereadable(f)
        let lines = readfile(f)
        call filter(lines, "v:val !~ '^" . vim_instance . "\\>'")
        call add(lines, data)
      else
        let lines = [data]
      endif
      call writefile(lines, f)
    endif
  endfunction

  if !exists('g:screen_size_restore_pos')
    let g:screen_size_restore_pos = 1
  endif
  if !exists('g:screen_size_by_vim_instance')
    let g:screen_size_by_vim_instance = 1
  endif
  autocmd VimEnter * if g:screen_size_restore_pos == 1 | call ScreenRestore() | endif
  autocmd VimLeavePre * if g:screen_size_restore_pos == 1 | call ScreenSave() | endif
endif

Version 2 (Vim 6 and above)Edit

Here is an alternative script which uses a regular Vim buffer to manipulate the vimsize file instead of Vim 7's readfile() and writefile() functions.
" Restore screen size and position
" Saves data in a separate file, and so works with multiple instances of Vim.
if has("gui_running")
  function! ScreenFilename()
    if has('amiga')
      return "s:.vimsize"
    elseif has('win32')
      return $HOME.'\_vimsize'
    else
      return $HOME.'/.vimsize'
    endif
  endfunction

  function! ScreenRestore()
    " - Remembers and restores winposition, columns and lines stored in
    "   a .vimsize file
    " - Must follow font settings so that columns and lines are accurate
    "   based on font size.
    if !has("gui_running")
      return
    endif
    if g:screen_size_restore_pos != 1
      return
    endif
    let vim_instance = (g:screen_size_by_vim_instance==1?(v:servername):'GVIM')
    " read any existing variables from .vimsize file
    silent! execute "sview " . escape(ScreenFilename(),'%#\ $')
    silent! execute "0/^" . vim_instance . " /"
    let vim_name  = matchstr(getline('.'), '^\w\+')
    let vim_cols  = matchstr(getline('.'), '^\w\+\s\+\zs\d\+')
    let vim_lines = matchstr(getline('.'), '^\w\+\s\+\d\+\s\+\zs\d\+')
    let vim_posx  = matchstr(getline('.'), '^\w\+\s\+\d\+\s\+\d\+\s\+\zs\d\+')
    let vim_posy  = matchstr(getline('.'), '^\w\+\s\+\d\+\s\+\d\+\s\+\d\+\s\+\zs\d\+')
    if vim_name == vim_instance
      execute "set columns=".vim_cols
      execute "set lines=".vim_lines
      silent! execute "winpos ".vim_posx." ".vim_posy
    endif
    silent! q
  endfunction

  function! ScreenSave()
    " used on exit to retain window position and size
    if !has("gui_running")
      return
    endif
    if !g:screen_size_restore_pos
      return
    endif
    let vim_instance = (g:screen_size_by_vim_instance==1?(v:servername):'GVIM')
    silent! execute "split " . escape(ScreenFilename(),'%#\ $')
    silent! execute "0/^" . vim_instance . " /"
    let vim_name  = matchstr(getline('.'), '^\w\+')
    if vim_name == vim_instance
      delete _
    endif
    $put = vim_instance . ' ' . &columns . ' ' . &lines . ' ' .
          \ (getwinposx()<0?0:getwinposx()) . ' ' .
          \ (getwinposy()<0?0:getwinposy())
    silent! x!
  endfunction

  if !exists('g:screen_size_restore_pos')
    let g:screen_size_restore_pos = 1
  endif
  if !exists('g:screen_size_by_vim_instance')
    let g:screen_size_by_vim_instance = 1
  endif
  autocmd VimEnter * call ScreenRestore()
  autocmd VimLeavePre * call ScreenSave()
endif

CommentsEdit

Feel free to add comments here for script improvements.
For the Version 2 script, since it uses Vim buffers for the manipulations it would be useful to disable all autocmds before opening splitting the buffer and re-enable them when closing the buffer. Many people have lots of plugins installed which can make opening buffers somewhat expensive (and therefore unnecessary time delay). Using the Vim 7 readfile() and writefile() functions avoid this overhead.

Android Source Repo GPG public key not found

http://stackoverflow.com/questions/19126603/android-source-repo-gpg-public-key-not-found
\
the guide about repo on source.android.com fails.
Getting another repo is the answer.



Android Source Repo GPG public key not found

I am running Linux Mint 14 and trying to download the android source. I followed the instruction for setting up the environment and when I was trying to get the source with repo, I got the following error.
...
 * [new tag]         v1.9.4     -> v1.9.4
 * [new tag]         v1.9.5     -> v1.9.5
 * [new tag]         v1.9.6     -> v1.9.6

object e76efdd7b342577c40aa271fa5ded9d66a783a9b
type commit
tag v1.12.4
tagger Conley Owens <cco3@android.com> 1380645867 -0700

repo 1.12.4

gpg: Signature made Tue 01 Oct 2013 09:44:27 AM PDT using RSA key ID 692B382C
gpg: Can't check signature: public key not found
error: could not verify the tag 'v1.12.4'
I've tried importing the public key from the instruction, try generating my own GPG keys, as well as symbolic linking the directories ~/.gnupg and ~/.repoconfig/gnupg both ways and I still get the same error. I also tried to deleting the ~/.repoconfig and ~/.gnupg and still no luck.
Any help would be appreciated.
share|improve this question
I'm having the same issue. Tried alot of different solutions mentioned everywhere: delete the repoconfig dir, import a key, git tag -v 1.12.4 can't wrap my head aroundMarijn yesterday
i found a solution here:http://www.marshut.com/wrrts/repo-release-1-12-4.html
[quote] Sorry, I realized today that we didn't upload the newest version of the launcher. I'll update the documentation. For the meantime, please use:
curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > ~/bin/repo chmod a+x ~/bin/repo
sha1 e197cb48ff4ddda4d11f23940d316e323b29671c
If verification errors persist, you can blow away (or move) your ~/.repoconfig dir to ensure the new public keys are imported.
Sorry for the trouble everyone! [/quote]
share|improve this answer
yup, that fixed it...YTKColumba yesterday
seems that repo 1.12.4 was only released a few hours agoMarijn yesterday
Seconding (thirding?) this. Replaced the installed version (and B2G version) of repo with this and things are back up and running.Jostein Kjønigsen yesterday

Wednesday, October 2, 2013

How MMS, Multi-media Messaging Service works ?

From wikipedia...only technical part is cited.
http://en.wikipedia.org/wiki/Multimedia_Messaging_Service

Some key points are...
1. MMSC(Multimedia Messaging Service Centre) works as the core function.
2. The end-most system in carrier-side is HTTP-capable.
3. Using SMS control-channel, carrier network checks the capability of mobile user's handset for MMS. Url for the MMS is contained in the SMS control message.
4. The MMS-capable handset will pull the MMS content from carrier network using MMS URL.
5. The MMS-incapable handset may receive the MMS URL as SMS text body, which can be a link to a web browser.
6. MMS may be encoded in MIME or MIME-like format and may be converted into other format by carrier network function so that the mobile user handset can process.

fyi

Technical description[edit]

MMS messages are delivered in a completely different way from SMS. The first step is for the sending device to encode the multimedia content in a fashion similar to sending a MIME e-mail (MIME content formats are defined in the MMS Message Encapsulation specification). The message is then forwarded to the carrier's MMS store and forward server, known as the MMSC (Multimedia Messaging Service Centre). If the receiver is on another carrier, the relay forwards the message to the recipient's carrier using the Internet.[5]
Once the MMSC has received a message, it first determines whether the receiver's handset is "MMS capable", that it supports the standards for receiving MMS. If so, the content is extracted and sent to a temporary storage server with an HTTP front-end. An SMS "control message" containing the URL of the content is then sent to the recipient's handset to trigger the receiver's WAP browser to open and receive the content from the embedded URL. Several other messages are exchanged to indicate status of the delivery attempt.[6] Before delivering content, some MMSCs also include a conversion service that will attempt to modify the multimedia content into a format suitable for the receiver. This is known as "content adaptation".
If the receiver's handset is not MMS capable, the message is usually delivered to a web based service from where the content can be viewed from a normal internet browser. The URL for the content is usually sent to the receiver's phone in a normal text message. This behaviour is usually known as the "legacy experience" since content can still be received by a phone number, even if the phone itself does not support MMS.
The method for determining whether a handset is MMS capable is not specified by the standards. A database is usually maintained by the operator, and in it each mobile phone number is marked as being associated with a legacy handset or not. It can be a touch 'hit or miss', since customers can change their handset at will and this database is not usually updated dynamically.
MMS does not utilize one's own operator maintained data plan to distribute multimedia content. Operator maintained data plans are only used when message included links (if any) are explicitly clicked.
E-mail and web-based gateways to the MMS (and SMS) system are common. On the reception side, the content servers can typically receive service requests both from WAP and normal HTTP browsers, so delivery via the web is simple. For sending from external sources to handsets, most carriers allow MIME encoded message to be sent to the receiver's phone number with a special domain. An example of this would be PTN@messaging.carrier.com, where PTN is the public telephone number. Typically the special domain name is carrier specific.

Tuesday, September 24, 2013

How to resolve the problem when Ubuntu on VMWare cannot get the ip address.

Ubuntu 3.8.0 64-bit installed on VMWare 9 could not get the ip address.

Network is configured as DHCP in Ubuntu and the bridge mode is set on VMWare VM configuration.
At first run, it worked and even samba service with Windows 7, the host OS worked successfully.

Today it does not work at all and no ip address is acquired when I checked with 'ifconfig' command.
Shutting down and restarting the VM was not the solution.

Googling told me the answer.

Set the /etc/network/interfaces file as follows.
============================
auto eth0
iface eth0 inet dhcp
============================

There was "lo" instead of "eth0".
Still I don't understand why it worked before and now I have to change the above file.

In some linux, the file is /etc/networking/interfaces, the google told.

Thanks, Google.

Sunday, September 22, 2013

ODEX decompilation

ODEX is an Optimized DEX, which means a .odex file is a runtime instance of the dalvik byte code binary .dex file.
Usually .dex file exists inside of .apk and it turns into .odex when running and stored in the dalvik cache. If the binary file exists in the form of .odex file, then it exists outside of .apk file and it is not stored in the dalvik cache. .odex file can boost the initial loading performance of android app.

To decompile .dex files
1. Convert .dex file into .jar file using dex2jar utility.
2. Look into .jar file using jd-gui
   or extract .jar file into .class files and convert .class files into .java files using jad utility.


To decompile .odex files, you need some prior steps changing .odex file into .dex file.

0. prerequisites
   - baksmali.jar & smali.jar from http://code.google.com/p/smali/downloads/list
   - system/framework folder and the files in it.(This is usually included in the system.img of rom images.)
   - Of course, the target .odex file.(for example "target_sample.odex")

 1. Convert .odex file into Smali format files using baksmali utility.
    java -jar baksmali.jar -d system/framework -x target_sample.odex
   -Here baksmali.jar filename may be changed depending on the file name and the version of baksmali.
   - "system/framework" folder may be different depending on the place where you put it.
   - Then the Smali formatted files are generated in the "out" folder.

 2. Bind the smali formatted files into .dex file.
    java -jar smali.jar -o classes.dex out
   -Here smali.jar filename may be changed depending on the file name and the version of smali.
   - "-o" option is for designating the output file name of .dex file, so you can change the classes.dex into anything you want.
   - the last "out" is the folder name generated in the prior step.


Now you have the .dex file and you can proceed the dex/java decompilation.




=======================================================================
Here I wrote a batch file script for the above steps.

Put a .odex file & framework folder and run the script.
Then the decompilation of .odex-->.dex-->.jar-->.java is done at one shot.

All the result and the related files are saved into a folder given as the argument of the script.
The argument should be the name of .odex file without the extension .odex.

The assumptions are as follows.
0. In Windows7 environment, jdk is installed.(Test with jdk 1.7.0_25)
1. dex2jar-0.0.9.13 folder exists. Of course dex2jar.bat should be there.
2. baksmali-2.0b6.jar exists.
3. jad.exe exists.
4. smali-2.0b6.jar exists.
5. Save the below script as odex2jard.bat.
(If some files have different version, then the script should be revised accordingly.)
===========================Start of script ================================
@echo off
if x%1x == xx (
echo ....................................
echo No argument.
echo ....................................
goto usage
)
if not exist .\%1.odex (
echo ....................................
echo %1.odex file does not exist.
echo ....................................
goto usage
)
if exist .\%1.dex (
echo ....................................
echo %1.dex file exists.
echo Move or remove existing %1.dex file.
echo ....................................
goto usage
)
if exist .\%1_dex2jar (
echo ....................................
echo %1_dex2jar folder exists.
echo Move or remove existing %1_dex2jar folder.
echo ....................................
goto usage
)
if exist .\%1_dex2jar.jar (
echo ....................................
echo %1_dex2jar.jar file exists.
echo Move or remove existing %1_dex2jar.jar file.
echo ....................................
goto usage
)
if exist .\%1 (
echo ....................................
echo The result is saved into %1 folder.
echo Move or remove existing %1 folder.
echo ....................................
goto usage
)
if exist .\out (
echo ....................................
echo "out" folder is used as temp.
echo Move or remove "out" folder.
echo ....................................
goto usage
)
if not exist .\framework (
echo ....................................
echo No "framework" folder!!
echo The framework folder should be right here.
echo Cautious not to be system/framework!!
echo ....................................
goto usage
)
java -jar baksmali-2.0b6.jar -d framework -x %1.odex
java -jar smali-2.0b6.jar -o %1.dex out
rmdir /S /Q .\out
call .\dex2jar-0.0.9.13\dex2jar.bat %1.dex
mkdir %1_dex2jar
cd %1_dex2jar
jar xvf ..\%1_dex2jar.jar
cd ..
.\jad -o -d %1_dex2jar -r -s java %1_dex2jar/**/*.class
mkdir %1
move .\framework %1
move .\%1.odex %1
move .\%1.dex %1
move .\%1_dex2jar.jar %1
move .\%1_dex2jar %1
echo ....................................
echo DONE !!
echo ....................................
goto :eof
:usage
echo .
echo Usage:
echo ....................................
echo odex2jard.bat "target_filename"
echo ....................................
echo No file extension at "target_filename"
echo eg) For abc.odex, type as follows
echo odex2jard.bat abc
echo ....................................
goto :eof

=========================== Endof script =================================

Most frequently used jad command options as a batch file.

jad and jd-gui are usually used to decompile java classes.
When using jad, all the class files in the directory structure need to be decomplied at once.
So I wrote a batch file working in the cmd window of Windows environment.

Copy the following lines and save them as jad.bat.
Run jad.bat with the only argument, the target directory name. All the class files should be unzipped under the target directory in advance.

@echo off
if x%1x == xx (
        echo .
        echo Usage:
        echo ....................................
        echo         jad.bat "target_dir"
        echo ....................................
        goto :eof
)
.\jad -o -d %1 -r -s java %1/**/*.class

You don't need to remember all the options of jad and don't need to revisit them every time you try.
You can write down the script for *nix family easily.

Thanks.

How to read .rfs files, a form of android rom images.

To inspect the .rfs files you only need a linux and the followung simple command.

# mount -o loop factory.rfs /target_dir

Here factory.rfs is the rom image file and the target_dir is the directory you want to mount the .rfs image.



I've tested this on my Ubuntu 3.8.0 64-bit running as a guest OS on VMWare 9.

This command line requires the root privilege.
So in fact, I have typed the following command.

# sudo mount -o loop factoryrfs.rfs ./rfs

The rom image file name was factoryrfs.rfs and the target directory was rfs under the current directory.

Saturday, September 21, 2013

How to enable Korean language input keyboard on Ubuntu

http://xmodulo.com/2012/11/how-to-enable-korean-language-input-on-ubuntu.html


How to enable Korean language input keyboard on Ubuntu

If you would like to use foreign language input on Ubuntu, there are two ways to enable foreign language input. One method is using Smart Common Input Method platform (SCIM), and the other one is to use Intelligent Input Bus (iBus).
SCIM is the original input method used to support dozens of different foreign languages in Ubuntu prior to Ubuntu version 9.10. However, SCIM is known to be somewhat unstable, may unduly eat up system resources, and could demand re-install from time to time.
iBus is a new input method platform designed to overcome some of the limitations of SCIM. Unlike SCIM, iBus has separate iBus daemon and client processes (e.g., input engines and configuration tools), and loads any necessary engine on demand. As such, iBus improves the modularity and stability of the input system, as well as save on startup time and memory footprint. iBus is the default input method framework in use for Ubuntu 10.04 (Lucid) and higher.
If you would like to enable Korean language input on Ubuntu, you can use either SCIM or iBus, depending on your Ubuntu version.

Enable Korean language input on Ubuntu 9.04 and lower

Go to “System Settings” -> “Keyboard”. Click on “Layout Settings”. Click on “+” at the bottom to add Korean keyboard layout.
Now, install scim as follows.
$ sudo apt-get install scim-hangul
Log out and log in again. Go to “System Settings” -> “Language Support”. Choose scim-bridge in Keyboard input method system. Finally reboot.
At this point, you can now switch between English and Korean by pressing Ctrl+Space.

Enable Korean language input on Ubuntu 9.10 and higher

Although you can still use SCIM on newer versions of Ubuntu, it is recommended that you use iBus for reasons mentioned above. Note that if you have installed SCIM on your system before, you need to completely remove all SCIM-related packages (e.g., search for “SCIM” using synaptic), before installing iBus. The following guide on using iBus has been tested on Ubuntu 12.10 Desktop.
To install iBus, go to “System Settings” -> “Language Support”. Click on “Install/Remove Language”. Choose “Korean” language, and install it.
After having installed Korean language, choose “ibus” for Keyboard input method system in the same “Language Support” window.
On Ubuntu Dashboard, search for “Keyboard input methods”, and launch it. Under “Input Method” tab, click on “Customize active input methods”, and add “Korean” to input method. Under “General” tab, you can configure keyboard shortcuts to toggle between English and Korean. The default keyboard shortcut is Ctrl+Space.
If you would like to configure Hangul keyboard (e.g., dubeolsik, sebeolsik, etc), search for “IBus Hangul Preferences” in Ubuntu dashboard, and launch it to do that.
At this point, you can now toggle between English and Korean by pressing Ctrl+Space.

Android audio articles & etc - http://shadowxx.egloos.com/category/%EC%BB%B4%EB%B6%80%EB%A6%AC%20%EC%9D%B4%EC%95%BC%EA%B8%B0

http://shadowxx.egloos.com/category/%EC%BB%B4%EB%B6%80%EB%A6%AC%20%EC%9D%B4%EC%95%BC%EA%B8%B0

though most of them are in Korean.

Compiling simg2img and make_ext4fs from Android v4.2.1 sources

http://muzso.hu/2012/08/10/how-to-pack-and-unpack-system.img-and-userdata.img-from-an-android-factory-image#comment-1678

gcc compiling option should be re-located, which is supposed to depends on the computer environment.


Compiling simg2img and make_ext4fs from Android v4.2.1 sources

The process is a bit different now.
Let's assume that the $AOSP_ROOT variable points to our AOSP root (eg. export AOSP_ROOT="$HOME/Android/AOSP").

  1. Download the https://android.googlesource.com/platform/system/core repository:
    cd "$AOSP_ROOT"
    [ ! -d "platform/system" ] && mkdir -p platform/system
    cd platform/system
    git clone https://android.googlesource.com/platform/system/core
  2. Check out a revision of your choice:
    cd core
    git checkout android-4.2.1_r1
  3. Compile simg2img:
    cd libsparse
    gcc -o simg2img -Iinclude -lz simg2img.c sparse_crc32.c backed_block.c output_file.c sparse.c sparse_err.c sparse_read.c

    gcc -o simg2img -Iinclude simg2img.c sparse_crc32.c backed_block.c output_file.c sparse.c sparse_err.c sparse_read.c -lz
    (When compiling, the link option should come at last on my computer. If not "undefined reference to xxxx" errors happened.)
The unpacking is quite the same:
  • Unpack your Android image files (of course you should adjust the commands for the correct path to the IMG files):
    cd ../../
    ./core/libsparse/simg2img system.img system.raw.img
    ./core/libsparse/simg2img userdata.img userdata.raw.img
  • Do whatever you want with the images (eg. you can use Paragon's ExtFS on a Mac or just simply mount the images in linux via the loop device). Eg.
    mkdir /mnt/my_system /mnt/my_userdata
    mount -t ext4 -o loop system.raw.img /mnt/my_system
    mount -t ext4 -o loop userdata.raw.img /mnt/my_userdata
And the compilation of make_ext4fs did get more complicated too:
  1. Download the https://android.googlesource.com/platform/system/extras repository:
    cd "$AOSP_ROOT/platform"
    [ ! -d "system" ] && mkdir system
    cd system
    git clone https://android.googlesource.com/platform/system/extras
  2. Check out a revision of your choice:
    cd extras
    git checkout android-4.2.1_r1
  3. Compile make_ext4fs:
    cd ..
    gcc -o make_ext4fs -Icore/libsparse/include -lz extras/ext4_utils/make_ext4fs_main.c extras/ext4_utils/make_ext4fs.c extras/ext4_utils/ext4fixup.c extras/ext4_utils/ext4_utils.c extras/ext4_utils/allocate.c extras/ext4_utils/contents.c extras/ext4_utils/extent.c extras/ext4_utils/indirect.c extras/ext4_utils/uuid.c extras/ext4_utils/sha1.c extras/ext4_utils/wipe.c core/libsparse/backed_block.c core/libsparse/output_file.c core/libsparse/sparse.c core/libsparse/sparse_crc32.c core/libsparse/sparse_err.c core/libsparse/sparse_read.c
And the repacking is all the same too:
PATH="$PATH:$(pwd)" ./extras/ext4_utils/mkuserimg.sh -s /mnt/my_system_dir my_system.img ext4 /tmp 512M

How To Install Git on Ubuntu 12.04

https://www.digitalocean.com/community/articles/how-to-install-git-on-ubuntu-12-04


How To Install Git on Ubuntu 12.04

What the Red Means

The lines that the user needs to enter or customize will be in red in this tutorial!

The rest should mostly be copy-and-pastable.

About Git


Git is a distributed version control system released to the public in 2005. The program allows for non-linear development of projects, and can handle large amounts of data effectively by storing it on the local server.

This tutorial will cover two ways to install Git.

How to Install Git with Apt-Get


Installing Git with apt-get is a quick and easy process. The program installs on the virtual private server with one command:
sudo apt-get install git-core

After it finishes downloading, you will have Git installed and ready to use.

How to Install Git from Source


If you are eager to download the most recent version of Git, it is generally a good idea to install it from the source.

Quickly run apt-get update to make sure that you download the most recent packages to your VPS.
sudo apt-get update

Prior to installing Git itself, download all of the required dependancies:
sudo apt-get install libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev build-essential

Once they are installed, you can download the latest version of Git from the google code page.
wget https://git-core.googlecode.com/files/git-1.8.1.2.tar.gz

After it downloads, untar the file and switch into that directory:
tar -zxf git-1.8.1.2.tar.gz
cd git-1.8.1.2

If you want to do a global install, install it once as yourself and once as root, using the sudo prefix:
make prefix=/usr/local all
sudo make prefix=/usr/local install

If you need to update Git in the future, you can use Git itself to do it.
git clone git://git.kernel.org/pub/scm/git/git.git

How to Setup Git


After Git is installed, whether from apt-get or from the source, you need to copy your username and email in the gitconfig file. You can access this file at ~/.gitconfig.

Opening it following a fresh Git install would reveal a completely blank page:
sudo nano ~/.gitconfig

You can use the follow commands to add in the required information.
git config --global user.name "NewUser"
git config --global user.email newuser@example.com

You can see all of your settings with this command:
git config --list

If you avoid putting in your username and email, git will later attempt to fill it in for you, and you may end up with a message like this:
[master 0d9d21d] initial project version
 Committer: root 
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:

    git config --global user.name "Your Name"
    git config --global user.email you@example.com

After doing this, you may fix the identity used for this commit with:

    git commit --amend --reset-author

See More


This tutorial covered how to install Git on your virtual private server. Stay tuned for a second tutorial on Git Basics.



By Etel Sverdlov

Wednesday, September 18, 2013

How to Read MMS Data in Android?

http://stackoverflow.com/questions/3012287/how-to-read-mms-data-in-android

How to Read MMS Data in Android?

I want to read MMS data I have seen the part table in the mmssms.db where the mms entries are stored; I am using a cursor and I want to know the appropriate URI; I am using "content://mms-sms/conversations" and the Column names of "Address"(Sent to), "Text" or "Subject" and "Data" column name of image.
I have seen the schema of mmssms.db and Their Column of part Table.
share|improve this question
The mmssms.db database is part of the firmware and is not accessible by Android applications. The content://mms-sms/conversations content provider is not part of the SDK and should not be accessed by Android applications.CommonsWare Jun 10 '10 at 11:12
3
Please accept an answer…user1521536 Aug 22 '12 at 3:09

5 Answers

It's kind of difficult to find documentation about this, so I will collect here all information I have found. If you are in a rush or just don't like to read, jump to the How to get data from a SMS section.

content://mms-sms/conversations

This is the URI of the Mms and SMS provider... which allows us to query the MMS and SMS databases at the same time, and mix them in a single thread (which are called conversations).
Why is it important the content://mms-sms/conversations uri? Well, that's the standard way of getting MMS and SMS messages; for instance, when you receive a SMS and click on the notification bar, it will send a broadcast intent like this: content://mms-sms/conversations/XXX, where XXX is the id of the conversation.

Get a list of all conversations

The only thing you have to do is to query the content://mms-sms/conversations Uri:
ContentResolver contentResolver = getContentResolver();
final String[] projection = new String[]{"*"};
Uri uri = Uri.parse("content://mms-sms/conversations/");
Cursor query = contentResolver.query(uri, projection, null, null, null);
Note: usually, when you call query and want to return all columns you can pass null as the projection parameter. However, you cannot do that with this provider, so that's why I'm using *.
Now you can loop through the Cursor as usual. These are the more important columns you would want to use:
  • _id is the ID of the message. Captain obvious to the rescue? Not really. This ID can be used to retrieve detailed information using either content://sms or content://mms.
  • date no explanation needed.
  • thread_id is the ID of the conversation
  • body The content of the last SMS on this conversation. If it's an MMS, even if it has a text part, this will be null.
Note: if you query content://mms-sms/conversations it will return a list of different conversations whose _id is the last SMS or MMS in each conversation. If you query content://mms-sms/conversations/xxx it will return each SMS and/or MMS on the conversation whose ID is xxx.

How to differentiate between SMS and MMS

Usually, you will want to know which type of message you are handling. Documentation says:
A virtual column, MmsSms.TYPE_DISCRIMINATOR_COLUMN, may be requested in the projection for a query. Its value is either "mms" or "sms", depending on whether the message represented by the row is an MMS message or an SMS message, respectively.
I think it's referring to this variable... however I have not been able to make it work. If you have please tell me how or edit this post.
So far this is what I have done and it seems to work but there must be better ways:
ContentResolver contentResolver = getContentResolver();
final String[] projection = new String[]{"_id", "ct_t"};
Uri uri = Uri.parse("content://mms-sms/conversations/");
Cursor query = contentResolver.query(uri, projection, null, null, null);
if (query.moveToFirst()) {
    do {
        String string = query.getString(query.getColumnIndex("ct_t"));
        if ("application/vnd.wap.multipart.related".equals(string)) {
            // it's MMS
        } else {
            // it's SMS
        }
    } while (query.moveToNext());
}

How to get data from a SMS

So you have the ID of the SMS, then the only thing you have to do is:
String selection = "_id = "+id;
Uri uri = Uri.parse("content://sms");
Cursor cursor = contentResolver.query(uri, null, selection, null, null);
String phone = cursor.getString(cursor.getColumnIndex("address"));
int type = cursor.getInt(cursor.getColumnIndex("type"));// 2 = sent, etc.
String date = cursor.getString(cursor.getColumnIndex("date"));
String body = cursor.getString(cursor.getColumnIndex("body"));

How to get data from a MMS data?

MMSs are a little bit different. They can be built with different parts (text, audio, images, etc.); so here will see how to retrieve each kind of data separately.
So let's guess we have the MMS id in the mmsId variable. We can get detailed information about this MMS by using the content://mms/ provider:
Uri uri = Uri.parse("content://mms/");
String selection = "_id = " + mmsId;
Cursor cursor = getContentResolver().query(uri, null, selection, null, null);
However, the only interesting column is read which is 1 if the message has already been read.

How to get text content from MMS

Here we have to use content://mms/part... for instance:
String selectionPart = "mid=" + mmsId;
Uri uri = Uri.parse("content://mms/part");
Cursor cursor = getContentResolver().query(uri, null,
    selectionPart, null, null);
if (cursor.moveToFirst()) {
    do {
        String partId = cursor.getString(cursor.getColumnIndex("_id"));
        String type = cursor.getString(cursor.getColumnIndex("ct"));
        if ("text/plain".equals(type)) {
            String data = cursor.getString(cursor.getColumnIndex("_data"));
            String body;
            if (data != null) {
                // implementation of this method below
                body = getMmsText(partId);
            } else {
                body = cursor.getString(cursor.getColumnIndex("text"));
            }
        }
    } while (cursor.moveToNext());
}
It could contain different parts of text... but usually it'd be only one. So if you want to remove the loop it will work most of the times. This is how the getMmsText method looks like:
private String getMmsText(String id) {
    Uri partURI = Uri.parse("content://mms/part/" + id);
    InputStream is = null;
    StringBuilder sb = new StringBuilder();
    try {
        is = getContentResolver().openInputStream(partURI);
        if (is != null) {
            InputStreamReader isr = new InputStreamReader(is, "UTF-8");
            BufferedReader reader = new BufferedReader(isr);
            String temp = reader.readLine();
            while (temp != null) {
                sb.append(temp);
                temp = reader.readLine();
            }
        }
    } catch (IOException e) {}
    finally {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {}
        }
    }
    return sb.toString();
}

How to get image from MMS

It's the same than getting the text part... the only difference is that you will be looking for a different mime-type:
String selectionPart = "mid=" + mmsId;
Uri uri = Uri.parse("content://mms/part");
Cursor cPart = getContentResolver().query(uri, null,
    selectionPart, null, null);
if (cPart.moveToFirst()) {
    do {
        String partId = cPart.getString(cPart.getColumnIndex("_id"));
        String type = cPart.getString(cPart.getColumnIndex("ct"));
        if ("image/jpeg".equals(type) || "image/bmp".equals(type) ||
                "image/gif".equals(type) || "image/jpg".equals(type) ||
                "image/png".equals(type)) {
            Bitmap bitmap = getMmsImage(partId);
        }
    } while (cPart.moveToNext());
}
This is how the getMmsImage method looks like:
private Bitmap getMmsImage(String _id) {
    Uri partURI = Uri.parse("content://mms/part/" + _id);
    InputStream is = null;
    Bitmap bitmap = null;
    try {
        is = getContentResolver().openInputStream(partURI);
        bitmap = BitmapFactory.decodeStream(is);
    } catch (IOException e) {}
    finally {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {}
        }
    }
    return bitmap;
}

How to get the sender address

You will need to use the content://mms/xxx/addr provider, where xxx is the id of the MMS:
private String getAddressNumber(int id) {
    String selectionAdd = new String("msg_id=" + id);
    String uriStr = MessageFormat.format("content://mms/{0}/addr", id);
    Uri uriAddress = Uri.parse(uriStr);
    Cursor cAdd = getContentResolver().query(uriAddress, null,
        selectionAdd, null, null);
    String name = null;
    if (cAdd.moveToFirst()) {
        do {
            String number = cAdd.getString(cAdd.getColumnIndex("address"));
            if (number != null) {
                try {
                    Long.parseLong(number.replace("-", ""));
                    name = number;
                } catch (NumberFormatException nfe) {
                    if (name == null) {
                        name = number;
                    }
                }
            }
        } while (cAdd.moveToNext());
    }
    if (cAdd != null) {
        cAdd.close();
    }
    return name;
}

Final thoughts

  • Can't understand why Google, with those thousands of millions of dollars, don't pay a student or someone else to document this API. You have to check the source code to know how it works and, which is worse, they don't make public those constants used in the columns of the database, so we have to write them manually.
  • For other kind of data inside an MMS you can apply the same idea learned above... it's just a matter of knowing the mime-type.
share|improve this answer
1
Conserning content://mms-sms/conversations. This url contains list with all threads. But not separate messages (sms or mms). So there is no sense to get to know sms or mms it is while it is none of them.Maxim Aug 8 '11 at 13:21
would there be a reason why all my MMS mime types come back as application/smil?Justin Feb 28 '12 at 23:19
1
Justin, because MMS are stored in database as slideshow using SMIL.Naba Mar 2 '12 at 5:59
@Cristian hi, i am the one who ask you in twitter. i want to get data from MMS as List so i found this tutorial,it takes ur code and add listview but when i run it. it did not show me anythingMaha Apr 10 '12 at 8:49
You better create a question and share your code with us. How can we see what you are doing wrong if we do not know your code?Cristian Apr 10 '12 at 14:50
show 11 more comments
The answer by Christian is excellent. However, the method for getting the sender's address did not work for me. The Long.parseLong statement doesn't do anything except possibly throw an exception and new String(...) ?.
On my device the cursor count is 2 or more. The first typically has a "type" of 137 and the others have a "type" of 151. I cannot find where this is documented, but one can deduce 137 is "from" and 151 is "to". Thus, if I run the method as is, I do not get an exception, and it returns the last row, which is a recipient and only one of several in many cases.
Also AFAICT the selection is not necessary as all the rows have the same msg_id. However, it doesn't hurt.
This is what works for me to get the sender's address:
public static String getMMSAddress(Context context, String id) {
    String addrSelection = "type=137 AND msg_id=" + id;
    String uriStr = MessageFormat.format("content://mms/{0}/addr", id);
    Uri uriAddress = Uri.parse(uriStr);
    String[] columns = { "address" };
    Cursor cursor = context.getContentResolver().query(uriAddress, columns,
            addrSelection, null, null);
    String address = "";
    String val;
    if (cursor.moveToFirst()) {
        do {
            val = cursor.getString(cursor.getColumnIndex("address"));
            if (val != null) {
                address = val;
                // Use the first one found if more than one
                break;
            }
        } while (cursor.moveToNext());
    }
    if (cursor != null) {
        cursor.close();
    }
    // return address.replaceAll("[^0-9]", "");
    return address;
}
I didn't care about whether it is all numeric, but I included a way to eliminate everything but numerals as a comment if that is desired. It can easily be modified to return all the recipients, as well.
I assume it worked for him. It looks like it would give the right answer if the exception occurred on the first row.
share|improve this answer
I wouldn't try to call parseLong on the contact_id field; treat it as a string. In fact, it's quite possible that it could be an email address or something, in the case of email-to-mms gateways.Edward Falk Nov 22 '12 at 17:36
Take a look at this. Worked well for me.
share|improve this answer
what about application/smil type MMS messages?toobsco42 Jul 17 '12 at 7:42
The answer given above for getting the getMMSAddress() should not contain the loop while (cursor.moveToNext());. It should only extract the address from the first element in the cursor. For some reason that is unknown to me, this cursor has more than one record. The first one contains the Sender's address. The other elements of the cursor beyond the first one, contain the receiver's address. Thus the code as is return the receivers address and not the sender address.
This has been very helpful for cracking open the contents of an MMS.
share|improve this answer
I had to make some modifications in order to get this to work for me.
  1. When I retrieve the cursor.getString(cursor.getColumnIndex("type")) from the mms-sms/conversations content, ("content://mms-sms/conversations/") I test the value of the "type" field for null. If the variable is null - i.e.
    String otype = c.getString(c.getColumnIndex("type"));
    if(otype != null) {
        //this is an sms - handle it...
    the message is an SMS, else it is an MMS. For MMS's you have to test for both mime types as follows:-
    if (("application/vnd.wap.multipart.related".equalsIgnoreCase(msg_type)
        ||"application/vnd.wap.multipart.mixed".equalsIgnoreCase(msg_type))
        && !id.equalsIgnoreCase(lastMMSID)) {
             //this is a MMS - handle it...
  2. When you use a ContentObserver to monitor the message content for changes, it fires several notifications for the same message. I use a static variable - in my case lastMMSID - to keep track of the message.
  3. This code works well to retrieve the content of both Inbound and Outbound messages. It is important to iterate through all the records that are returned by the "content://mms/part/" uri in order to get to the content - text and/or attachments - of the MMS.
  4. The only way that I could find that works pretty well to differentiate between inbound and outbound MMS's, is to test the null status of the "m_id" field of the mms-sms/conversations content.
    String m_id = c.getString(c.getColumnIndex("m_id"));
    String mDirection = m_id == null? "OUT": "IN";
A final thought on how to get the Address Field. For some reason the Address Content does not like to be queried with a {" * "} parameter, but this works:-
final String[] projection = new String[] {"address", "contact_id", "charset", "type"};
If it is an outbound message, the "type" to look for will be 151. For an inbound message, the "type" will be 137. A fully functional piece of code will look something like this:-
private String getANumber(int id) {
    String add = "";
    final String[] projection = new String[] {"address","contact_id","charset","type"};
    final String selection = "type=137 or type=151"; // PduHeaders
    Uri.Builder builder = Uri.parse("content://mms").buildUpon();
    builder.appendPath(String.valueOf(id)).appendPath("addr");

    Cursor cursor = context.getContentResolver().query(
        builder.build(),
        projection,
        selection,
        null, null);

if (cursor.moveToFirst()) {
          do {
              String add = cursor.getString(cursor.getColumnIndex("address"));
              String type: cursor.getString(cursor.getColumnIndex("type"));
          } while(cursor.moveToNext());
      }
      // Outbound messages address type=137 and the value will be 'insert-address-token'
      // Outbound messages address type=151 and the value will be the address
      // Additional checking can be done here to return the correct address.
      return add;
}
To all the brave warriors who have gone before me in this post - I thank thee from the bottom of my heart!
share|improve this answer