Welcome

how would you rate The Holy Qura'an - Arabic ver?

Showing posts with label android. Show all posts
Showing posts with label android. Show all posts

Wednesday, February 19, 2014

Step by step on how to add Facebook plugin on Phonegap

I have posted an answer on stackoverflow on how to do it and here is more:

Using CLI add the APP_ID and APP_NAME variables to your command. Something like this:

C:\myProject>cordova plugin add https://github.com/phonegap/phonegap-facebook-plugin --variable APP_ID=your_facebook_app_id --variable APP_NAME=your_facebook_app_name
I got it installed this way but not sure if the app is functional or not. Something to test.
I had an issue with phonegap build giving me the error One of your plugins requires a parameter: APP_ID, APP_NAME. That was because I didn't add those variables to the config.xml file.
This solved it


<gap:plugin name="com.phonegap.plugins.facebookconnect">
  <param name="APP_ID" value="your_facebook_app_id" />
  <param name="APP_NAME" value="your_facebook_app_name" />
</gap:plugin>

Please remember to modify the plugin.xml file under root/plugins/com.phonegap.plugins.facebookconnect/plugin.xml
<preference name="APP_ID" />
<preference name="APP_NAME" />

Also, I had issue with facebook failing to initial and it was because my config.xml had this
<widget id="com.app.xxx" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://cordova.apache.org/ns/1.0">

and solved it by changing it to this:
<widget id="com.app.xxx" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://phonegap.com/ns/1.0">

This should get the app to work.

After you start using it you will notice when you do login facebook will through at you errors like "invalid android_key parameter". This means that you haven't register the app platform on Facebook.

Go to your app facebook page: https://developers.facebook.com/x/apps/app_id/settings/
Under Settings -> Basic -> click on add platform

Now you need to sign your app using command line on windows, for this to work you will need to have java keytool installed and i'm not going through that here, PLEASE KEEP IN MIND TO AVOID ADDING SPACES, SPECIAL CHARACTERS AND ALL LOWER CASE [I had issues with phonegap not recognizing my alias because of that].

C:\mykeystorebox>keytool -genkey -v -keystore mynewkey.keystore -alias mykeyalias -keyalg rsa -keysize 2048 -validity 10000
Enter keystore password:
Re-enter new password:
What is your first and last name?
[Unknown]: sean
What is the name of your organizational unit?
[Unknown]:
What is the name of your organization?
[Unknown]: testcompany
What is the name of your City or Locality?
[Unknown]: london
What is the name of your State or Province?
[Unknown]: on
What is the two-letter country code for this unit?
[Unknown]: ca
Is CN=sean, OU=Unknown, O=testcompany, L=london, ST=on, C=ca correct?
[no]: yes

Generating 2,048 bit RSA key pair and self-signed certificate (SHA256withRSA) with a validity of 10,000 days
for: CN=sean, OU=Unknown, O=testcompany, L=london, ST=on, C=ca
Enter key password for
(RETURN if same as keystore password):
[Storing mynewkey.keystore]

C:\mykeystorebox>keytool -exportcert -alias mykeyalias -keystore mynewkey.keystore | openssl sha1 -binary | openssl base64
Enter keystore password: *************
Abikekw4k3lfmK23kvJl32Ljflw301=

Now go back to facebook page and take Abikekw4k3lfmK23kvJl32Ljflw301= and put it under Key Hashes. You will need to add your app class in there too.

Save that.

Now go to Phonegap and upload your keystore as a key for your android and sign your APK with it. It will ask for a title and could be anything, alias and in this case should be mykeyalias.

Sunday, January 19, 2014

Push Notification Android - Phonegap 3.2 Plugin

I have been trying to test the native phonegap push notification on version 3.2 but almost everything I tried resulted in "Class not found" issue". After a couple of days of trials here is how I finally got it to work.


  1. Using the CLI install the push notification plugin: 
    • $ phonegap local plugin add https://github.com/phonegap-build/PushPlugin
  2. Add
     <script type="text/javascript" src="PushNotification.js"></script>  
    
    to the header of your index.html
  3. Add the following to your index.html body
               <div id="home" style="position:absolute; bottom:0; left:0; z-index:99999;">  
                    <div id="app-status-div">  
                         <ul id="app-status-ul">  
                              <li>Cordova PushNotification Plugin Demo</li>  
                         </ul>  
                    </div>  
               </div>  
    
  4. In your javascript add
     var pushNotification;  
           function onDeviceReady() {  
             $("#app-status-ul").append('<li>deviceready event received</li>');  
                         document.addEventListener("backbutton", function(e)  
                         {  
                  $("#app-status-ul").append('<li>backbutton event received</li>');  
                            if( $("#home").length > 0)  
                              {  
                                   // call this to get a new token each time. don't call it to reuse existing token.  
                                   //pushNotification.unregister(successHandler, errorHandler);  
                                   e.preventDefault();  
                                   navigator.app.exitApp();  
                              }  
                              else  
                              {  
                                   navigator.app.backHistory();  
                              }  
                         }, false);  
                         try   
                         {   
                  pushNotification = window.plugins.pushNotification;  
                  if (device.platform == 'android' || device.platform == 'Android') {  
                                   $("#app-status-ul").append('<li>registering android</li>');  
                    pushNotification.register(successHandler, errorHandler, {"senderID":"661780372179","ecb":"onNotificationGCM"});          // required!  
                              } else {  
                                   $("#app-status-ul").append('<li>registering iOS</li>');  
                    pushNotification.register(tokenHandler, errorHandler, {"badge":"true","sound":"true","alert":"true","ecb":"onNotificationAPN"});     // required!  
                  }  
             }  
                         catch(err)   
                         {   
                              txt="There was an error on this page.\n\n";   
                              txt+="Error description: " + err.message + "\n\n";   
                              alert(txt);   
                         }   
           }  
           // handle APNS notifications for iOS  
           function onNotificationAPN(e) {  
             if (e.alert) {  
                $("#app-status-ul").append('<li>push-notification: ' + e.alert + '</li>');  
                navigator.notification.alert(e.alert);  
             }  
             if (e.sound) {  
               var snd = new Media(e.sound);  
               snd.play();  
             }  
             if (e.badge) {  
               pushNotification.setApplicationIconBadgeNumber(successHandler, e.badge);  
             }  
           }  
           // handle GCM notifications for Android  
           function onNotificationGCM(e) {  
             $("#app-status-ul").append('<li>EVENT -> RECEIVED:' + e.event + '</li>');  
             switch( e.event )  
             {  
               case 'registered':  
                              if ( e.regid.length > 0 )  
                              {  
                                   $("#app-status-ul").append('<li>REGISTERED -> REGID:' + e.regid + "</li>");  
                                   // Your GCM push server needs to know the regID before it can push to this device  
                                   // here is where you might want to send it the regID for later use.  
                                   console.log("regID = " + e.regid);  
                              }  
               break;  
               case 'message':  
                    // if this flag is set, this notification happened while we were in the foreground.  
                    // you might want to play a sound to get the user's attention, throw up a dialog, etc.  
                    if (e.foreground)  
                    {  
                                        $("#app-status-ul").append('<li>--INLINE NOTIFICATION--' + '</li>');  
                                        // if the notification contains a soundname, play it.  
                                        var my_media = new Media("/android_asset/www/"+e.soundname);  
                                        my_media.play();  
                                   }  
                                   else  
                                   {     // otherwise we were launched because the user touched a notification in the notification tray.  
                                        if (e.coldstart)  
                                             $("#app-status-ul").append('<li>--COLDSTART NOTIFICATION--' + '</li>');  
                                        else  
                                        $("#app-status-ul").append('<li>--BACKGROUND NOTIFICATION--' + '</li>');  
                                   }  
                                   $("#app-status-ul").append('<li>MESSAGE -> MSG: ' + e.payload.message + '</li>');  
                                   $("#app-status-ul").append('<li>MESSAGE -> MSGCNT: ' + e.payload.msgcnt + '</li>');  
               break;  
               case 'error':  
                                   $("#app-status-ul").append('<li>ERROR -> MSG:' + e.msg + '</li>');  
               break;  
               default:  
                                   $("#app-status-ul").append('<li>EVENT -> Unknown, an event was received and we do not know what it is</li>');  
               break;  
             }  
           }  
           function tokenHandler (result) {  
             $("#app-status-ul").append('<li>token: '+ result +'</li>');  
             // Your iOS push server needs to know the token before it can push to this device  
             // here is where you might want to send it the token for later use.  
           }  
           function successHandler (result) {  
             $("#app-status-ul").append('<li>success:'+ result +'</li>');  
           }  
           function errorHandler (error) {  
             $("#app-status-ul").append('<li>error:'+ error +'</li>');  
           }  
                    document.addEventListener('deviceready', onDeviceReady, true);  
    
  5. Now go to your www/config.xml and add
     <gap:plugin name="com.phonegap.plugins.PushPlugin" />  
    
Now build and compile your project. You should get it working now.

So what's next?! When you run your app and registration is success what you need to play with is e.regid under the case: "registered".

 So what you could do is using ajax send the e.regid to a php file to store that regid in the database as an identity to this user's device.

Next you could test sending the user messages using something like:
 function send_gcm_notify($reg_id, $message) {  
      $apiKey = "AIzaSyDXlsn2rlbTxZsa3apYfQu0kaSNzzzzzag8"; //google browser api key  
      $url = 'https://android.googleapis.com/gcm/send';  
   $fields = array(  
     'registration_ids' =>; array( $reg_id ),  
     'data'       =>; array( "message" => $message ),  
   );  
   $headers = array(  
     'Authorization: key=' . $apiKey,  
     'Content-Type: application/json'  
   );  
   $ch = curl_init();  
   curl_setopt($ch, CURLOPT_URL, $url);  
   curl_setopt($ch, CURLOPT_POST, true);  
   curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);  
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);  
   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);  
   curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));  
   $result = curl_exec($ch);  
   if ($result === FALSE) {  
     die('Problem occurred: ' . curl_error($ch));  
   }  
   curl_close($ch);  
   echo $result;  
  }  
 $reg_id = "APA91bxxxsszzjVXv9jW4O2mD0Nvljf_0BLzjHzCqKa-9VthTYYDqB9BfKj88Fd3234fscARTRaNsm3xKk73V-xWZIM3ETuptUFxxYVwik1234WmeABgcf_yG4Gkd0GSk3Zfydw8Cv6H3b0K";  
 $msg = "Google Cloud Messaging working well";  
 send_gcm_notify($reg_id, $msg);  

Wednesday, January 15, 2014

Push Notification - Phonegap 3.0+ with pushwoosh

I had so much trouble integrating Push Notification using all the documentation available. After two days of struggle I got to the bottom of it and finally it's working. Here's what I did.
  1. If you installed Push plugin before, then delete it and start fresh.
  2. Follow the instructions in here integrating phonegap on android
  3. In your config.xml file add < gap:plugin name="com.pushwoosh.plugins.pushwoosh" version="3.0.1" > < /gap:plugin > ....... PLEASE NOTE THE SPACES I ADDED BEFORE AND AFTER THE TAGS IN HERE. REMOVE THE EXTRA SPACING
  4. projectid: is actually the Project Number under your Developers Console > overview.
  5. That's it.

Friday, August 13, 2010

New Updates







+++++++++++++
UPDATE: Aug 24, 2010

This link is for the new version 3.4 of "The Holy Quran - Medina"


UPDATE: Aug 15, 2010
This link is for the new version 3.4 of "The Holy Quran - Medina, Froyo"

+++++++++++++


Holy Quran - Medina Updates:

1. Many people sent me emails regarding missed pages in their app. This occurs due to an error during downloading pages. Thus I added a "FIX" button to the main menu. Make sure you are connected to the internet first, then you will see the download indicator showing all pages being checked again.

2. The new update will include more detailed bookmarking system as well as fast bookmarking (the old system). You can access your bookmarks by clicking on Read Bookmarks on the front page.

3. I had many issues with moving the app to the SD, therefore, I will release a new version that runs only on API 8 and eventually it will be the formal version that I'll keep updating.




Holy Quran - Eng.Ver Updates:
New update will be released to handle mixing pages with the images folder, sorry about this error, my mistake.

Latest update Aug 31,2010

Monday, June 14, 2010

The Holy Qura'an

The Holy Quraan - Full Version



Upcoming Update 3

I received an email from brother "mohammed24" and he was asking me about the UI and telling me that many people are asking for upgrading its design. This is a message he included in his email from a user on ce4arab
===============
اولا الله يجزا المبرمج خير ووالديه على هالبرنامج الحلو
ثانيا انا قادم من اي فون ومازلت استخدم اي باد فاسمحو لي بهالملاحظة وياليت المبرمج يسمعها
البرنامج شكله مش ولابد
اذا قارنته بالبرامج اللي في الاندرويد هو قمه
لكن لو تقارنه ببرنامج مصحف المدينة اللي على الاي فون
فرق
فاتمنا من المبرمج الله يخليه لو يركز على الشكل شوي
والبرنامج له مستقبل قوي
خصوصا اللي يلاحظ سرعة تحديثه
اسف اذا كان تعليقي ازعلكم لكن والله ان هذا البرنامج مهم ياجماعة ماتتخيلون وش يسوي بغير المسلمين لما يشوفونه فلو كان شكله حلو + مجاني + تقييم عالي في الماركت = مسلمين جدد
تحياتي


Therefore, the upcoming update 3 will include an upgrade to all the pages, menu, and also the UI in general. A fix for the zoom and a couple more new features. Just stay tuned ;)



Update 2.2.0 - July 01,2010

Some people will have issues with some pages and that is due to a network error while running the app for the first time. So this update should solve that issue. Also, I might not have explained the Bookmark thing before, but if you hold your finger to a specific page you will receive a message asking to bookmark that specific page for a later time access. Whenever you run your app you could simply go to the menu and select "Read Bookmark" that will take you to your last page you bookmarked.


Update 2.1.0 - June 22,2010

New Features:
- zoom
- menu options, basically to read your bookmarks and read "About"

So what's new in this update? Well, first of all you can zoom in by a click on a page and return by one click by the zoomed image. Second, I added bookmarks as many requested, kinda hidden I know but I find it easier for me this way, code wise. A long click on an image will give you the option to bookmark the current page or not. To get to the bookmarked page all you need to do is just go to Menu and select "Read Book Mark."

Things I learned:
- Making Alert dialogs.
- Creating Menu Elements
- Using both setOnItemClickListener and setOnItemLongClickListener to zoom in and to create a bookmark.


==============
First of all, I have to admit that it took me a long time to finish this app. First time I finished it I tried to upload it to the market but due to the massive size (30M) of it I couldn't. So I had to find an alternative way to get it smaller and loadable.
So, since all Soras are images it would be more efficient to save them on the SD card and downloadable from a URL. Doing that totally forced me to make lots of changes in the app and that's what kept me long till I uploaded the full version.

Things I learned:
1. making directories on the SD card to hold images downloaded from a server.
2. making a progress bar to indicate the amount of data saved.
3. creating a gallery with a String data input array.
4. sorting a list of files.
5. giving permissions to the app

if you are having troubles downloading this app from the market, here it is :)

Thursday, June 3, 2010

The Holy Qura'an

================================================

Update June 09, 2010


OK, so yesterday I uploaded my demo for The Holy Quraan on Android Market. My idea in making my apps is to make is as straightforward and easy as I could, I call this method LEC (Life Experience Computerization). You open a book and you want to jump to a specific page and start reading. You don't read the intro and bio pages every time you open your book. So this is why I build my apps like that. "just saying this 'cause I got a comment about this from one friend :) you know who you are

So, lets start, getting my app to jump to a specific page was a bit challenging. I use a gallery to show all the pages. The main menu is connected to all this pages and that's why you could jump to a specific Sora from the main menu and still could flip to all the other pages from that page.
At this point, I will omit the zoom function as a friend suggested and will focus on making the full version available. Options menu will be added in the next update.

Challenges I faced:
1. Enlarging images in my gallery to fit the screen.
2. Zooming .. still not sure how handle it perfectly.
3. Connecting main menu to point to a page in the gallery

OK, how does the gallery work?
First, lets say you have Screen1.java has a list of buttons one of them is related to btn1 in your Screen1.xml then Screen1.java should look something like this
==========
...
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.Screen1);

...
Button A = (Button) findViewById(R.id.btn1);
A.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
Intent i = new Intent(Screen1.this, Screen2.class);
int Str = 1;
i.putExtra("PASS", Str);
startActivity(i);
}
});
========
Notice you are passing "PASS=1" to Screen2.java where you will establish your gallery. Screen2.java should look like this:
public class Screen2 extends Activity
{
//---the images to display---
Integer[] imageIDs = {
R.drawable.Img0, //0
R.drawable.bgrd1 //1
};
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.Screen2);
Gallery gallery = (Gallery) findViewById(R.id.gallery1);
gallery.setAdapter(new ImageAdapter(this));
...

public class ImageAdapter extends BaseAdapter
{
private Context context;
private int itemBackground;
public ImageAdapter(Context c)
{
context = c;
//---setting the style---
TypedArray a = obtainStyledAttributes(R.styleable.Gallery1);
itemBackground = a.getResourceId(
R.styleable.Gallery1_android_galleryItemBackground, 0);
a.recycle();
}
//---returns the number of images---
public int getCount() {
return imageIDs.length;
}
//---returns the ID of an item---
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
//---returns an ImageView view---
public View getView(int position, View convertView, ViewGroup parent) {

ImageView imageView = new ImageView(context);
imageView.setImageResource(imageIDs[position]);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setLayoutParams(new Gallery.LayoutParams(150, 120));
imageView.setBackgroundResource(itemBackground);
return imageView;
}
}
====
Notice three things,
1. The array of images you want to show is placed at the beginning of your class
2. your layout here is Screen2.xml
3. you must add ImageAdapter

Also, Screen2.xml should include your [Gallery android:id="@id/gallery1"/]


So this is basically how you set up your gallery.




================================================

Zoom




This is my new attempt to build an android app. This one will be fully released on android 2.2 due to the fact that the size will be HUGE. Some of the functionalities are:
1. Flipping pages by scrolling right and left.
2. Zooming to the page by clicking on it.
3. A list for all Soras to select from.

hmmmm what else!!!
More details about my progress will be posted soon.

Tuesday, May 25, 2010

Official version of Hisn Al Muslim on Android



Coming soon - Update 1.0.6:

This is useful on Android 2.2. Since the size of the file is big, I think it's better if you move it to your SD Card. Again, this functionality will be available in Android 2.2. So once you upgrade to 2.2 you'd be able to move the program to your SD Card.

Also, I am working on optimizing the program and try to make it smaller than it is.


================================================================




Finally I made it. It took a lot of effort to get this app together since it's my first app ever on android. I was looking for this app on android a while ago just before but unfortunately there wasn't.
I dedicate this app for my, God bless her soul and may Allah forgive all her sins and may heaven and Al Furdaws Ala'ala be where she is now.

I finished this app but haven't reviewed it yet. Please if you found any error or mistakes notify me so I could make the right changes.

I hope you all enjoy it and find it very useful.

Monday, May 24, 2010

some thoughts

At first I thought coding for android would be easy. Just shove your code in one file and you're done. aaaaaaaaaaaah NOPE, that's not the case. Everything is separate, some people will say what the hell, some others love it. It is more sufficient and organized, you've got (if you are using Eclipse):

1. src folder, contains source code (java)

2. gen folder, contains a R class file which gets generated automatically by the compiler

3. res folder, contains your recourses folders; drawable(images will be here), layouts(xml files will be here), and values(strings.xml)

4. AndroidManifest.xml this file "in my understanding" is used to include all the java classes as activities and looooots more, google it :D

By the way, to be able to publish your project your AndroidManifest.xml files should start like this:
[manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="package.name"
android:versionCode = "2"
android:versionName = "1.0.1"]
[uses-sdk android:minSdkVersion="7" /]
[application android:icon="@drawable/icon"]
****** use <> instead of [] *******

Another thing, some people will wonder what to do with the project after they're done programming. How could I compress my project in a .apk file?
All you need to do is:
right click on your project
> Android Tools
> Export Signed Application Package
> Export Unsigned Application Package

then follow the steps.

Saturday, May 22, 2010

Issues publishing on Android Market

when I tried to publish my .pkg file I received these errors:

Market requires versionCode to be set to a positive 32-bit integer in AndroidManifest.xml.
Market requires versionName to be set in AndroidManifest.xml.
Market requires the minSdkVersion to be set to a positive 32-bit integer in AndroidManifest.xml.

to solve that I had to alter my AndroidManifest.xml file as:

[manifest android="http://schemas.android.com/apk/res/android" package="android.test"
android:versionCode = "1"
android:versionName = "1.0"]
[uses-sdk android:minSdkVersion="7" /]

and I found out that the package attribute should be something unique, obviously "android.test" is not.

also, minSdkVersion is your API Level in which you made your program for.

The following table specifies the API Level supported by each version of the Android platform.

Platform VersionAPI Level
Android 2.28
Android 2.17
Android 2.0.16
Android 2.05
Android 1.64
Android 1.53
Android 1.12
Android 1.01
for more info read

My first attempt in programming for Android

Hisn Al Muslim, dedicated for my beloved mother, Allah Bless her soul.

I will post it on the market in Arabic and soon will do another version in English.